сдвиг нуля по части регистра

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
supercelt
Открыл глаза
Сообщения: 68
Зарегистрирован: Вс авг 02, 2015 18:02:38

сдвиг нуля по части регистра

Сообщение supercelt »

STM32

Порт В. Использую пины 5 6 7 8. Изначально они open drain и вытянуты в высокоомку. То есть я на них записал 1. А теперь в цикле мне надо пройтись поочерёдно по каждому биту нулём

1111
0111
1011
1101
1110

Раньше было проще, так как конфа была другая и изначально там были нули и надо было пробросить единицу

for(i = 0; i < 4; i++){
GPIOB->BSRR = (1 << (i + 5));
}

А теперь надо нуль. Как это сделать покороче? и что бы не затронуть остальные неиспользуемые биты
Реклама
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: сдвиг нуля по части регистра

Сообщение Аlex »

По мимо регистра установки, существует ещё и регистр сброса по маске. Почему бы им не воспользоваться ?
Реклама
supercelt
Открыл глаза
Сообщения: 68
Зарегистрирован: Вс авг 02, 2015 18:02:38

Re: сдвиг нуля по части регистра

Сообщение supercelt »

Аlex писал(а):По мимо регистра установки, существует ещё и регистр сброса по маске. Почему бы им не воспользоваться ?
Это BRR? Я его пррбовал. Чето у меня не получилось. Как я понял в каждой итерации надо сначало установить везде 1, а потом ставить 0 там где надо. С 1 было проще. Ее можно было просто сдвигать.
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: сдвиг нуля по части регистра

Сообщение Z_h_e »

Регистр BSRR позволяет не только устанавливать отдельные биты, но и сбрасывать тоже.

Попробуйте вот так

Код: Выделить всё

GPIOB->LCKR=GPIO_LCKR_LCK9;
for(i = 8+16; i >= 5+16; i--){
GPIOB->BSRR = (1 << i)|(1<<(i-16+1));
}
GPIOB->LCKR=0;
Не проверял, смущает These bits are write-only and can be accessed in Word mode only. Быть может нельзя одновременно устанавливать и сбрасывать порты этим регистром.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
Эиком - электронные компоненты и радиодетали
BorisSPB
Встал на лапы
Сообщения: 145
Зарегистрирован: Ср фев 01, 2012 10:55:53

Re: сдвиг нуля по части регистра

Сообщение BorisSPB »

Так в том и фишка что can, а не must
Реклама
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: сдвиг нуля по части регистра

Сообщение Reflector »

Z_h_e писал(а): Не проверял, смущает These bits are write-only and can be accessed in Word mode only. Быть может нельзя одновременно устанавливать и сбрасывать порты этим регистром.
Word - это у них 32 бита. Кроме того там написано, что если сразу устанавливать и сбрасывать, то установка имеет приоритет.
Реклама
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: сдвиг нуля по части регистра

Сообщение Z_h_e »

Ну на счет World значит затупил. Тогда должно работать.
-------
Проще вообще без цикла и будет максимально быстро.

Код: Выделить всё

GPIOB->BSRR = (1 << (8+16));
GPIOB->BSRR = (1 << (7+16))|(1<<8);
GPIOB->BSRR = (1 << (6+16))|(1<<7);
GPIOB->BSRR = (1 << (5+16))|(1<<6);
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
supercelt
Открыл глаза
Сообщения: 68
Зарегистрирован: Вс авг 02, 2015 18:02:38

Re: сдвиг нуля по части регистра

Сообщение supercelt »

Сделал вот так

Код: Выделить всё

void KEYBOARD_SCAN(void){
		unsigned char i, j;
				for(i = 0; i < 4; i++){
						GPIOB->BSRR |= 0x1E0;
						GPIOB->BSRR |= (1 << (i + 5 + 16));
						for(j = 0; j < 4; j++){
								if(!(GPIOB->IDR & 1 << (j + 11))){
										key = (1 << i);
										key |= (1 << j) << 4;
								}
						}
				}	
				if(old_key == 0){
						old_key = key;
				} else {
								GPIOD->BSRR |= 0x4;
								if(!(key ^ old_key)){
										valid_key++;
								} else {
										valid_key = 0;
								}
								if(valid_key == 5){
										TIM2->CR1 &= ~TIM_CR1_CEN;	
										find_key = key;
										valid_key = 0;
										old_key = 0;
										key = 0;
										NVIC_EnableIRQ(EXTI15_10_IRQn);
									  GPIOB->BRR |= 0x1E0;
								}	
				}
}
Прикол все цифры работают норм, кроме 1 и 4. Когда жмёшь на 1 на экране - 4, когда жмёшь на 4 , на экране - 7. Либо при нажатии на 1 или 4 зависает.
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: сдвиг нуля по части регистра

Сообщение Аlex »

supercelt писал(а):Как я понял в каждой итерации надо сначало установить везде 1, а потом ставить 0 там где надо.
Наоборот. Где в маске стоит единица, там происходит сброс бита.
Просто двигайте единицу в маске и кидайте её в регистр сброса.
supercelt писал(а):Сделал вот так
Кошмар :shock:
BorisSPB
Встал на лапы
Сообщения: 145
Зарегистрирован: Ср фев 01, 2012 10:55:53

Re: сдвиг нуля по части регистра

Сообщение BorisSPB »

Для регистра BSRR чтение не имеет смысла - только запись, причем значение имеет запись единицы в тех разрядах, где биты должны быть изменены. Биты 0...15 устанавливают выход в 1, биты 16...31 сбрасывают выход в 0. Поэтому можно писать в этот регистр сразу 32 бита и без оператора |=, достаточно только =.
supercelt
Открыл глаза
Сообщения: 68
Зарегистрирован: Вс авг 02, 2015 18:02:38

Re: сдвиг нуля по части регистра

Сообщение supercelt »

Нету идей, почему вместо 1 вылезает 4, а вместо 4 вылезает 7 ??? Все остальные клавиши норм
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: сдвиг нуля по части регистра

Сообщение Аlex »

А у вас нету идей по поводу того, что сказали люди выше ?
Или вы слушаете только то, что хотите слушать ? Зачем тогда вопросы задавать ? :facepalm:
supercelt
Открыл глаза
Сообщения: 68
Зарегистрирован: Вс авг 02, 2015 18:02:38

Re: сдвиг нуля по части регистра

Сообщение supercelt »

Так я написал это после того, как сделал по наставлениям выше)))
Ответить

Вернуться в «ARM»