1. 什么是GPIO?(了解)



2. STM32 GPIO简介
2.1. GPIO特点


2.2. GPIO电气特性

2.3. GPIO引脚分布图


IO引脚分布特点:按组存在、组数视芯片而定、每组最多16个IO引脚。
3. IO端口基本结构介绍






4. GPIO八种工作模式

4.1. 输入浮空


特点:空闲时(高阻态),IO状态不确定,由外部环境决定。
4.2. 输入上拉


特点:空闲时(高阻态),IO呈现高电平。
4.3. 输入下拉


特点:空闲时(高阻态),IO呈现低电平。
4.4. 模拟功能


特点:专门用于模拟信号输入或输出,如ADC和DAC
4.5. 开漏输出


特点:不能输出高电平,必须有外部(或内部)上拉才能输出高电平。
4.6. 开漏式复用功能


特点:不能输出高电平,必须有外部(或内部)上拉才能输出高电平。由其他外部控制输出。
4.7. 推挽输出


特点:可输出高低电平,驱动能力强。
4.8. 推挽式复用功能


特点:可输出高低电平,驱动能力强,由其他外设控制输出。

5. GPIO寄存器

5.1. 端口配置寄存器(GPIOx_CRL和GPIOx_CRH)(x=A..E)
这两个寄存器都是GPIO口配置寄存器,不过CRL控制端口的低8位(GPIOx_0~7) ,CRH控制端口的高8位(GPIOx_8~15) 。寄存器的作用是控制GPIO的工作模式 和工作速度。


STM32F103为例,每组GPIO下有16个IO口,一个寄存器共32位,每4个位控制1个IO口,所以才需要俩个寄存器完成。我们看看这个寄存器的复位值,然后用复位值举例说明一下这样的配置值代表什么意思。比如 GPIOA_CRL 的复位值是 0x44444444,4 位为一个单位都是 0100,以寄存器低四位说明一下,首先位 1:0 为 00 即是设置为 PA0 为输入模式,位 3:2 为 01 即设置为浮空输入模式。所以假如 GPIOA_CRL 的值是 0x44444444,那么 PA0~PA7 都是设置为输入模式,而且是浮空输入模式。
上面这 2 个配置寄存器就是用来配置 GPIO 的相关工作模式和工作速度,它们通过不同的配置组合方法,就决定我们所说的 8 种工作模式。下面,我们来列表阐述,如表 13.1.3.1。

5.2. 端口输出数据寄存器(GPIOx_ODR)(x=A..E)
该寄存器用于控制GPIOx的输出高低电平。该寄存器32位,低16位为数据有效位,高16位为保留位。

该寄存器低 16 位有效,分别对应每一组 GPIO 的 16 个引脚。当 CPU 写访问该寄存器,如果对应的某位写 0(ODRy=0),则表示设置该 IO 口输出的是低电平,如果写 1(ODRy=1),则表示设置该 IO 口输出的是高电平,y=0~15。
此外,除了 ODR 寄存器,还有一个寄存器也是用于控制 GPIO 输出的,它就是 BSRR 寄存器。
5.3. 端口输入数据寄存器(GPIOx_IDR)(x=A..E)
该寄存器可以读出GPIOx的端口的引脚状态。

5.4. 端口置位/复位寄存器(GPIOx_BSRR)(x=A..E)
该寄存器用于控制GPIOx的输出高低电平。该寄存器位32位,高16位为清除位,低16位为设置位。

5.5. 端口位设置/清除寄存器(GPIOx_BRR)(x=A..E)
该寄存器用于清除GPIOx组的位,高16位用于保留,低16位用来清除0~15口。


5.6. ODR和BSRR寄存器控制输出有什么区别?
使用ODR,在读和修改访问之间产生中断时,可能会发生风险,BSRR则无风险。

总的来说,建议大家使用BSRR寄存器控制输出。
6. 通用外设驱动模型(四步法)




7. GPIO配置步骤






8. 点亮一个LED灯(成为点灯大师的第一步)



分析IO应该设置为什么模式?**推挽输出。**开漏输出需要接外部或内部上拉电阻。




HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET);
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_SET);
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_RESET);
HAL_Delay(500);
9. 按键控制控制LED

如何消除抖动波形?
两种方法:软件消抖,通过延时跳过抖动的时间段,在判断IO输入电平。
硬件消抖,通过电路设计去除抖动波形,比如RS触发器、电容滤波。
按键原理图(精英板)

有三个按键,PA0、PE4、PE3。
分析IO应该设置为什么模式?
KEY_UP(PA0):接VCC,按下时为高电平,不按下为低电平。所以要设置为下拉输入,默认低电平。
KEY0(PE4):接GND,按下时为低电平,不按下为高电平。所以要设置为上拉输入,默认高电平。
KEY1(PE3):接GND,按下时为低电平,不按下为高电平。所以要设置为上拉输入,默认高电平。
int main(void)
{
HAL_Init();
sys_stm32_clock_init(RCC_PLL_MUL9);
delay_init(72);
led_init();
key_init();
while(1)
{
int ret=key_scan();
if(ret==1)
{
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);
}
}
}
void key_init(void)
{
GPIO_InitTypeDef key_init_struct;
__HAL_RCC_GPIOE_CLK_ENABLE(); /* IO口PE时钟使能 */
key_init_struct.Pin = GPIO_PIN_3; /* KEY0引脚 */
key_init_struct.Mode = GPIO_MODE_INPUT; /* 输入模式 */
key_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
key_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
HAL_GPIO_Init(GPIOE, &key_init_struct) ; /* 初始化KEY0引脚 */
}
uint8_t key_scan(void)
{
if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==0)
{
delay_ms(10); //消抖
if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==0) //读取按键返回值
{
while(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3)==0); //等待按键松开
return 1; //按键按下时返回1,没有返回0
}
}
return 0;
}