三.关于STM32F4找不到BRR或BSRR的问题
在移植LCD驱动时发现了个问题:编译器找不到BSRR和BRR寄存器,如下:
#define SCL_H GPIOB->BSRR = GPIO_Pin_6
#define SCL_L GPIOB->BRR = GPIO_Pin_6
1.库函数替代
这里要注意的是F4系列已经没有这BRR寄存器了,但其实对这两个寄存器的操作就相当于拉低或拉高相应GPIO的电平,我们完全可以以库函数来代替:
void GPIO_SetBits(GPIO_Typedef* GPIOx, uint16_t GPIO_Pin)
void GPIO_ResetBits(GPIO_Typedef* GPIOx, uint16_t GPIO_Pin)
2.寄存器
或者我们还可以用BSRRH和BSRRL代替,如下:
#define SCL_H GPIOB->BSRRH = GPIO_Pin_6
#define SCL_L GPIOB->BSRRL = GPIO_Pin_6
原因如下:
BSRR 和 BRR 都是 STM32 系列 MCU 中 GPIO 的寄存器。 BSRR 称为端口位设置/清楚寄存器,BRR称为端口位清除寄存器。
BSRR 低 16 位用于设置 GPIO 口对应位输出高电平,高 16 位用于设置 GPIO 口对应位输出低电平。
BRR 低 16 位用于设置 GPIO 口对应位输出低电平。高 16 位为保留地址,读写无效。
我们详细观察库函数:
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;
}
}
3.寄存器偏移
于是我们又可以总结出一种方法
#define SCL_H GPIOx->BSRR = (uint32_t)GPIO_Pin << 16U;
#define SCL_L GPIOx->BSRR = GPIO_Pin;