提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 一、模式配置寄存器CRL和CRH
- 二、端口输入数据寄存器(GPIOx_IDR) (x=A..E)
- 三、端口输出数据寄存器(GPIOx_ODR) (x=A..E)
- 四、端口位设置/清除寄存器(GPIOx_BSRR) (x=A..E)
- 五、端口位清除寄存器(GPIOx_BRR) (x=A..E)
- 六、端口配置锁定寄存器(GPIOx_LCKR) (x=A..E)
前言
1、主要介绍stm32GPIO 相关的寄存器。
STM32 的 IO 口可以由软件配置成如下 8 种模式:
1、输入浮空
2、输入上拉
3、输入下拉
4、模拟输入
5、开漏输出
6、推挽输出
7、推挽式复用功能
8、开漏复用功能
【硬件干货】漏极开路?推挽输出?介绍GPIO的工作模式
STM32 的每个 IO 端口都有 7 组寄存器来控制。他们分别是:
1、两个配置模式的32 位的端口配置寄存器 CRL 和 CRH,控制着每个 IO 口的模式及输出速率;
3、两个 32 位的数据寄存器 IDR 和 ODR;
4、一个 32 位的置位/复位寄存器BSRR;
5、一个 16 位的复位寄存器 BRR;
6、一个 32 位的锁存寄存器 LCKR;这里我们仅介绍常用 的
几个寄存器,我们常用的 IO 端口寄存器只有 4 个:CRL、CRH、IDR、ODR。
一、模式配置寄存器CRL和CRH
该寄存器的复位值为 0X4444 4444,复位值其实就是配置端口为浮空输入模式。从上图还可以得出:STM32 的 CRL 控制着每组 IO 端口(A~G)的低 8 位的模式。每个 IO 端口的位占用 CRL 的 4 个位,高两位为 CNF,低两位为 MODE。这里我们可以记住几个常用的配置,比如 0X0 表示模拟输入模式(ADC 用)、0X3 表示推挽输出模式(做输出口用,50M 速率)、0X8 表示上/下拉输入模式(做输入口用)、0XB 表示复用输出(使用 IO 口的第二功能,50M 速率)。
CRH 的作用和 CRL 完全一样,只是 CRL 控制的是低 8 位输出口,而 CRH 控制的是高 8位输出口。这里我们对 CRH 就不做详细介绍了。
例:
GPIOC->CRH&=0XFFF00FFF;
GPIOC->CRH|=0X00038000;
GPIOC->ODR=1<<11;
二、端口输入数据寄存器(GPIOx_IDR) (x=A…E)
IDR 是一个端口输入数据寄存器,只用了低 16 位。该寄存器为只读寄存器,并且只能以16 位的形式读出。
三、端口输出数据寄存器(GPIOx_ODR) (x=A…E)
该寄存器为可读写,从该寄存器读出来的数据可以用于判断当前 IO 口的输出状态。而向该寄存器写数据,则可以控制某个 IO 口的输出电平。
四、端口位设置/清除寄存器(GPIOx_BSRR) (x=A…E)
该寄存器是对GPIOx_ODR寄存器的操作,我们之前举例时,都是用GPIOx_ODR去和一个16位数进行与运算和或运算,在进行运算时,需要求这个16位数,比较麻烦。不过可以移位法,将第一位置1,然后左移一定的位数(<<)。GPIOx_BSRR可以直接对GPIOx_ODR寄存器的某位进行设置。唯一不同的用GPIOx_BSRR操作GPIOx_ODR寄存器时,不用考虑GPIOx_ODR寄存器的不相关位。
![在这里插入图片描述](https://img-blog.csdnimg.cn/babed782c0d44360b2017cf634e7b6a2.png
GPIOx_BSRR也是32位寄存器,其中低16位是对GPIOx_ODR寄存器16个IO位置1,高16位是对GPIOx_ODR寄存器16个IO位置0。注意的是,如果GPIOx_BSRR的高16位和低16位都对某一IO口进行了配置,则以GPIOx_BSRR寄存器的低16位的配置为优先级。
五、端口位清除寄存器(GPIOx_BRR) (x=A…E)
GPIOx_BRR寄存器也是32位寄存器,但是高16位被保留,所以可以把它当做是16位寄存器。它的作用是将对应的0~15 IO口清零。即当对应位为1时,对应IO口置0,当对应位为0时,对应IO口保持原来的状态。
编程时,只需:GPIO(A~E)=1<<m,即可将PXm置0。
六、端口配置锁定寄存器(GPIOx_LCKR) (x=A…E)
当执行正确的写序列设置了位16(LCKK)时,该寄存器用来锁定端口位的配置。位[15:0]用于锁定GPIO端口的配置。
注意:锁住的是端口配置寄存器CRL或CRH
在规定的写入操作期间,不能改变LCKP[15:0]。当对相应的端口位执行了LOCK序列后,在下次系统复位之前将不能再更改端口位的配置。每个锁定位锁定控制寄存器(CRL, CRH)中相应的4个位。
具体叙述一下:
首先第16位,即高16位的第1位为LCKK,要开启锁IO模式,必须先“开锁”,开锁密码:写1——>写0——>写1——>读0——>读1。最后的读1可省略,但其它“密码”顺序、内容都不能错。
开锁程序:(GPIOB为例)
uint32_t t;
GPIOB->LCKR|=0x00010000;
GPIOB->LCKR&=0x0000ffff;
GPIOB->LCKR|=0x00010000;
t=GPIOB->LCKR;
t=GPIOB->LCKR;
然后就是给某IO口上锁了,需要注意的是,只有第16位——>LCKK为0时,GPIOx_LCKR寄存器才可以被写入,某位写入1,则对应的IO口被锁住。
以PB5为例:
GPIOB->LCKR&=0x0000ffff;
GPIOB->LCKR=1<<5;
在HAL库中有函数用于锁定GPIO
HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
__IO uint32_t tmp = GPIO_LCKR_LCKK;
assert_param(IS_GPIO_LOCK_INSTANCE(GPIOx));
assert_param(IS_GPIO_PIN(GPIO_Pin));
SET_BIT(tmp, GPIO_Pin);
GPIOx->LCKR = tmp;
GPIOx->LCKR = GPIO_Pin;
GPIOx->LCKR = tmp;
tmp = GPIOx->LCKR;
if ((uint32_t)(GPIOx->LCKR & GPIO_LCKR_LCKK))
{
return HAL_OK;
}
else
{
return HAL_ERROR;
}
}
配置好GPIO之后再调用这个函数可以看到
小灯依然会闪烁
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)