STM32的GPIO方向定义和方向寄存器的理解

好长时间没有摆弄STM32了,最近在学习MPU6050模块中遇到了关于GPIO方向定义的问题,查阅了网上的一些资料也不是特别好理解,因此在本博文中将以一种更轻松地方式去理解和解释这个问题。

接下来我们需要用到一些在STM32开发中常用的知识,其中涉及到了数字电子技术的许多内容。若有不明白的内容请查阅和参考数字电子技术相关参考资料。

首先,我们要明确为什么要对GPIO的方向去进行定义。这是由于IIC通信的特点所决定的,需要进行输入和输出的定义。以下代码是我在学习过程中所遇到的

//IO方向设置
#define MPU_SDA_IN()  {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=8<<28;}//0X8FFFFFFF
#define MPU_SDA_OUT() {GPIOB->CRL&=0X0FFF0FFF;GPIOB->CRL|=3<<28;}//0X3FFFFFFF

先说明一下我在IIC通信时定义的引脚。由于我采用的是STM32F103C8T6这款芯片,这款芯片有两个IIC总线接口,分别是PB6|PB7和PB10|PB11。因此在这里直接采用了PB6引脚作为IIC的SCL线,PB7引脚作为IIC的SDA线。

明确了总线的接口,接下来就到了令人头痛的环节—配置寄存器。

寄存器这个东西,本身就是一堆二进制数在这工作,它有个特性,就是只认0或1。对CPU或者MCU而言,这是它们喜闻乐见的交流方式;但是对开发者而言,稍微有些繁杂。

本次我们需要使用的寄存器是GPIO寄存器里的CRH和CRL寄存器。虽然也称为CRH,但是不是和谐号的CRH啊。

CRH和CRL寄存器如下图所示(在这里只列出了CRL寄存器,CRH寄存器同理):

在这里插入图片描述
先看到GPIOx中的x的取值范围,从A到E,也就是说STM32芯片有GPIOA、GPIOB、GPIOC、GPIOD、GPIOE这五个GPIO引脚大类。在这里我们要设置GPIOB,因此可以看到代码中对应了GPIOB。

在这里还需要明确一点,GPIOx大类下一般含有16个端口,端口的起始编号是0,结束编号是15,这是和数字电子技术中的编号是一致的,目的是在二进制、四进制、八进制、十六进制中实现对全零或全一时进行编号,例如在接下来用到的二进制中的0000和1111。由CRL寄存器控制的端口为GPIOB_0至GPIOB_7;由CRH寄存器控制的端口为GPIOB_8至GPIO_15。

在代码中,我们要设置SDA的模式,而SDA是由PB7,也就是GPIOB_7实现的,属于低八位,使用的寄存器是CRL寄存器,设置代码如下:

GPIOB->CRL&=0X0FFFFFFF

上述代码表示对应的位数清零,很明显在最高位也就是编号为7的位设置为0。这时,已经实现了GPIO_7对应的寄存器的清零工作,为下一步该位的设置做准备。

将对应的位清零后,接下来需要考虑这个位的设置问题。由于在这里希望其作输入,定义了一个输入函数MPU_SDA_IN(),因此需要将这个已经清零的位实现输入模式的设置,查看寄存器的设置要求,主要有两项,分别是CNF和MODE,在这里CNF7选择上拉/下拉输入模式,MODE7很明显只有一种输入选择,因此二者组合起来就是1000,对应的十六进制数是8。

但是不要忘了,作为开发者是认识8这个十六进制数的,但是MCU不认识啊,它只认识由0或1组成的二进制数。接下来要实现将上述分析的数(1000)赋值给已经清零的位,该怎么办呢?

下面的语句将实现对清零后的位进行赋值。

GPIOB->CRL|=8<<28

字面上看上去似乎是将8左移28位。恭喜,你已经离最后的结果不远了,只差临门一脚。在这里不要只看到8这个十六进制数,而是要看到8后面表示的二进制数1000。我们可以数一数CRL寄存器的总位数,一个端口(或者引脚)由CNF和MODE进行控制,CNF和MODE都占用两个位,因此一个端口就需要四个位才能实现模式和端口的选择。

当我们赋值时,1000位于CRL寄存器的低四位,也就是图中的3210位。当向左移动一个位时,1000的位置就变为4321位,当向左移动两个位时,1000的位置就变为5432位,以此类推。当我们希望将1000移动到清零后的位时,在这个例子中就需要向左移动28位。

移动完成后,我们可以计算最后的结果,可以看到最后赋值成功的结果就是0X8FFFFFFF。

同理,可以实现MPU_SDA_OUT()的设置。

这样就实现了IIC的输入和输出的定义,同时对于代码的可读性也有很大的提高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值