Сдвиг бита в части регистра

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

Сдвиг бита в части регистра

Сообщение supercelt »

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

Есть порт В микроконтроллера 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 строчки. Как?
Реклама
Аватара пользователя
GARMIN
Держит паяльник хвостом
Сообщения: 954
Зарегистрирован: Вс дек 02, 2012 16:58:33
Откуда: от туда
Контактная информация:

Re: Сдвиг бита в части регистра

Сообщение GARMIN »

supercelt писал(а):Здравствуйте.
Есть порт В микроконтроллера stm32
Я задействую 5,6,7,8 пины. Остальные служат под другие нужды.
В цикле for надо на 5 пин подать 1, а при следующем заходе в цикл - сдвигать ее влево. Получится, что цикл проворачивается и каждый раз нужно ставить 1 с 5 по 8 пин, при этом что бы остальные пины были 0.
Примерно так можно сделать:

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

const uint32_t mask = 0x000001E00;
uint32_t i;
for (i = 0x0020; i < 0x0200; i <<= 1)
{
    GPIOD->ODR = (GPIOD->ODR & ~mask) | i;
}
Реклама
Аватара пользователя
AVI-crak
Прорезались зубы
Сообщения: 202
Зарегистрирован: Сб янв 09, 2016 15:51:17
Контактная информация:

Re: Сдвиг бита в части регистра

Сообщение AVI-crak »

supercelt писал(а):Я уверен, что программеры с опытом делают это в 1 - 2 строчки. Как?
Неверное представление. Делается так - чтобы можно было понять смысл написанного, и легко изменить под текущие требования.
Спойлер

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

#define GPIO_Pin_0    (uint16_t) 1
#define GPIO_Pin_1    (uint16_t) 1<<1
#define GPIO_Pin_2    (uint16_t) 1<<2
#define GPIO_Pin_3    (uint16_t) 1<<3
#define GPIO_Pin_4    (uint16_t) 1<<4
#define GPIO_Pin_5    (uint16_t) 1<<5
#define GPIO_Pin_6    (uint16_t) 1<<6
#define GPIO_Pin_7    (uint16_t) 1<<7
#define GPIO_Pin_8    (uint16_t) 1<<8
#define GPIO_Pin_9    (uint16_t) 1<<9
#define GPIO_Pin_10   (uint16_t) 1<<10
#define GPIO_Pin_11   (uint16_t) 1<<11
#define GPIO_Pin_12   (uint16_t) 1<<12
#define GPIO_Pin_13   (uint16_t) 1<<13
#define GPIO_Pin_14   (uint16_t) 1<<14
#define GPIO_Pin_15   (uint16_t) 1<<15

/// Заюзанные ноги
#define Gpin5           GPIO_Pin_5
#define Gpin6           GPIO_Pin_6
#define Gpin7           GPIO_Pin_7
#define Gpin8           GPIO_Pin_8
#define Gpin5_6_7_8     (uint32_t)( Gpin5 | Gpin6 | Gpin7 | Gpin8 )

#define GpinL1     (uint32_t) (( Gpin5 ) << 16) | (Gpin5_6_7_8 ^ Gpin5)
#define GpinL2     (uint32_t) (( Gpin6 ) << 16) | (Gpin5_6_7_8 ^ Gpin6)
#define GpinL3     (uint32_t) (( Gpin7 ) << 16) | (Gpin5_6_7_8 ^ Gpin7)
#define GpinL4     (uint32_t) (( Gpin8 ) << 16) | (Gpin5_6_7_8 ^ Gpin8)



static uint32_t GpinL [4]={
GpinL1,GpinL2,GpinL3,GpinL4};

/// Запись в порт, у вас B.
/// GPIOB->BSRR = GpinL[x];

/// Правка структуры GPIO_TypeDef, BSRR - должен быть 32 бита,
///это разовое обращение к сбросу и установке, сброс важнее

//  __IO uint32_t IDR;      /*!< GPIO port input data register,         Address offset: 0x10      */
//  __IO uint32_t ODR;      /*!< GPIO port output data register,        Address offset: 0x14      */
//  >>>> тут __IO uint32_t BSRR;     /*!< GPIO port bit set/reset register,      Address offset: 0x18      */
//  __IO uint32_t LCKR;     /*!< GPIO port configuration lock register, Address offset: 0x1C      */
//  __IO uint32_t AFR[2];   /*!< GPIO alternate function registers,     Address offset: 0x20-0x24 */
//} GPIO_TypeDef;
У вас задача - в цикле дрыгать ногами не трогая всё остальное, это означает что можно посчитать таблицу средствами GCC, и очень удобно к ней обращаться.
Ответить

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