看到这个标题你是不是想问为什么要麻烦的使用寄存器来设置引脚的输入输出呢?使用库函数多方便。
因为比如当我们在使用IIC通讯的时候,IIC通讯速率400KHz,需要特别快的通讯速率,用库函数来设置引脚的话很不方便,所以当我们被要求速度快的情况下,最好的办法就是直接操作寄存器。
那该怎么配置寄存器呢?接下来我们通过STM32L031F4P6单片机举例子来看看怎么配置
我们首先找到芯片的参考手册,找到关于GPIO端口模式寄存器(MODER)
这是一个32位的单片机,所以它的寄存器也是32位,通过看图咱们可以知道它有32个位,其中每两位为一组,就是有16组,16组就对应IO口的16个引脚,例如PA口的16个引脚,PB口的16个引脚
Bit1:0就控制PA0、PB0、PC0、PD0;Bit3:2就控制PA1、PB1、PC1、PD1;以此类推
现在我们需要设置PA6引脚,所以我们要修改Bit13:12这两个位,这两个位不是0就是1,搭配起来的话就是有四种状态
00:输入模式
01:通用输出模式
10:复用功能
11:模拟输入模式
现在我们需要用到输入模式和输出模式,也就是将Bit13:12这两个位设置为00和01,通过下面代码我们就可以很轻松的通过配置寄存器设置了PA6引脚的输入输出了
void MPU_SDA_OUT() // PA6 输出模式
{
GPIOA->MODER |= (0x1<<12); // 给bit13:12写01
}
void MPU_SDA_IN() // 输入模式
{
GPIOA->MODER &= ~(0x3<<12); // 给bit13:12写00
}
下面我再解释一下这个位运算:
首先我们要知道逻辑运算符(!,&&,||)和位运算符(<<,>>,~,|,^,&)的区别:
我们对寄存器的操作使用的是位运算符,而逻辑运算符一般用于在程序中判断逻辑中使用。
输出模式:将寄存器MODER的第13位清“0”12位置“1” MODER |= (0x1<<12);
(将0X1左移12位,使用位运算"|" )
输入模式:将寄存器MODER的第13位清“0”12位清“0” MODER &= ~(0x3<<12);
(将0X3左移12位,取反,使用位运算"&" )
总结一下:
将某位置1,移位后使用位运算"|" ;
将某位清0,移位取反后,使用位运算"&"