嵌入式开发寄存器编程几个常见的位操作

一、位操作


    C语言支持的6种位操作符如下:

1. 不改变其他位的值的状况下,对某几个位进行设值。
        方法:先对需要设置的位用&操作符(对应位&0)进行清零操作,然后用|操作符设值(对应位|你想要设定的值)。

举例:改变 GPIOA-> BSRRL 的状态  

GPIOA-> BSRRL &=0XFF0F;  //将第 4-7 位清 0
GPIOA-> BSRRL |=0X0040; //设置相应位的值,不改变其他位的值


2.  移位操作提高代码的可读性


         位操作在单片机开发中也非常重要,我们来看看下面一行代码

  GPIOx->ODR |= (((uint32_t)0x01) << pinpos);


这个操作就是将 ODR 寄存器的第 pinpos 位设置为 1,为什么要通过左移而不是直接设置一个固定的值呢?

其实,这是为了提高代码的可读性以及可重用性。这行代码可以很直观明了的知道,是将第 pinpos 位设置为 1。

如果你写成GPIOx->ODR =0x0040; 这样的代码就不好看也不好重用了。

 

3. ~取反操作使用技巧


        SR 寄存器的每一位都代表一个状态,某个时刻我们希望去设置某一位的值为 0,同时其他位都保留为 1,

简单的作法是直接给寄存器设置一个值:

      

  TIMx->SR=0xFFF7;


        这样的作法设置第 3 位为 0,但是这样的作法同样不好看,并且可读性很差。看看库函数
代码中怎样使用的:

     

   TIMx->SR &= (uint16_t)~TIM_FLAG;


        而 TIM_FLAG 是通过宏定义定义的值:

    #define TIM_FLAG  ((uint16_t)0x0001)
        看这个应该很容易明白,可以直接从宏定义中看出 TIM_FLAG_ 就是设置的第 0位了,可读性非常强。
总结:

        在实际开发过程中, 对寄存器的开发实际就是对位的操作,主要包括置1,清零,移位,取反等操作。

为说明方便,定义如下3个8位的寄存器:

#define   REG     0xFFFFFF10

1,对单个的位进行赋值

(1)    将寄存器REG的第5位置“1”

REG |= (1 << 5);

(2)    将寄存器REG的第5位清零

REG &= ~(1 << 5);

(3)    将寄存器REG的第3、5位置“1”

REG |= (1 << 5) | (1 << 3);

(4)    将寄存器REG的第3、5位清零

REG &= ~( (1 << 5) | (1 << 3) );

下面举例:

在实际寄存器开发过程中可以参考:

https://blog.csdn.net/yangyaokun0220/article/details/80166221

你可能感兴趣的:(Linux)