GPIO口 寄存器的使用

基础知识
ORD,BSRR,BRR[寄存器] 的作用是对已经初始化后的 IO 口输出高、低电平。

  • ***ODR寄存器****可读可写,32位,既能控制管脚为高电平,也能控制管脚为低电平。GPIO管脚对于位写1为高电平,写 0 为低电平。(低 16 位用于设置 GPIO 口对应位输出高/低电平。高 16 位保留地址,读写无效。)

    *BSRR寄存器* 称为端口位设置/清除寄存器,只写寄存器,32位, 既能控制管脚为高电平,也能控制管脚为低电平,对寄存器高 16位 写1 对应管脚为低电平,对寄存器低16位写1对应管脚为高电平。写 0 ,无动作

    BRR寄存器称为端口位清除寄存器,只写寄存器,32位, 只能改变管脚状态为低电平,寄存器管脚对应位写 1 相应管脚会变为低电平。写 0 无动作。(BRR低 16 位用于设置 GPIO 口对应位输出低电平。高 16 位保留地址,读写无效。)

    所以理论上来讲,BRR 寄存器的功能(低16位)和 BSRR 寄存器高 16 位的功能是一样的。

    BSRR、BRR、 ODR 之间的关系
    配置 BSRR , BRR 是为了对端口输出进行配置,而 ODR 寄存器也是用于输出数据的寄存器,一个 ODR 寄存器控制了一组(16位)的 GPIO 输出。因此,对 ODR 进行修改也可以到达对 IO 口输出进行配置。
    由于对 ODR 寄存器的读写操作必须以 16 位的形式进行。因此,如果使用 ODR 改写数据以控制输出时,须采用“读-改-写”的形式进行。
    BRR、BSRR都可以做到假如只想改变位0的值,则不论其他位为何值,用一个等号就可以完成。
    而ODR改变时则是全部改变。
    比如16位本来为1010101010101010,经过GPIOx->BSRR=0x01后变为1010101010101011,而经过GPIOx->ODR=0x01后变为0000000000000001。

实例分析
实例1
经常会看到类似如下的宏定义语句,用于对已经初始化后的 IO 口输出高、低电平。

\#define SET_BL_HIGH() GPIOA->BSRR=GPIO_Pin_5
\#define SET_BL_LOW() GPIOA->BRR=GPIO_Pin_010

其作用类似于如下两个库函数,

void GPIO_SetBits(GPIO_Typedef* GPIOx, uint16_t GPIO_Pin)
void GPIO_ResetBits(GPIO_Typedef* GPIOx, uint16_t GPIO_Pin)

而且实际上这两个库函数就是通过修改BSRR,BRR寄存器的值来实现对 IO 口设置的
因此,使用宏或者库函数本质上都是一样的。区别在于使用宏更快,而使用函数更灵活。

实例2
在使用寄存器BSRR 和寄存器BRR时,使用规则总结如下:
1、置GPIOD->BSRR低16位的某位为’1’,则对应的I/O端口置’1’;而置GPIOD->BSRR低16位的某位为’0’,则对应的I/O端口不变。
2、置GPIOD->BSRR高16位的某位为’1’,则对应的I/O端口置’0’;而置GPIOD->BSRR高16位的某位为’0’,则对应的I/O端口不变。
3、置GPIOD->BRR低16位的某位为’1’,则对应的I/O端口置’0’;而置GPIOD->BRR低16位的某位为’0’,则对应的I/O端口不变。

使用场合举例如下:
1)要设置D0、D5、D10、D11为高,而保持其它I/O口不变,只需一行语句:
GPIOD->BSRR = 0x0C21;// 使用规则1
2)要设置D1、D3、D14、D15为低,而保持其它I/O口不变,只需一行语句:
GPIOD->BRR = 0xC00A;// 使用规则三
3)要同时设置D0、D5、D10、D11为高,设置D1、D3、D14、D15为低,而保持其它I/O口不变,也只需一行语句:
GPIOD->BSRR = 0xC00A0C21;// 使用规则一和规则二

实例3
假设需要对 GPIOA_Pin_6 输出高电平。采用改写 ODR 寄存器的方式时,使用“读-改-写”操作,代码如下:

uint32_t temp;
temp = GPIOA->ODR;
temp = temp | GPIO_Pin_4;
GPIOA->ODR = temp;

而使用改写 BSRR 寄存器时,仅需要使用如下语句:

GPIOA->BSRR = GPIO_Pin_6;

在修改 ODR 时,为了确保对端口 6 的修改不会影响到其他端口的输出,需要对端口的原始数据进行保存,之后再对端口 6 的值进行修改,最后再写入寄存器(即读-改-写形式改变位的状态)。而对 BSRR 的操作,是写 1 有效,写 0 不改变原状态,因此可以对端口 6 置 1,其他位保持为 0。BSRR 为 1 的位,会修改相应的 ODR 位,从而控制输出电平。
因此,在设置单个 IO 口输出时,使用 BSRR 进行操作会更加方便。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值