1、GPIO分组
大组有七组GPIOA~GPIOG,每一个大组有16个管脚,分别是GPIOx0~GPIOx15。
2、GPIO的内部框图
- 每一个IO管脚内部都有控制器,如上图所示。
- 普通输出高低电平是通过操作“输出数据寄存器”来实现的。
- 输出类型:推挽输出、开漏输出。不管哪一种输出,目的只有一个:向芯片外部输出高低电平。
- 推挽输出:P-MOS和N-MOS交替工作。当P-MOS导通,N-MOS截止时,向芯片外部输出高电平,高电平来自于VDD;当P-MOS截至,N-MOS导通时,向芯片外部输出低电平,低电平来自于VSS。
- 开漏输出:P-MOS永远截至,NMOS管可导通可截至。当P-MOS截至,N-MOS导通时,向芯片外部输出低电平,低电平来自于VSS。开漏输出要输出高电平,需要挂载上拉电阻,高电平来自于上拉电阻的VDD。
- 开漏输出高电平需要挂载 上拉电阻,上下电阻可以用芯片内部的,也可以在芯片外部挂
- 如果要求的驱动功能力不高,可以用推挽输出。如下情景,则选用开漏输出:①如果要求的驱动电流要比较大,选用开漏输出,开漏输出可以通过调节上拉电阻的阻值和VDD的电平值实现驱动电流的调节;②需用改变高电平的电平值时,可以用开漏输出。
3、GPIO输出相关寄存器
3.1、RCC AHB1 外设时钟使能寄存器 (RCC_AHB1ENR)
作用:使能GPIO口的时钟。
在配置GPIO的相关寄存器之前,必须先使能GPIO的时钟。
举例:如果配置GPIOA的MODER/OTYPER/ODER寄存器之前,必须将RCC->AHB1ENR寄存器的位0置1。
3.2、GPIO 端口模式寄存器 (GPIOx_MODER)
该寄存器的作用是配置GPIO的工作模式。
- 每一组GPIO口都要有个MODER寄存器。
- MODER寄存器是32位有效,每一位都可读可写。
- MODER寄存器每两位为一个小组,总共16个小组,分别是MODER0~MODER15。
- MODER寄存器与GPIO口的对应关系:GPIOx0~GPIOx15与MODER0~MODER15一一对应。(x:A~G)。
- 两位有四种情况,具体如下:
举例:
GPIOA3配置输出模式,需要配置GPIOA->MODER寄存器中的MODER3,即位7:6,配置为01。
对应的代码:GPIOA->MODER |=(1<<6);
3.3、GPIO 端口输出类型寄存器 (GPIOx_OTYPER)
作用:配置GPIO口的输出类型:推挽?开漏?
- 每一组GPIO口都要有1个OTYPER寄存器。
- OTYPER寄存器是低16位有效,低16位每一位都可读可写。
- OTYPER寄存器1位为一个小组,总共16个小组,分别是OT0~OT15。
- OTYPER寄存器与GPIO口的对应关系:GPIOx0~GPIOx15与OT0~OT15,一一对应。(x:A~G)。
- 1位有两种情况,具体如下:
举例:GPIOD8配置“输出推挽”,需要将GPIOD->OTYPER寄存器中的OT8清0,即需要将位8清零。
对应的代码:GPIOD->OTYPER &=~(1<<8);
举例:GPIOE6配置“输出开漏”,需要将GPIOE->OTYPER寄存器中的OT6置一,即需要将位6置一。
对应的代码:GPIOE->OTYPER |=(1<<6);
3.4、GPIO 端口输出数据寄存器 (GPIOx_ODR)
作用:用于控制GPIO口,向芯片外部输出高低电平
- 每一组GPIO口都要有1个ODR寄存器。
- ODR寄存器是低16位有效,低16位每一位都可读可写。
- ODR寄存器1位为一个小组,总共16个小组,分别是ODR0~ODR15。
- ODR寄存器与GPIO口的对应关系:GPIOx0~GPIOx15与ODR0~ODR15,一一对应。(x:A~G)。
- 1位有两种情况,具体如下:
0 : 相应的管脚输出低电平 |
1:相应的管脚输出高电平 |
举例:GPIOD7输出高电平,需要将GPIOD->ODR的ODR7置1,即位7置1。对应的代码:GPIOD->ODR |=(1<<7);
举例:GPIOC9输出低电平,需要将GPIOC->ODR的ODR9,即位9清零。对应的代码:GPIOC->ODR&=~(1<<9);
3.5、GPIO 端口输出速度寄存器 (GPIOx_OSPEEDR)
该寄存器的作用是配置GPIO的输出速度。
- 每一组GPIO口都要有个OSPEEDR寄存器。
- OSPEEDR寄存器是32位有效,每一位都可读可写。
- OSPEEDR寄存器每两位为一个小组,总共16个小组,分别是MODER0~MODER15。
- MODER寄存器与GPIO口的对应关系:GPIOx0~GPIOx15与OSPEEDR0~OSPEEDR15一一对应。(x:A~G)。
- 两位控制一个IO口,两位有四种情况,具体如下:
举例:GPIOA7的输出速度配置为25MHZ,需要配置GPIOA->OSPEEDR寄存器的OSPEEDR7,即位15:14,配置为01,对应的代码GPIOA->OSPEEDR |=1<<14.
举例:GPIOG9的输出速度配置为50MHZ,需要配置GPIOG->OSPEEDR寄存器的OSPEEDR9,即位19:18,配置为10,对应的代码GPIOG->OSPEEDR |= 2<<18.
3.6、GPIO 端口置位/复位寄存器 (GPIOx_BSRR)
作用:用于控制ODR寄存器来实现间接的向芯片外部输出高低电平
- 每一组GPIO口都要有1个BSRR寄存器。
- BSRR寄存器是32有效,每一位都可读可写。
- BR15~BR0 (bit reset 位清零)是用于间接控制ODR寄存器的ODR15~ODR0来向芯片外部输出低电平。
- BS15~BS0 (bit set 置位)是用于间接控制ODR寄存器的ODR15~ODR0来向芯片外部输出高电平。
- STM32F407底层将BSRR分BSRRH(高16位)和BSRRL(低16位)。
- 置一则有效,清零则无效,如下所示:
0:不会对相应的 ODRx 位执行任何操作
1:对相应的 ODRx 位进行置位/复位
举例:GPIOA8输出低电平,方法有两种:①GPIOA->ODR &=~(1<<8); ②GPIOA->BSRRH = 1<<8;
3.7、GPIO 端口上拉/下拉寄存器 (GPIOx_PUPDR)
该寄存器的作用是配置上下拉模式。
- 每一组GPIO口都要有个PUPDR寄存器。
- PUPDR寄存器是32位有效,每一位都可读可写。
- PUPDR寄存器每两位为一个小组,总共16个小组,分别是PUPDR0~PUPDR15。
- PUPDR寄存器与GPIO口的对应关系:GPIOx0~GPIOx15与PUPDR0~PUPDR15一一对应。(x:A~G)。
- 两位有四种情况,具体如下:
举例:GPIOF9配置为为上拉模式,需要配置GPIOF->PUPDR寄存器的PUPDR9,即位19:18,配置为01,
对应的代码:GPIOF->PUPDR |= 1<<18。
提问:GPIOE14配置为为下拉模式,需要配置GPIOE->PUPDR寄存器的PUPDR14,即位29:28,配置为10,
对应的代码:GPIOE->PUPDR |= 2<<28。
3.8、GPIO 端口输入数据寄存器 (GPIOx_IDR)
作用:用于保存芯片外部输入的高低电平
- 每一组GPIO口都要有1个IDR寄存器。
- IDR寄存器是低16位有效,低16位每一位只可读。
- IDR寄存器1位为一个小组,总共16个小组,分别是IDR0~IDR15。
- IDR寄存器与GPIO口的对应关系:GPIOx0~GPIOx15与IDR0~IDR15,一一对应。(x:A~G)。
- 1位有两种情况,具体如下:
0 : 相应的管脚输入低电平 |
1:相应的管脚输入高电平 |
举例:获知GPIOA3的输入电平,对应的代码如下:
if(GPIOA->IDR&(1<<3)){
//表明GPIOA3输入高电平
}else{
//表明GPIOA3输入低电平
}
3.9、GPIO 复用功能高位寄存器 (GPIOx_AFRH)
- 作用:选择第几复用功能
- 复用功能寄存器分为:高、低两个寄存器,这两个寄存器都是32位有效,每一位都可读可写
- 复用功能寄存器4位为1小组,分别是AFL0~AFL7、AFH8~AFH15
- AFL0~AFL7 是和GPIOx0~GPIOx7一一对应,AFH8~AFH15和GPIOx8~GPIOx15一一对应。
- 4位为1小组,四位有16种情况:
举例:
假设PA9的选择为复用功能7,即AF7,对应的代码如下:GPIOA->AFRH |= 7<<4 ;
PA10的选择为复用功能7,即AF7,对应的代码如下:GPIOA->AFRH |= 7<<8;
注意:STM32底层没有AFRH和AFRL寄存器,底层是封装成一个数组AFR[2],ARF[0]代表AFRL寄存器,AFR[1]代码AFRH寄存器
所以上面的代码应该写成:GPIOA->AFR[1] |= 7<<4 ; GPIOA->AFR[1] |= 7<<8 ;