任何一个单片机, 最简单的外设莫过于 IO 口的高低电平控制了,本章将通过一个经典的
跑马灯程序,带大家开启 STM32F1 之旅, 通过本章的学习, 你将了解到 STM32F1 的 IO 口作为输出使用的方法。
STM32 的 IO 口可以由软件配置成如下 8 种模式:
1、 输入浮空
2、 输入上拉
3、 输入下拉
4、 模拟输入
5、 开漏输出
6、 推挽输出
7、 推挽式复用功能
8、 开漏复用功能
STM32 的每个 IO 端口都有 7 个寄存器来控制。他们分别是:配置模式的 2 个 32 位的端口
配置寄存器 CRL 和 CRH; 2 个 32 位的数据寄存器 IDR 和 ODR; 1 个 32 位的置位/复位寄存器
BSRR;一个 16 位的复位寄存器 BRR; 1 个 32 位的锁存寄存器 LCKR;这里我们仅介绍常用 的
几个寄存器,我们常用的 IO 端口寄存器只有 4 个: CRL、 CRH、 IDR、 ODR。CRL 和 CRH 控制着每个 IO 口的模式及输出速率。
该寄存器的复位值为 0X4444 4444,从图 6.1.1 可以看到,复位值其实就是配置端口为浮空
输入模式。从上图还可以得出: 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 就不做详细介绍了。
接下来我们讲解怎么在库函数初始化 GPIO 的配置。 GPIO 相关的函数和定义分布在 HAL库文件 stm32f1xx_hal_gpio.c 和头文件 stm32f1xx_hal_gpio.h 文件中。
在 HAL 库开发中, 初始化 GPIO 是通过 GPIO 初始化函数完成:
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
这个函数有两个参数,第一个参数是用来指定需要初始化的 GPIO 对应的 GPIO 组,取值范围
为 GPIOA~GPIOE。第二个参数为初始化参数结构体指针,结构体类型为 GPIO_InitTypeDef。
下面我们看看这个结构体的定义。
typedef struct
{
uint32_t Pin;
uint32_t Mode;
uint32_t Pull;
uint32_t Speed;
}GPIO_InitTypeDef;
下面我们通过一个 GPIO 初始化实例来讲解这个结构体的成员变量的含义。通过初始化结构体初始化 GPIO 的常用格式是:
GPIO_Initure.Pin=GPIO_PIN_9|GPIO_PIN_10; //PF9,10
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed= GPIO_SPEED_FREQ_HIGH; //高速
HAL_GPIO_Init(GPIOF,&GPIO_Initure);
上面代码的意思是设置 GPIOF 的第 9 和 10 端口为推挽输出模式,同时速度为 50M,上拉。
ODR 是一个端口输出数据寄存器,也只用了低 16 位。该寄存器为可读写,从该寄存器读
出来的数据可以用于判断当前 IO 口的输出状态。而向该寄存器写数据,则可以控制某个 IO 口
的输出电平。该寄存器的各位描述如图 6.1.3 所示:
在 HAL 库 中 设 置 ODR 寄 存 器 的 值 来 控 制 IO 口 的 输 出 状 态 是 通 过 函 数
HAL_GPIO_WritePin 来实现的:
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,GPIO_PinState PinState)
使用实例如下:
HAL_GPIO_WritePin(GPIOF,GPIO_PIN_9,GPIO_PIN_SET);
IDR 是一个端口输入数据寄存器,只用了低 16 位。该寄存器为只读寄存器,并且只能以
16 位的形式读出。该寄存器各位的描述如图 6.1.2 所示:
要想知道某个 IO 口的状态, 你只要读这个寄存器,再看某个位的状态就可以了。使用起
来是比较简单的。 库函数相关函数为:
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
函数是用来读取一组 IO 口的一个输入电平。比如我们要读取 GPIOF.5 的输入电平,方法
为:
HAL_GPIO_ReadPin (GPIOF, GPIO_Pin_5);
1、打开CubeMX软件,如图任选一个即可。
2、出现这种情况直接点击“cancle”即可
3、根据你自己需要的芯片型号,输入关键字,如:“103c8”,那么你选的就是stm32f03c8t6
4、接下来会弹出以下页面,该页面分为三个区域,以序号说明进行理解便可
5、我们只需在图块3中把你硬件连接led灯的引脚,单击选择设置为“GPIO_OUPT”即可(这里我选择PA9为例子,进行演示)
6、配置RCC使用外部时钟源
7、接下来进行时钟设置
8、设置完mcu各个配置之后,进行工程文件的保存
9、完成工程创建
10、对应找到你保存工程的位置
void main()
{
while(1)
{
HAL_GPIO_WritePin(GPIOA,LED1_Pin ,GPIO_PIN_SET);//对GPIOA的LED1引脚设置为高电平
HAL_Delay (500);//延时500ms
HAL_GPIO_WritePin(GPIOA,LED1_Pin ,GPIO_PIN_RESET);//对GPIOA的LED1引脚设置为低电平
HAL_Delay (500);
}
}