当前位置:首页 > 单片机 > 单片机
[导读] 一、用法经常会看到类似如下的宏定义语句,用于对已经初始化后的 IO 口输出高、低电平。#define SET_BL_HIGH() GPIOA->BSRR=GPIO_Pin_0#define SET_BL_LOW() GPIOA->BRR=GPIO_Pin_012其作用类似于如下两个库函数,v

 一、用法

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

#define SET_BL_HIGH() GPIOA->BSRR=GPIO_Pin_0

#define SET_BL_LOW() GPIOA->BRR=GPIO_Pin_012

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

void GPIO_SetBits(GPIO_Typedef* GPIOx, uint16_t GPIO_Pin)

void GPIO_ResetBits(GPIO_Typedef* GPIOx, uint16_t GPIO_Pin) 12

而且实际上这两个库函数就是通过修改BSRR,BRR寄存器的值来实现对 IO 口设置的。如下便是输出高电平的函数体:

void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

{

/* Check the parameters */

assert_param(IS_GPIO_ALL_PERIPH(GPIOx));

assert_param(IS_GPIO_PIN(GPIO_Pin));

GPIOx->BSRR = GPIO_Pin;

}12345678

因此,使用宏或者库函数本质上都是一样的。区别在于使用宏更快,而使用函数更灵活。

二、解释

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 123

这么来看的话,其实 BRR 寄存器是比较多余的。而实际上,在最新的 STM32F4 系列 MCU 的 GPIO 寄存器中,已经找不到 BRR 寄存器了,仅保留了 BSRR 寄存器用于实现端口输出高低电平。因此,在 STM32F4 系列 MCU 的库函数中,对 GPIO 口输出高低电平的函数为如下形式:

void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)

{

/* Check the parameters */

assert_param(IS_GPIO_PIN(GPIO_Pin));

assert_param(IS_GPIO_PIN_ACTION(PinState));

if(PinState != GPIO_PIN_RESET)

{

GPIOx->BSRR = GPIO_Pin;

}

else

{

GPIOx->BSRR = (uint32_t)GPIO_Pin << 16U;

}

}123456789101112131415

可见,不管是输出高还是输出低,都是对 BSRR 寄存器的操作。

三、BSRR、BRR、 ODR 之间的关系

配置 BSRR , BRR 是为了对端口输出进行配置,而 ODR 寄存器也是用于输出数据的寄存器,一个 ODR 寄存器控制了一组(16位)的 GPIO 输出。因此,对 ODR 进行修改也可以到达对 IO 口输出进行配置。

但是,由于对 ODR 寄存器的读写操作必须以 16 位的形式进行。因此,如果使用 ODR 改写数据以控制输出时,须采用“读-改-写”的形式进行。

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

uint32_t temp;

temp = GPIOA->ODR;

temp = temp | GPIO_Pin_6;

GPIOA->ODR = temp;1234

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

GPIOA->BSRR = GPIO_Pin_6;1

这是因为在修改 ODR 时,为了确保对端口 6 的修改不会影响到其他端口的输出,需要对端口的原始数据进行保存,之后再对端口 6 的值进行修改,最后再写入寄存器。而对 BSRR 的操作,是写 1 有效,写 0 不改变原状态,因此可以对端口 6 置 1,其他位保持为 0。BSRR 为 1 的位,会修改相应的 ODR 位,从而控制输出电平。

对 BSRR 的操作可以实现原子操作。因此在设置单个 IO 口输出时,使用 BSRR 进行操作会更加方便。

但也有例外的时候,在需要对单个IO口进行 Toggle 操作时(即对当前输出取反输出,当前输出为高则输出低,当前输出低则输出高),官方的库函数就是直接对 ODR 寄存器进行操作的。代码如下:

void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

{

/* Check the parameters */

assert_param(IS_GPIO_PIN(GPIO_Pin));

GPIOx->ODR ^= GPIO_Pin;

}1234567

这是因为,0 和 1 与 1 进行异或操作被取反,0 和 1 与 0 进行异或操作保持原值。如下:

0 ^ 1 = 1

1 ^ 1 = 0

0 ^ 0 = 0

1 ^ 0 = 1

声明:本文仅代表作者本人观点,不代表本站观点,如有问题请联系站方处理。
换一批
延伸阅读

处理特定任务的单片机可减轻主单片机或微处理器的任务和工作负荷,从而有助于简化各种应用的设计流程。

关键字: Microchip 单片机 RTOS

触控按键产品应用推陈出新,终端产品朝向智能化趋势发展,市场迈入高速成长阶段,合泰半导体(HOLTEK)全新推出资源更丰富、效能更高的5V宽电压Arm® Cortex®-M0+ 触控单片机HT32F542xx系列,型号为H...

关键字: 智能化 HOLTEK 单片机

芯岭技术的智能电压电流表方案,主控芯片采用了九齐NY8A054E单片机,通过电路设计,搭建功能模块完成产品的开发,主控芯片控制电路,负责开关控制,其主要的操作功能如下: 1、显示范围:-1999至1999,测直流电流时...

关键字: 解决方案 芯岭技术 方案开发 单片机

智能车载空气净化器机器内的微风扇(又称通风机)使车内空气循环流动,污染的空气通过机内的PM2.5过滤网和活性炭滤芯后将各种污染物过滤或吸附,然后经过装在出风口的负离子发生器(工作时负离子发生器中的高压产生直流负高压),将...

关键字: 解决方案 芯岭技术 方案开发 单片机

智能净水器是一种低废水排放的设备,通过程序设置,智能净水器可以智能判断净水器的使用情况,实现自动清洗和污水排放,智能识别净水器滤芯的剩余使用时间,并及时智能提醒更换滤芯。可以有效滤除水中的铁锈、砂石、胶体以及吸附水中余氯...

关键字: 解决方案 芯岭技术 方案开发 单片机

中国,北京 – 2022年5月5日 – Analog Devices, Inc.(Nasdaq:ADI)推出新一代16至24位超高精度逐次逼近寄存器(SAR)模数转换器(ADC)系列产品,可简化仪器仪表、工业和医疗健康应...

关键字: 模数转换器 寄存器 ADI

该智能声控灯方案,主控芯片采用九齐单片机NY8A062D。智能声控灯是通过声波信号来控制灯泡点亮的,当声控灯周围有较强的声波信号时,其内部的声音传感器,也就是我们平时说的话筒将接收到的声波信号转换成电信号,再经放大、整形...

关键字: 解决方案 芯岭技术 方案开发 单片机

该智能感应路灯解决方案是通过单片机控制,通过调节占空比来控制灯亮及灯灭,同时结合红外感应模块和pwm控制来感应人体,当路灯探知到人体的热辐射时,调高灯的亮度,人离开后降低灯的高度,实现智能感应的功能。

关键字: 智慧城市 解决方案 芯岭技术 方案开发 单片机

Microchip推出5个新产品系列和60多款新器件,进一步丰富8位PIC®和AVR®单片机

关键字: 嵌入式设计 Microchip 单片机

芯岭技术的灭蚊灯解决方案,采用了封装型号为8引脚sop的九齐NY8A054E型号单片机作为该游戏手柄充电座的主控芯片,负责开关控制、定时和倾倒提示等功能。

关键字: 芯岭技术 灭蚊灯方案开发 单片机

编辑精选

技术子站

关闭