目录
1. GPIO相关寄存器
对于每个GPI/O端口的寄存器:(32位)
- 配置寄存器:GPIOx_CRL 和 GPIOx_CRH
- 数据寄存器:GPIOx_IDR 和 GPIOx_ODR
- 位设置/清除寄存器:GPIOx_BSRR
- 锁定寄存器:GPIOx_LCKR
- 位清除寄存器:GPIOx_BRR
GPIO端口的每个位可以由软件分别配置成多种模式,I/0端口寄存器必须按32位字被访问(不允许半字或字节访问,如下文提到16位访问,是因为编译环境会自动补齐到32位),关于几种模式在后文介绍
1.1 配置寄存器(CRL、CRH)
2个32位的配置寄存器分别为配置低寄存器(GPIOx_CRL) 和 配置高寄存器(GPIOx_CRH)
① 端口配置低寄存器(GPIOx_CRL) (x=A…E)
结合下图来说明,低位寄存器是用来配置GPIO0到GPIO7的,A~E共5组GPIO,相对应的可以知道高位寄存器则用来配置A ~ E组寄存器的GPIO8到GPIO15;可以发现,每一个GPIO引脚由4个比特位控制,其中第2位是MODE,用来配置该GPIO是输入还是输出模式,如果是输出,对应引脚输出的最大速度;其中的高2位是CNF,用来配置引脚输入/输出时的具体功能模式,不同应用需求对应不同的模式设置(后文解释)
② 端口配置高寄存器(GPIOx_CRH) (x=A…E)
同上面的低位配置寄存器一样,只不过高位配置寄存器是用来配置GPIO8~GPIO15的;要知道,一般配置一个GPIO的输入输出模式时,先配置MODE,确定引脚是用来输入还是输出,其次再配置CNF来设置具体的工作模式
1.2 数据寄存器(IDR、ODR)
2个32位的数据寄存器分别是输入数据寄存器(GPIOx_IDR) 和 输出数据寄存器(GPIOx_ODR)
① 输入数据寄存器(GPIOx_IDR) (x=A…E)
1、
输入数据寄存器是32位的,但是只用到0~15位,分别对应一组GPIO的16个引脚,仅可读;
2、
0~15位组成一“字”,名为IDR,读的时候只能以字的形式读取,即一次读取16位的比特位;
② 输出数据寄存器(GPIOx_ODR) (x=A…E)
1、
输出数据寄存器也是32位,只用到0~15位,分别对应一组GPIO的16个引脚,可读写;
2、
读写寄存器时也只能以字的形式操作
1.3 位设置/清除寄存器(BSRR)
这是一个32位的寄存器,低16位(BS)用来设置端口的位,高16位(BR)则是用来清除端口的位;两者均仅可写,写操作时需以字的形式写入
如对于置位GPIO15时,令BS15为1表示置位,此时BR15就不能设为1了,如果BS为1时BR也为1,则默认BS生效
1.4 锁定寄存器(LCKR)
锁定寄存器(GPIOx_LCKR) (x=A…E)是一个32位的寄存器,当设置了位16(LCKK)时,则会锁定端口位的配置,位[15:0]对应的GPIO的16个引脚,当对相应的端口位执行了LOCK后,在下次系统复位之前将不能再更改端口位的配置
每个锁定位锁定控制寄存器(CRL, CRH)中相应的4个位,需要注意锁键的输入序列,顺序不要搞错,并且位[15:0]只能在LCKK为0时才可写
1.5 位清除寄存器(BRR)
位清除寄存器(GPIOx_BRR) (x=A…E) 的高16位保留,不使用;低16位以字的形式进行写入,写入1时才会对位有影响
2. ODR, BSRR, BRR控制位的区别
- 三者均为32位寄存器,均可写,需以字形式写
- ODR[0,15]对应位写1,输出高电平,0对应低电平
- BSRR[16,31]对应位写1输出低电平,0无效
BSRR[0,15]对应位写1输出高电平,0无效 - BRR[0,15]对应位写1输出低电平,写0无效(仅低电平)
1、
BRR和BSRR的最显著用处就是可以只改变某一个或某几个针脚的值而不改变其他(因为0无效)
2、
ODR改变时则是改变全部位的状态(仅可以字形式写)
//对于ODR操作GPIO的伪代码如下:
disable_irq() //关闭中断
save_gpio_pin_sate = read_gpio_pin_state();
save_gpio_pin_sate = xxxx;
chang_gpio_pin_state(save_gpio_pin_sate);
enable_irq();
可见当控制GPIO的状态时最好不要使用ODR,关闭中断明显会延迟或丢失一事件的捕获
3、
BSRR的高16位和BRR的低16位具有相同功能,举例:
对GPIOE的16个IO,改变低8位的数据而保持高8位不变
① GPIOE->BSRR = (0x34) & 0xff; //操作BSRR[0,15]
② GPIOE->BRR = ~(0x34) & 0xff;
一次完成对8位的操作:
GPIOE->BSRR = ((0x34) & 0xff) | ( (~(0x34) & 0xff)<<16 );
一次完成对16位的操作:
GPIOE->BSRR = ((0x34)& 0xffff) | ( (~(0x34))<<16 );
BSRR的高16位并非是多余的,对GPIOE的位7置’1’,位6置’0’:
GPIOE->BSRR = 0x400080;
不使用BSRR高16位,要分2次操作,造成位7和位6的变化不同步
GPIOE->BSRR = 0x80;
GPIOE->BRR = 0x40;
4、
有些IO时序要求非常严格,同时对一个GPIO置1和对另一个GPIO清0是很必要的
5、
BSRR还有一个特点,就是Set比Reset的级别高
3. GPIO口的几种模式总结
3.1 常见名词解释
内置外设:如串口、ADC、DCA等等(属于stm32内部功能模块)
端口复用:当一个GPIO作为内置外设的功能引脚时,称为复用。比如说,STM32的串口1的引脚对应的I/O位PA9、PA10。而PA9、PA10默认的功能都是GPIO,所以说当PA9、PA10引脚作为串口1使用的时候就是端口复用
端口重映射:把引脚的内置外设功能映射到其他的引脚上,但不是可以随便映射的,需要参照数据手册
推挽结构:两个参数相同的三极管或MOS管分别受两互补信号的控制,总是在一个三极管或MOS管导通的时候另一个截止。高低电平由输出电平决定。有推有拉,任何时候IO口的电平都是确定的,不需要外接上拉或者下拉电阻
开漏输出:只可以输出强低电平,高电平得靠外部电阻拉高。输出端相当于三极管的集电极。适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内);
GPIO内部电路结构:
FT:代表GPIO口兼容3.3V和5V
保护二极管:IO引脚上下两边两个二极管用于防止引脚外部过高、过低的电压输入
P-MOS、N-MOS管:由P-MOS管和N-MOS管组成的单元电路使得GPIO具有“推挽输出”和“开漏输出”的模式
TTL肖特基触发器:信号经过触发器后,模拟信号转化为0和1的数字信号
GPIO支持4种输入模式,三种最大翻转速度(2MHz、10MHz、50MHz)
3.2 四种输入模式
① 浮空输入(GPIO_Mode_IN_FLOATING)
逻辑器件与引脚即不接高电平,也不接低电平,相当于浮在空中呈高阻态,上面用绳子一拉就上去了,下面用绳子一拉就沉下去了,一般用来做ADC输入用,这样可以减少上下拉电阻对结果的影响
② 输入上拉(GPIO_Mode_IPU)
上拉就是通过上拉电阻把电位拉高,比如拉到Vcc,将输入的不确定的信号嵌位在高电平
③ 输入下拉(GPIO_Mode_IPD)
下拉就是把电压拉低,拉到GND,下拉电阻另一端接地即可,原理与上拉的一样
④ 模拟输入(GPIO_Mode_AIN)
模拟输入是指0,1的二进制数字信号,通过数模转换,转换成模拟信号,模拟输入模式下,I/O端口的模拟信号(电压信号,而非电平信号&