寄存器的秒懂操作
一、寄存器操作的分类
寄存器的操作主要是读操作以及写操作,写操作中主要有直接赋值法多位赋值法和单BIT赋值法,直接赋值法主要适用于要将寄存器整体的值全部的强制的修改,而多位赋值法和单Bit赋值法主要是指改变单个或者多个位不改变其他位的值,而读操作是指读取一个寄存器单个或多个位的值,不改变原来的值。
二、寄存器读操作
例如:现在有一个寄存器P0MOD(此时可以见寄存器看作是一个变量,每一个变量中的每一个Bit都可以看作具备是特殊功能的开关),我要对P0MOD的第3位进行读操作。
//当前P0MOD的值为171 转为16进制为0xAB 转为二进制为 10101011
int i; //设定一个值保存读到的数据
i = P0MOD & (1 << 2); //要读哪位就将该值与上1左移第几位-1 (<<表示左移)
printf("%d",i);
//打印当前值为0 ,所以第三位的值为零
//如果i=4,也就是i != 0;可以得到P0MOD的第3位为1;
三、寄存器的写操作
当我们要对寄存器进行写操作时,主要是要考虑对寄存器进行操作时不要影响其他位的值,所以我将写操作概括位一个四字总结:“或1与0”,也就是说当我想要对他进行写0操作时用或运算,我想要对他进行写1操作时用与运算,具体如下:
//如果当前P0MOD的值仍为171 转为16进制为0xAB 转为二进制为 10101011
//我要对当前寄存器的第三位进行写1操作,这时候我们可以用或操作
P0MOD = P0MOD | (1 << 2); => 简写为: P0MOD |= (1 << 2);
//此时P0MOD的值为 10101 1 11
//假如我要已经对当前寄存器的第三位进行了写1操作,但是我现在又想将他写回0,这时候我们可以用与操作
P0MOD = P0MOD & ~(1 << 2); => 简写为: P0MOD &= ~(1 << 2);
//此时P0MOD的值为 10101 0 11
//注意与操作用的也时1左移进行选位,需要将整体取反后才能得到反码与寄存器才能达到效果。
四、寄存器的多位操作
对寄存器中多个位进行操作可以先将对应位进行清零,再把相对应的位写上1
//如果当前P0MOD的值仍为171 转为16进制为0xAB 转为二进制为 10101011
//我要对当前寄存器的低三位进行写101操作
P0MOD &= ~(7 << 0); //7 转为二进制是111 此时低三位为10101 000
//再将第0位和第3位进行写1,可得;
P0MOD |= (5 << 0); //5 转为二进制是101 此时低三位为10101 101
//之所以要先清0,是因为避免原来是1时,再或一个1,结果仍为1。
1 | 0 == 1; 1 | 1 ==1; // 如果原本为1,此时不管或任何值都不变;
五、寄存器宏定义操作的写法
#define NUMBER(NUM) (1<<NUM ) //根据传入的NUM值选择对应的位
#define RESET 0 //定义0
#define SET 1 //定义1
//根据REORSET的值判断是写入0还是写入1
#define WRITE_REG(REG,NUM,REORSET) REORSET?(REG|=NUM):(REG&=~NUM)
//根据(REG&NUM)的值是0还是非0来决定当前的宏是0还是1
#define READ_REG(REG,NUM) ((REG&NUM))?(1):(0)
int main(void)
{
char reg = 0; //创建一个变量reg
WRITE_REG(reg,NUMBER(4),SET); //写入变量的第5个位为1
printf("%d\n",reg); //读取当前reg为16
printf("%d\n",READ_REG(reg,NUMBER(4))); //使用读取宏打印1
WRITE_REG(reg,NUMBER(4),RESET); //写入变量的第5个位为0
printf("%d\n",READ_REG(reg,NUMBER(4))); //使用读取宏打印1为0
return 0;
}
七、总结
对寄存器的操作可以控制单片机的运行,以上的操作可以对控制单片机来说已经足够了,如果有更好的想法欢迎私信交流。