Пользовался - удобно. ИАР оптимизирует как надо.
{
// Для массива в RAM размером 8 бит.
#define WRITE_BIT_ARRAY_8( dst, index_dst, val ) dst=((dst)& \
(~(1<<(index_dst))))|((1&(val))<<(index_dst))
unsigned char _array8=0; // массив из 8 бит
unsigned char _bit=7;
// поставить и сбросить бит _bit в массиве бит _array8
WRITE_BIT_ARRAY_8( _array8,_bit,1);
printf("Set: %02x\n",_array8); // проверка - стоИт.
WRITE_BIT_ARRAY_8( _array8,_bit,0);
printf("Clr: %02x\n",_array8); // проверка - лежит.
}
{
// Для массива в RAM размером до 16 бит.
#define WRITE_BIT_ARRAY_16( dst, index_dst, val ) dst= \
(unsigned int)((((unsigned int)dst)& \
(~(1<<((unsigned int)index_dst))))| \
((1&((unsigned int)val))<<((unsigned int)index_dst)))
unsigned int _array16=0; // массив из 16 бит
unsigned char _bit=15;
// поставить и сбросить бит _bit в массиве бит _array16
WRITE_BIT_ARRAY_16( _array16,_bit,1);
printf("Set: %04x\n",_array16); // проверка - стоИт.
WRITE_BIT_ARRAY_16( _array16,_bit,0);
printf("Clr: %04x\n",_array16); // проверка - лежит.
}
{
// Для массива в RAM размером до 32 бит.
#define WRITE_BIT_ARRAY_32( dst, index_dst, val ) dst= \
(unsigned long)((((unsigned long)dst)& \
(~(1UL<<((unsigned long)index_dst))))| \
((1UL&((unsigned long)val))<<((unsigned long)index_dst)))
unsigned long _array32=0UL;
unsigned char _bit=31; // массив из 32 бит
// поставить и сбросить бит _bit в массиве бит _array32
WRITE_BIT_ARRAY_32( _array32,_bit,1);
printf("Set: %08lx\n",_array32); // проверка - стоИт.
WRITE_BIT_ARRAY_32( _array32,_bit,0);
printf("Clr: %08lx\n",_array32); // проверка - лежит.
}
{
// Копирование бита index_sou из байта sou, в бит
// index_dst байта dst.
unsigned char dst=0;
unsigned char sou=0xff;
unsigned char index_dst=3;
unsigned char index_sou=5;
dst=(dst&(~(1<<index_dst)))|((1&(sou>>index_sou))<<index_dst);
printf("%02x %02x \n",dst,sou);
}