首页>>科技 >>内容

STM32,BSRR_BRR_ODR寄存器详情解析

发布时间:2023-09-16 10:14:26编辑:温柔的背包来源:

STM32,BSRR_BRR_ODR寄存器详情解析

很多朋友对STM32,BSRR_BRR_ODR寄存器详情解析不是很了解,每日小编刚好整理了这方面的知识,今天就来带大家一探究竟。

一、 Usage You will often see macro definition statements similar to the following. Used to output high and low levels to the initialized image orthographic tube. Define set _ bl _ high () gpioa-"bsrr=gpio _ pin _ 0 # define set _ bl _ low () gpioa-"brr=gpio _ pin _ 0, which is similar to the following two library functions. void GPIO _ set bits(GPIO _ Typedef * GPIO x,uint16_t GPIO_Pin)void GPIO _ reset bits(GPIO _ Typedef * GPIO x,uint 16 _ t GPIO _ Pin)

事实上,这两个库函数通过修改BSRR和BRR寄存器的值来设置IO端口。下面是输出高电平的函数体:Void gpio _ set bits(gpio _ typedef * gpiox,uint 16 _ t gpio _ pin){assert _ param(is _ gpio _ all _ peri ph(gpiox));assert _ param(IS _ GPIO _ PIN(GPIO _ PIN));GPIOx-》BSRR=GPIO _ Pin;因此,使用宏或库函数本质上是一样的。区别在于使用宏更快,使用函数更灵活。

二、说明BSRR和BRR都是STM32系列MCU中的GPIO寄存器。BSRR称为端口位设置/清除寄存器,BRR称为端口位* *寄存器。BSRR的低16位用于设置GPIO口相应的位输出高电平,高16位用于设置GPIO口相应的位输出低电平。BRR的低16位用于设置GPIO端口相应的位输出低电平。高16位为保留地址,读写无效。

所以理论上,BRR寄存器的作用和BSRR寄存器的高16位是一样的。换句话说,有两种方法可以输出低级宏语句。# define set _ bl _ low()gpioa-"BRR=gpio _ pin _ 0等价于# define set _ bl _ low()gpioa-"bsrr=gpio _ pin _ 0"16

这样,BRR登记册实际上是多余的。事实上,在最新的STM32F4系列单片机的GPIO寄存器中,已经找不到BRR寄存器,只保留了BSRR寄存器来实现端口输出的高低电平。所以在STM32F4系列单片机的库函数中,输出高低电平到GPIO口的函数是如下形式:Voidhal _ GPIO _ Write引脚(GPIO _ TypeDef * GPIOX,uint16_t GPIO_Pin,GPIO _ PIN State引脚状态){

assert _ param(IS _ GPIO _ PIN(GPIO _ PIN));assert _ param(IS _ GPIO _ PIN _ ACTION(PinState));如果(PinState!=GPIO _ PIN _ RESET){ GPIOx-》BSRR=GPIO _ PIN;} else { GPIOx-》BSRR=(uint 32 _ t)GPIO _ Pin《16U;}}可见,不管是输出高还是输出低,都是对BSRR寄存器的操作。

三、BSRR,BRR和ODR配置BSRR。BRR用于配置端口输出,ODR寄存器也用于输出数据。一个ODR寄存器控制一组(16位)GPIO输出。因此,修改ODR也可以实现IO口输出的配置。但是,由于ODR寄存器的读写操作必须以16位的形式进行。因此,如果用ODR重写数据来控制输出,就必须以“读-修改-写”的形式完成。

假设你需要输出一个高电平到GPIOA_Pin_6。重写ODR寄存器时,使用“读-改-写”操作,代码如下:uint32 _ t temptemp=GPIOA-》ODR;temp=temp | GPIO _ Pin _ 6;GPIOA-》ODR=temp;重写BSRR寄存器时,只需要使用以下语句:gpioa-bsrr=gpio _ pin _ 6;

这是因为在修改ODR时,为了保证端口6的修改不会影响其他端口的输出,需要保存该端口的原始数据,然后修改端口6的值,最后写入寄存器。对于BSRR,写1有效,写0不改变原来的状态,所以端口6可以设置为1,其他位可以保持为0。BSRR为1的位将修改相应的ODR位来控制输出电平。

BSRR的操作可以实现原子操作。所以在设置单个IO口输出时,使用BSRR进行操作会更加方便。然而,也有例外。当单个IO口需要Toggle(即电流输出反相,电流输出高输出低,电流输出低输出高)时,官方库函数直接操作ODR寄存器。代码如下:void Hal _ gpio _ toggle pin(gpio _ typedef * gpiox,uint16 _ tpio _ pin) {

assert _ param(IS _ GPIO _ PIN(GPIO _ PIN));gpiox-》ODR ^=gpio _ pin;}这是因为0和1与1的异或运算是反转的,0和1与0的异或运算保持了原来的值。如下:0 1=11 1=0 0 0=01 0=1。

以上知识分享希望能够帮助到大家!