浅谈STM32的端口输出方式
扫描二维码
随时随地手机看文章
STM32有两个寄存器可以控制IO输出, 一个是ODR寄存器, 只使用了低16位. 向此寄存器写数据, 就可以控制某个引脚的输出电平.
BSRR寄存器是端口位设置/清除寄存器. 此寄存器和ODR寄存器有类似的功能, 都可以来用设置GPIO端口输出.此寄存器分为高16位和低16位, 向高16位的某位写1清除对应ODR寄存器位(输出0), 写0无影响. 向低16位某位写1置位对应ODR寄存器位(输出1), 写0无影响.
可见两个寄存器均可以控制IO输出, 从上文可知写BSRR实际上是可以影响ODR寄存器的值的, 那么使用这两个寄存器控制输出有什么区别呢?
在ST的手册中有这样的说明(RM0090 266页):
Each I/O port bit is freely programmable, however the I/O port registers have to accessed as 32-bit words, half-words or bytes. The purpose of the GPIOx_BSRR register is to allow atomic read/modify accesses to any of the GPIO registers. In this way, There is no risk of an IRQ occurring between the read and the modify access.
每个I/O端口位都可以自由编程, 然而I/O端口寄存器心須以32位字, 半字或者字节来访问, GPIOx_BSRR对任何端口寄存器的读/写访问均具有原子性. 以这种方式, 在读/写访问是发生中断并不会发生危险.
注:在STM32F1系列的手册中, I/O寄存器是只允许以32位字的方式访问, 半字和字节访问是不允许的.但在F4系列的手册中如上文,却并没有写不允许以半字或者字节的方式访问.
所以对IO的输出操作还是经过BSRR寄存器操作比较好.
在ST提供的固件库中提供了两个函数用来操作某一个IO:
12
voidGPIO_SetBits(GPIO_TypeDef*GPIOx,uint16_tGPIO_pin);voidGPIO_ReSetBits(GPIO_TypeDef*GPIOx,uint16_tGPIO_pin);
这两个函数的实现都是通过操纵BSRR寄存器来实现的.
这里再闲话一下STM32的端口控制方式: 传统的51, AVR等单片机是通过I/O控制寄存器写1/0来达到控制端口输出高/低, 显而易见, STM32的控制方式与其不同, 它是通过在两个不同的寄存器(实际上是一个寄存器的高低位, 为了好对比)中写1来完成输出高/低的, 写0无效.
这样做的好处是什么呢? 比如我要某个端口输出高, 我只要对它控制输出高电平的寄存器对应的位直接写1就可以了, 剩下的位不用管. 而传统的单片机, 我们要先将端口状态读回, 再小心翼翼的更改相应的位, 再写回去. 相比起来, STM32的操作方式简单多了, 并且出错的概率也小了许多.
全文完.