新随笔  :: 联系 :: 订阅 订阅  :: 管理

STM32系统开发--位、字节操作

Posted on 2024-01-17 15:06  日暮途远7  阅读(175)  评论(0编辑  收藏  举报

  针对MCU的嵌入是开发中经常涉及到寄存器的操作,例如GPIO配置低寄存器GPIOx_CRL(共32个bit),有时需要改变其中的一位或者几位bit值,同时不能影响其它bit位的值。

 例如,需要设置第0位bit=1时,不能简单的设置为:GPIOx_CRL=0x01 ,这样的方法会使得低配置寄存器GPIOx_CRL的其它比特位都置为0。

对于二进制位操作来说:

不管该位原来的值是0还是1,它跟0进行&运算,得到的结果都是0,而跟1进行&运算,将保持原来的值不变;

不管该位原来的值是0还是1,它跟1进行|运算,得到的结果都是1,而跟0进行|运算,将保持原来的值不变。

因此,设置第几位需要置1就将0x01左移几位,如:

GPIOx_CRL  |=   (0x01 << 0);

位操作用法可分为4类:

1、寄存器数据的位、字节读取操作:1)提取某一个字节,2)提取某一位;

2、寄存器数据的位、字节清零操作:1)清零某一个字节,2)清零某一位;

3、寄存器数据的位、字节置1操作: 1)将某一个字节置1, 2)将某一位置1;

4、判断某一位或某几位连续的值:1)判断某一位的值,2)判断某几位连续位的值。

1. 位、字节读取操作

/*以提取int型变量中某个字节为例*/
#define    GET_LOW_BYTE0(x)    ((x >>  0) & 0x000000ff)    /* 获取第0个字节 */
#define    GET_LOW_BYTE1(x)    ((x >>  8) & 0x000000ff)    /* 获取第1个字节 */
#define    GET_LOW_BYTE2(x)    ((x >> 16) & 0x000000ff)    /* 获取第2个字节 */
#define    GET_LOW_BYTE3(x)    ((x >> 24) & 0x000000ff)    /* 获取第3个字节 */
/*提取一字节变量中的某一位*/
#define    GET_BIT(x, bit)    ((x & (1 << bit)) >> bit)    /* 获取第bit位 */

2. 位、字节清零操作

/*清零int型变量中某一个字节*/
#define    CLEAR_LOW_BYTE0(x)    (x &= 0xffffff00)    /* 清零第0个字节 */
#define    CLEAR_LOW_BYTE1(x)    (x &= 0xffff00ff)    /* 清零第1个字节 */
#define    CLEAR_LOW_BYTE2(x)    (x &= 0xff00ffff)    /* 清零第2个字节 */
#define    CLEAR_LOW_BYTE3(x)    (x &= 0x00ffffff)    /* 清零第3个字节 */
/*清零一字节变量中的某一位*/
#define    CLEAR_BIT(x, bit)    (x &= ~(1 << bit))    /* 清零第bit位 */

3. 位、字节置1操作

/*int型变量中的某个字节置1*/
#define    SET_LOW_BYTE0(x)  (x |= 0x000000ff)    /* 第0个字节置1 */
#define    SET_LOW_BYTE1(x)  (x |= 0x0000ff00)    /* 第1个字节置1 */
#define    SET_LOW_BYTE2(x)  (x |= 0x00ff0000)    /* 第2个字节置1 */
#define    SET_LOW_BYTE3(x)  (x |= 0xff000000)    /* 第3个字节置1 */
/*一字节变量中的某一位置1*/
#define    SET_BIT(x, bit)    (x |= (1 << bit))    /* 置位第bit位 */

 

实例:通过定义一个位结构体对其赋值,再按位(小端)读取,实现位读取与置位操作。

struct eightbitdata_t{
    uint8_t a:1 ;
    uint8_t b:1 ;
    uint8_t c:1 ;
    uint8_t d:1 ;
    uint8_t e:1 ;
    uint8_t f:1 ;
    uint8_t g:1 ;
    uint8_t h:1 ;
    
};
uint8_t get_8bitdata(void);

struct imu_status_t{
    uint8_t accx;
    uint8_t accy;
    uint8_t accz;
    uint8_t gyrox;
    uint8_t gyroy;
    uint8_t gyroz;
    uint8_t temperature;
    uint8_t rsv;
};
/************************************************
函数名称 :位结构体测试函数
功    能 :
参    数 :
返 回 值 :返回整合好的一字节数据
*************************************************/
uint8_t get_8bitdata(void)
{
    struct eightbitdata_t otto={1,0,1,0,1,0,1,0};
    struct imu_status_t imu_status={0,0,0,0,0,0,0,0};
    //移位操作实现
    uint8_t  status;
    status=otto.a|(otto.b<<1)|(otto.c<<2)|(otto.d<<3)|(otto.d<<4)|(otto.e<<5)|(otto.f<<6)|(otto.g<<7);    
    //接收到一字节八位状态量,解析
    imu_status.accx=GET_BIT(status, 6);
    return imu_status.accx;
}