本文主要是介绍STM32GPIO寄存器CRL、CRH、IDR、ODR、BSRR、BRR,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
GPIO 寄存器描述
注意:本文以STM32F10XXX为参考,重在理解CRL与CRH
CRL与CRH分别为端口配置低与端口配置高寄存器,为32位寄存器,其中每四位控制一个I/O口
对CNFy与MODEy(y=0,1,2…7)位写1或0控制I/O口的输入输出模式
STM32I/O口都是16位的,CRL与CRH分别控制低8位与高8位,两个寄存器的用法与功能完全一模一样,下面来几个例子就明白了
e.g.PD1配置为推挽输出,最大速度50MHz
GPIOD->CRL=3<<4
新手注释:上方代码是对GPIOD_CRL寄存器左移4位再(即从第5位开始从右往左,前4位补0)写0011(至于为何写0011看上表),换算成十六进制就是0x0000 0030,如果还不理解(我只能说:唉!)可以在换成二进制看看
e.g.PC10配置为复用推挽输出,最大速度2MHz
GPIOC->CRH=0xA<<8
新手注释:0x为十六进制格式,A表示十进制10,换成二进制就是1010,聪明的你肯定明白了
问:“GPIOC-CRH”是什么意思?
答:表示GPIOC_CRH这一寄存器
问:GPIOC->CRH|=0X00038000 中"|"是什么意思?
答:“|”表示算术“或”,“1|1=1”,“1|0=1”,“0|0=0”
上方代码中“|”的作用是:在不影响其他I\O口的情况下仅对PC11、PC12进行配置
比如PC8、PC9已经配置好了,但你可能不知道配置的具体模式或者是懒得搭理,只晓得他两已经在用了,这时你又要对PC11、PC12进行配置,假设GPIOC_CRH寄存器的值已经为0x4444 44yy,此时GPIOC->CRH|=0X00038000就表示将0x4444 44yy|0x0003 8000的值写入寄存器,也就是将0x4447 C4yy写入GPIOC_CRH寄存器
IDR与ODR
IDR与ODR分别为输入与输出数据寄存器,即下图中的玩意儿
从图中也可以看到IDR只能读,而ODR可读可写,这两个寄存器的0与1分别反映了I/O口的低与高电平状态,IDR十分简单,ODR对应位写0或1可以控制I/O的状态,后面会详说
BSRR与BRR
BSRR与BRR分别叫做端口置位/复位、端口复位寄存器(有点蒙!!不怕)
BSRR为端口置位/复位寄存器,置位就是高电平、复位也就是低电平,这玩意是个32位寄存器,低16位控制置位、高16位控制复位
BRR为端口复位寄存器,这玩意虽然也是个32位寄存器但只有低16位可操作
注意:这两个寄存器的对应位只能写1有效
聪明的你肯定已经想到了:BSRR高16位与BRR功能完全一致
纳尼!为什么会有这种鸡肋的操作?
其实意法设置这两个寄存器还是有一定道理的,比如:
要求PC3输出高电平,PC5输出低电平
方法一:
GPIOC->BRSS|=1<<3
GPIOC->BRR|=1<<5
方法二:
GPIOC->BRSS|=(1<<3)|(1<<21)
两种方法虽然殊途同归,但重要的是方法一会导致PC3、PC5的电平变化不同步,方法二则可避免这一问题
再如:PC3输出高电平,PC端口其余引脚输出低电平
GPIOC->BRSS|=(1<<3)|((~(1<<3)&0xff)<<16)
用一句代码就能解决,但貌似对不太熟悉位操作的朋友有点复杂,多练练就好(套路)
看到这的朋友就可能会问前面的ODR既然可以控制I/O的高低电平,为什么还要BSRR、BRR这两个玩意!
这个我还不太明白,后续弄懂了再来说
但意法给了以下比较懵懂的答案
他的意思就是说在使用BSRR与BRR寄存器操作时不会与中断产生冲突,也就不会丢失中断事件,而使用ODR则会存在这一风险
下一篇:STM32I/O口配置上拉下拉输入寄存器版
这篇关于STM32GPIO寄存器CRL、CRH、IDR、ODR、BSRR、BRR的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!