Обсуждаем контроллеры компании Atmel.
Ответить

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

Вт июл 17, 2018 19:39:05

Как считать биты, допустим, № 0, 1, 5, 7 из переменной unsigned char и послать их последовательно (задержку я потом поставлю) на пин №5 порта PORTB в Atmel Studio на C/C++ ?

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

Вт июл 17, 2018 20:15:28

Например, так:
Код:
#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);

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

Вт июл 17, 2018 20:31:36

А попроще никак?

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

Вт июл 17, 2018 20:50:49

Да куда уж проще... Конечно, кода много (в символах), но нормальный компилятор каждый 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);

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

Вт июл 17, 2018 21:09:22

Второй вариант жрёт лишних 30 байт Program Memory Usage, по сравнению с первым.

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

Вт июл 17, 2018 21:20:03

Конечно, это нормально. Компилятор не может догадаться, что там простые битовые операции, и не использует команды 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))))
Ответить