Модераторы: PILOT, ManiaK, Mazzi
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сдвиг бита в части регистра 
:(
    Опции темы
supercelt
Дата 24.7.2016, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 658
Регистрация: 25.8.2005

Репутация: нет
Всего: 1



Здравствуйте.

Есть порт В микроконтроллера stm32

Я задействую 5,6,7,8 пины. Остальные служат под другие нужды.

В цикле for надо на 5 пин подать 1, а при следующем  заходе в цикл - сдвигать ее влево. Получится, что цикл проворачивается и  каждый раз нужно ставить 1 с 5 по 8 пин, при этом что бы остальные пины были 0.


Можно конечно сделать вот так

Код

for(i=0; i<4; i++){
    if(i == 0){
        GPIO->BSSR |= (1 << 5);
        GPIO->BRR |= (1 << 6) | (1 << 7) | (1 << 8);
        } else if(i == 1){
        GPIO->BSRR |= (1 << 6);
        GPIO->BRR |= (1 << 5) | (1 << 7) | (1 << 8);
    } else if(i == 2){
        GPIO->BSRR |= (1 << 7);
        GPIO->BRR |= (1 << 5) | (1 << 6) | (1 << 8);
    } else if(i == 3){
        GPIO->BSRR |= (1 << 8);
        GPIO->BRR |= (1 << 5) | (1 << 6) | (1 << 7);
    }

}


Но это быдлокодирование не катит. Затык, не могу сообразить. Я уверен, что программеры с опытом делают это в 1 - 2 строчки. Как?
PM   Вверх
Mikron
Дата 24.7.2016, 17:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 50
Регистрация: 2.5.2007

Репутация: нет
Всего: нет



Код

for(i=0; i<4; i++){
GPIO->BSRR |= ((1<<i)<<5)|((0xf&(~(1<<i)))<<5<<16)
}


Это сообщение отредактировал(а) Mikron - 24.7.2016, 17:52
PM MAIL   Вверх
Курсант
Дата 25.7.2016, 09:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 338
Регистрация: 21.2.2009
Где: Балашиха или Воро неж

Репутация: нет
Всего: 4



Эммм.. Простите, не понял проблемы. У Вас есть число, неважно, что там записано в какой пин. Для сдвига Вы просто делаете такую операцию:
Код

src = (src << 1) & 0x000001E0;

Это если нужно все остальные биты числа оставить нулевыми.
Если нужно оставить биты без изменения, то так
Код

src = ( src & ( 0xFFFFFE1F) ) | ( (src << 1) & 0x000001E0 );


Можно набросать такую функцию:
Код

void PushAndShift ( uint32_t* Dst, uint32_t PushedValue ) {
Dst* = ( Dst* src & ( 0xFFFFFE1F) ) | ( ( Dst* << 1) & 0x000001E0 )
if ( PushedValue ) {
Dst* |= ( 1 << 5 );
}
}

PM ICQ Skype   Вверх
baldman88
Дата 25.7.2016, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 210
Регистрация: 18.1.2009

Репутация: 1
Всего: 7



Mikron все верно написал. Только "или" перед знаком равенства излишне и можно это все упростить:
Код
for (i = 5; i <= 8; i++) {
    GPIOX->BSRR = (1 << i) | ((0x1E0 & (~(1 << i))) << 16);
}
По сути нужно в первые 16 бит записать единицу туда, где нужно выставить пин:
Код
(1 << i)
а в старшие 16 -- единицы туда, где сбросить:
Код
((0x1E0 & (~(1 << i))) << 16)
Дальше сделать логическое "или" и результат присвоить BSRR.

Это сообщение отредактировал(а) baldman88 - 25.7.2016, 13:56
PM MAIL   Вверх
qwerty4
Дата 28.7.2016, 16:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Диагност (самый настоящий, как Дядя Вова, тоже от верблюда)



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 14.7.2015

Репутация: нет
Всего: нет



Понаплодили тут извращенств  smile 

Код

for(int i = 1; i <= 8; i=i<<1)
    GPIOx_ODR = (GPIOx_ODR&0xFFFFFE1F)|(i<<5);


Это сообщение отредактировал(а) qwerty4 - 28.7.2016, 16:58
PM MAIL   Вверх
Mikron
Дата 28.7.2016, 17:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 50
Регистрация: 2.5.2007

Репутация: нет
Всего: нет



Цитата(qwerty4 @ 28.7.2016,  16:51)
Понаплодили тут извращенств  smile 

Код

for(int i = 1; i <= 8; i=i<<1)
    GPIOx_ODR = (GPIOx_ODR&0xFFFFFE1F)|(i<<5);

Все же рекомендуется регистр BSRR как я понимаю

user posted image

PM MAIL   Вверх
supercelt
Дата 28.7.2016, 18:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 658
Регистрация: 25.8.2005

Репутация: нет
Всего: 1



Да, рекомендуют работать именно с BSRR и BRR

Это сообщение отредактировал(а) supercelt - 28.7.2016, 18:51
PM   Вверх
qwerty4
Дата 29.7.2016, 13:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Диагност (самый настоящий, как Дядя Вова, тоже от верблюда)



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 14.7.2015

Репутация: нет
Всего: нет



Цитата(Mikron @  28.7.2016,  17:14 Найти цитируемый пост)
рекомендуется

Цитата(supercelt @  28.7.2016,  18:50 Найти цитируемый пост)
рекомендуют


Странные вы оба. Слышу звон, да не знаю где он. Перевожу на русский язык это ваше "рекомендуется":

Если не хотите заморачиваться с обеспечением атомарности чтения с последующей записью, то можете  использовать регистр B(S)RR. Если нет требований (как в исходном вопросе) к атомарности, то можете не использовать.
PM MAIL   Вверх
supercelt
Дата 28.8.2016, 14:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 658
Регистрация: 25.8.2005

Репутация: нет
Всего: 1



Голова уже кипит. Поделитесь пож опытом. Почему вот так работает

Код

unsigned char i, j;
                for(i = 0; i < 4; i++){
                        GPIOB->ODR = (1 << (i + 5));
                        for(j = 0; j < 4; j++){
                                if(GPIOB->IDR & 1 << (j + 11)){
                                        key = (1 << i);
                                        key |= (1 << j) << 4;
                                }
                        }
                }


А вот так не работает

Код

unsigned char i, j;
                for(i = 0; i < 4; i++){
                        GPIOB->BSRR = (uint32_t)(1 << (i + 5));
                        for(j = 0; j < 4; j++){
                                if(GPIOB->IDR & 1 << (j + 11)){
                                        key = (1 << i);
                                        key |= (1 << j) << 4;
                                }
                        }
                }


Я хочу через BSRR, а единица не скачет по битам а всё время стоит на последнем 8. Работает только когда использую ODR. Я уверен, что причина как всегда в какой-нибудь фигне. Просто пока у меня мало опыта)
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Микроконтроллеры (MCU) и микропроцессоры (MPU)"
PILOT ManiaK
UniBomb Mazzi

На данный раздел помимо Правил форума распространяются текже следующие правила:


  • Прежде чем создать тему воспользуйтесь поиском или посмотрите в faq. Возможно на форуме уже есть ответ на ваш или близкий к вашему вопрос.
  • В заголовке темы в квадратных скобках обозначьте используемое семейство микроконтроллера: [avr],[pic],[arm].
  • При создании темы с вопросом указывайте участок кода с ошибкой, версию компилятора, схемы подключения, fuse биты и прочие данные, которые помогут найти правильный ответ. Для форматирования текста программ используйте кнопку код.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Для флуда, просьб выполнить задание, поиска партнёров или исполнителей существуют свои разделы.
  • Если вы заметили несовместимое с правилами сообщение, то можете уведомить об этом модератора раздела нажав кнопку Репорт у соответствующего сообщения.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, PILOT, ManiaK, UniBomb, Mazzi.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Микроконтроллеры (MCU) и микропроцессоры (MPU) | Следующая тема »


 




[ Время генерации скрипта: 0.1354 ]   [ Использовано запросов: 20 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.