引脚的高、低电平控制,有3种方法(3个寄存器)
分别是通过GPIO的 3个 管脚控制寄存器:
- ODR寄存器, 控制管脚的高、低电平,低16位有效,写1 高电平, 写0 低电平;
- BSRR寄存器, 控制管脚的高、低电平,32位有效,低16位写1 高电平,高16位写1 低电平;
- BRR寄存器, 控制管脚的低电平,低16位有效,写1 低电平;
特别的: F1和F4系列都有 ODR和BSRR,但F4 取消了BRR。所以为了代码通用,尽量不使用BRR,反正BSRR能完成.
ODR、BSRR的使用区别:
你应该有过和我一样的疑问:
ODR寄存器只用低16位,就能控制引脚的高、低电平,还能读寄存器的值,用以判断引脚电平状态;
那么, 为什么要存在一个BSRR! 还分高、低16位! 还不能读寄存器的值!
写了几年的STM32代码, 一直在使用ODR, 几乎没用过BSRR. 直到今天查找F1和F4的GPIO操作区别时, 才发现BSRR的神奇之处。
(1) BSRR: 写入1生效, 写入0无动作. 同样置/复位, 比用ODR操作编译后要快几个动作, 想想以前用或/与操作, 真是多余了!
例如: PB1要设高电平, PB11设低电平;注意看注释
// 通过 ODR 寄存器
GPIOB->ODR |= 0X01 ; // 代码是一行, 但背后的运行是很多步:读取->或运算->写入
GPIOB->ODR &= ~(0X01<<11) ; // 同样是:读取->或运算->写入
// 通过 BSRR 寄存器
GPIOB->BSRR = 0X01 ; // 某个位直接置1,OK, 搞掂了。其它没置1的位不产生变化
GPIOB->BSRR = 0X01<<11; // 同上
(2) BSRR 操作, 不用关中断
这个不太理解, 功力不到时候. 引用网友的话吧:
“This way, there is no risk that an IRQ occurs between the read and the modify access.”
什么意思呢?就是你用BSRR和BRR去改变管脚状态的时候,没有被中断打断的风险。也就不需要关闭中断。
使用总结:
操作管脚状态, BSRR = 快 + 简单 !
(完~~~)