位操作
bit mask --位屏蔽
位屏蔽的含义是:从包含多个位集的一个或一组字节中选出指定的一(些)位。
作用分以下几类
1)为了检查一个字节中的某些位,可以让这个字节和屏蔽字(bit mask)进行按位与操作(C的按位与运算符为&)——屏蔽字中与要检查的位对应的位全部为1,而其余的位(被屏蔽的位)全部为0。
例如,为了检查变量 flags的最低位,你可以让flags和最低位的屏蔽字进行按位与操作:
flags &1;
2)为了置位所需的位,可以让数据和屏蔽字进行按位或操作(C的按位或运算符为|)。
例如,你可以这样置位flags的最低位:
flags |= 1;
3)为了清除所需的位,可以让数据和对屏蔽字按位取反所得的值进行按位与操作。
例如,你可以这样清除flags的最低位:
flags = flags& ~1;
或者这样:
flags&=~1 ;
一般用宏来处理标志会更方便,以adi_hal_internal.h为例,为了方便寄存器读写,做的api如下
///for analog die register operation
//置1
#define ANA_REG_OR(reg_addr, value) \
do{\
unsigned long flags; \
unsigned short adi_tmp_val;\
local_irq_save(flags);\
adi_tmp_val = ADI_Analogdie_reg_read(reg_addr); \
adi_tmp_val |= (unsigned short)(value); \
ADI_Analogdie_reg_write(reg_addr, adi_tmp_val); \
local_irq_restore(flags);\
}while(0)
/*
*设置某个(些)特定bit位
*如ADC某个寄存器的有32bit,其中0..3 bit表示adc的channel select,其值可以是0--15
*ADC_CS [3:0] R/W 4’h0 ADC channel ID, It is in 0 ~ 15.
*要设定此4bit可以使用以下接口,其中id赋值为0--15任意值,会写到寄存器相应位
*ANA_REG_MSK_OR(ADC_CS, id, ADC_CS_BIT_MSK);
*ADC_CS是寄存器地址
*#define ADC_CS_BIT_MSK 0x0F//adc channel id, it is 0-15
*/
#define ANA_REG_MSK_OR(reg_addr, value, msk) \
do{\
unsigned long flags; \
unsigned short adi_tmp_val;\
local_irq_save(flags);\
adi_tmp_val = ADI_Analogdie_reg_read(reg_addr); \
adi_tmp_val &= (unsigned short)(~(msk)); \
adi_tmp_val |= (unsigned short)((value)&(msk)); \
ADI_Analogdie_reg_write(reg_addr, adi_tmp_val); \
local_irq_restore(flags);\
}while(0)
//清0
#define ANA_REG_AND(reg_addr, value) \
do{\
unsigned long flags; \
unsigned short adi_tmp_val;\
local_irq_save(flags);\
adi_tmp_val = ADI_Analogdie_reg_read(reg_addr); \
adi_tmp_val &= (unsigned short)(value); \
ADI_Analogdie_reg_write(reg_addr, adi_tmp_val); \
local_irq_restore(flags);\
}while(0)
//这个用来直接设定全部bit位指定的值而不管原先的值
#define ANA_REG_SET(reg_addr, value) ADI_Analogdie_reg_write(reg_addr, (unsigned short)(value))
//这个用来读取寄存器的值
#define ANA_REG_GET(reg_addr) ADI_Analogdie_reg_read(reg_addr)