Битовые операции с микроконтроллерами Миландр

Целью битовых операций является изменение одного или нескольких битов в регистре или переменной не затрагивая значения других битов.

Нумерация бит начинается с нуля и идет справа налев0, соответственно самый младший бит (и самый правый) является нулевым.

Для задания номера бита я буду использовать шестнадцатеричную запись, чтобы отличать номер бита от его значения.

Для задания значения я иногда буду добавлять после него букву u, означающую беззнаковое число (unsigned), служащую для подавления предупреждения Keil "warning: implilcit conversion changes signedness: 'int' to 'unsigned int'".

Все примеры я буду приводить для регистра MDR_PORTB->RXTX, если нужно применить битовые операции к переменной то ее имя вставляется вместо MDR_PORTB->RXTX.

Если значения других битов не важны или должны быть нулями то используется операция присваивания.


MDR_PORTB->RXTX = (1 << 0x02); // Установка в 1 бита №2 (остальные биты регистра равны нулю)
MDR_PORTB->RXTX = ((1 << 0x02) | (1 << 0x03)); // Установка в 1 бита №2 и №3 
MDR_PORTB->RXTX = ((1 << 0x00) | (1 << 0x02) | (1 << 0x03)); // Установка в 1 бита №0, №2 и №3 
MDR_PORTB->RXTX = (3 << 0x02); // Установка в 1 бита №2 и №3 

Если значения других бит регистра нужно сохранять неизменными используют следующие битовые операции.

Установка бит


MDR_PORTB->RXTX |= (1 << 0x02); // Установка в 1 бита №2
MDR_PORTB->RXTX |= ((1 << 0x02) | (1 << 0x03)); // Установка в 1 бита №2 и №3
MDR_PORTB->RXTX |= ((1 << 0x00) | (1 << 0x02) | (1 << 0x03)); // Установка в 1 бита #0, №2 и №3
MDR_PORTB->RXTX |= (3 << 0x02); // Установка в 1 бита №2 и №3
MDR_PORTB->RXTX |= 0x0C;        // Установка в 1 бита №2 и №3

Сброс бит


MDR_PORTB->RXTX &= ~(1u << 0x02); // Сброс в 0 бита №2
MDR_PORTB->RXTX &= ~((1u << 0x02) | (1u << 0x03)); // Сброс в 0 бита №2 и №3
MDR_PORTB->RXTX &= ~((1u << 0x00) | (1u << 0x02) | (1u << 0x03)); // Сброс в 0 бита #0, №2 и №3
MDR_PORTB->RXTX &= ~(3u << 0x02); // Сброс в 0 бита №2 и №3
MDR_PORTB->RXTX &= 0xFFFFFFF3;    // Сброс в 0 бита №2 и №3 
MDR_PORTB->RXTX &= ~(0x0C);       // Сброс в 0 бита №2 и №3

Инверсия (изменение значения) бит


MDR_PORTB->RXTX ^= (1 << 0x02); // Инверсия значения бита №2
MDR_PORTB->RXTX ^= ((1 << 0x02) | (1 << 0x03)); // Инверсия значения бита №2 и №3
MDR_PORTB->RXTX ^= ((1 << 0x00) | (1 << 0x02) | (1 << 0x03)); // Инверсия значения бита #0, №2 и №3
MDR_PORTB->RXTX ^= (3 << 0x02); // Инверсия значения бита №2 и №3
MDR_PORTB->RXTX ^= 0x0C; // Инверсия значения бита №2 и №3	

Чтение бита и прочие операции


uint8_t bit_val = MDR_PORTB->RXTX & (1 << 0x03); // Считать значение бита №3
int val = byte1 | (byte2 << 8);  // Склейка двух байтов  byte2byte1
MDR_PORTB->RXTX = (MDR_PORTB->RXTX >> 1)  | (MDR_PORTB->RXTX << 15); // Циклический сдвиг влево значений регистра
MDR_PORTB->RXTX = (MDR_PORTB->RXTX << 1)  | (MDR_PORTB->RXTX >> 15); // Циклический сдвиг вправо значений регистра
MDR_PORTB->RXTX = (MDR_PORTB->RXTX << 16) | (MDR_PORTB->RXTX >> 16); // Поменять местами слова в 32х битном регистре (частный случай циклического сдвига)	
2024-04-21



Понравилась страница?
Добавить в закладки
Или поделиться!

Связанные темы

Битовые операции с микроконтроллерами Миландр