Выборочное чтение битов Atmel Studio C/C++ ?

Обсуждаем контроллеры компании Atmel.
Ответить
Прорезались зубы
Сообщения: 213
Зарегистрирован: Вт сен 09, 2008 18:17:27

Сообщение DENIS451 »

Как считать биты, допустим, № 0, 1, 5, 7 из переменной unsigned char и послать их последовательно (задержку я потом поставлю) на пин №5 порта PORTB в Atmel Studio на C/C++ ?
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3059
Зарегистрирован: Пн май 11, 2009 14:15:00
Откуда: СПб

Сообщение *Trigger* »

Например, так:

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

#define setBit(var, n) (var |= (1 << (n)))
#define clrBit(var, n) (var &= ~(1 << (n)))
#define tstBit(var, n) (var & (1 << (n)))

unsigned char var;

//...

if(tstBit(var, 0)) setBit(PORTB, 5);
else clrBit(PORTB, 5);

if(tstBit(var, 1)) setBit(PORTB, 5);
else clrBit(PORTB, 5);

if(tstBit(var, 5)) setBit(PORTB, 5);
else clrBit(PORTB, 5);

if(tstBit(var, 7)) setBit(PORTB, 5);
else clrBit(PORTB, 5);
Этот пост оказался полезен? Не поленись, нажми Изображение слева!
:) :)) :)))
Куплю индикаторы ИТС-1А, ИТС-1Б, ИГВ1-8х5Л, ИГПС1-222/7, ИГПС1-111/7 и подобные.
Реклама
Прорезались зубы
Сообщения: 213
Зарегистрирован: Вт сен 09, 2008 18:17:27

Сообщение DENIS451 »

А попроще никак?
Друг Кота
Аватара пользователя
Сообщения: 3059
Зарегистрирован: Пн май 11, 2009 14:15:00
Откуда: СПб

Сообщение *Trigger* »

Да куда уж проще... Конечно, кода много (в символах), но нормальный компилятор каждый if/else превратит в 5 - 6 ассемблерных команд.

Если хочется покороче, можно использовать такой макрос:

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

#define cpyBit(dst, dst_n, src, src_n) (dst = ((dst) & (~(1 << (dst_n)))) | (((src) & (1 << (src_n))) ? (1 << (dst_n)) : 0))
Применять так:

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

cpyBit(PORTB, 5, var, 0);
cpyBit(PORTB, 5, var, 1);
cpyBit(PORTB, 5, var, 5);
cpyBit(PORTB, 5, var, 7);
Этот пост оказался полезен? Не поленись, нажми Изображение слева!
:) :)) :)))
Куплю индикаторы ИТС-1А, ИТС-1Б, ИГВ1-8х5Л, ИГПС1-222/7, ИГПС1-111/7 и подобные.
Реклама
Эиком - электронные компоненты и радиодетали
Прорезались зубы
Сообщения: 213
Зарегистрирован: Вт сен 09, 2008 18:17:27

Сообщение DENIS451 »

Второй вариант жрёт лишних 30 байт Program Memory Usage, по сравнению с первым.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3059
Зарегистрирован: Пн май 11, 2009 14:15:00
Откуда: СПб

Сообщение *Trigger* »

Конечно, это нормально. Компилятор не может догадаться, что там простые битовые операции, и не использует команды cbi / sbi. В первом случае догадывается.

Можно первый вариант целиком в макрос завернуть:

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

#define cpyBit(dst, dst_n, src, src_n) do{                           \
                                         if((src) & (1 << (src_n)))  \
                                           dst |= (1 << (dst_n));    \
                                         else                        \
                                           dst &= ~(1 << (dst_n));   \
                                       }while(0);
То же самое, но с тернарным оператором:

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

#define cpyBit(dst, dst_n, src, src_n) (((src) & (1 << (src_n))) ? (dst |= (1 << (dst_n))) : (dst &= ~(1 << (dst_n))))
Этот пост оказался полезен? Не поленись, нажми Изображение слева!
:) :)) :)))
Куплю индикаторы ИТС-1А, ИТС-1Б, ИГВ1-8х5Л, ИГПС1-222/7, ИГПС1-111/7 и подобные.
Реклама
Ответить

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