STM32 IO输入实验
实验内容
- 使用Keil 5编写程序,要求在LED模块上按下相应按键后,按键对应的LED状态翻转。总共有四个按键:S1、S2、S3和S4,分别对应LED1、LED2、LED3和LED4。
实验目的
- 了解按键的工作原理
- 掌握STM32上的IO口作为输入端口的配置方法
- 加深对编程思想理解
实验环境
实验所需硬件
序号 | 名称 | 数量 | 备注 |
---|---|---|---|
1 | 电脑 | 1台 | 系统Windows7及以上 |
2 | STM32底座模块 | 1个 | · |
3 | LED模块 | 1个 | · |
4 | ST-Link下载器 | 1个 | · |
5 | ST-Link下载器连接线 | 1根 | · |
6 | 配套按键实验代码 | 1份 | · |
实验所需软件
ST-Link下载器 & ST-Link下载器连接线
STM32底座:HIVE PRO STM32是一种基于STM32F103C8T6芯片的蜂巢底座。
LED模块:LED模块共有四个按键,4个LED灯,可供完成流水灯、按键处理等相关实验。按键的触发为低电平,LED灯低电平点亮。
实验要求
- 掌握STM32中通用IO作为输入口的配置方法。
- 掌握按键编程的方法,能够编程读取按键的状态,并根据按键动作编程实现相关模块的控制。
实验原理
STM32的IO口作为输出在上一节IO口输出实验已经有了比较详细的介绍。这一节介绍STM32的IO口作为输入使用。本节是通过调用函数HAL_GPIO_ReadPin()来读取IO口的输入状态。了解了这点,就可以开始硬件设计和软件设计。
硬件设计
实验用到的硬件模块及原理图如下面图所示。本实验用到的是S1、S2、S3、S4按键,以及LED1、LED2、LED3、LED4。通过按键及LED的组合我们实现以下功能:按下S1灯LED1亮,再次按下熄灭;按下S2灯LED2亮,再次按下熄灭;按下S3灯LED3亮,再次按下熄灭;按下S4灯LED4亮,再次按下熄灭。
实验步骤
0
① LED模块安装于STM32底座上。ST-Link连接底座与计算机,如下图:
② 访问github,进入github界面后点击Code,Clone HTTPS安全链接,如下图所示:
③ 打开电脑终端,进入工作目录workspace (workspace 为工程文件夹所在目录):
cd workspace
④ 运行clone
命令:
git clone https://github.com/aiotcom/eps.git
下载目录至指定文件夹下。
如果提示“command not found”表示电脑没有安装Git,请至Git官网下载。
如果电脑没有安装 Git 软件,也可以进入Github,点击 Code
-> DownLoad ZIP
下载所有工程代码。如下图所示:
如果电脑没有公网,可以进入D:\实验教程与代码 选择相应的代码。
⑤ 打开 Keil 5 工程软件,点击工具栏: ` Project ->
Open Project,选择工程文件:
STM32基础实验\2.IO输入实验\USER\KEY.uvprojx` 并打开。
如果没有安装该软件,请至Keil官网下载。
⑥ 工程启动后,点击 Rebuild
重新编译。如下图:
⑦ 编译成功,如下图:
⑧ 点击 Download
按钮下载程序,如下图所示:
⑨ 下载完成后,将USB线进行重连操作(即:将STLink的USB线从底座上取下,再重新接上)。
⑩ 观察操作实验:
按下按键S1,LED1被点亮,再次按下按键S1,LED1熄灭;
按下按键S2,LED2被点亮,再次按下按键S2,LED2熄灭;
按下按键S3,LED3被点亮,再次按下按键S3,LED3熄灭;
按下按键S4,LED4被点亮,再次按下按键S4,LED4熄灭。
代码讲解
① 程序目录结构,如下图。CORE
文件夹为STM32内核代码,HALLIB
文件文件夹为底层HAL库文件,我们主要关心,main.c
及HARDWARE
中的代码。
② main.c中进行硬件的初始化及整个代码的逻辑控制。
int main(void)
{
static uint8_t key = 0;
HAL_Init();//初始化HAL库,为随后用到的HAL_Delay()函数提供时钟。
LED_Init();//初始化LED灯控制的IO口
KEY_Init();//初始化按键输入的IO口
while(1)
{
key = KEY_Scan();//获取按键
switch(key)
{
case S1_PRES:
HAL_GPIO_TogglePin(LED_PORT,LED1_PIN);//S1 按下,翻转LED1灯状态
break;
case S2_PRES:
HAL_GPIO_TogglePin(LED_PORT,LED2_PIN);//S2 按下,翻转LED2灯状态
break;
case S3_PRES:
HAL_GPIO_TogglePin(LED_PORT,LED3_PIN);//S3 按下,翻转LED3灯状态
break;
case S4_PRES:
HAL_GPIO_TogglePin(LED_PORT,LED4_PIN);//S4 按下,翻转LED4灯状态
break;
default:break;
}
}
}
③ LED.c为LED驱动代码,代码实现对LED灯控制的IO进行初始化设置IO口为推挽上拉模式,重点不要忘记使用能IO接口的时钟及设置输出的速度。
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_Initure;
LED_IO_RCC();
GPIO_Initure.Pin = LED1_PIN|LED2_PIN|LED3_PIN|LED4_PIN;
GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP;//推挽输出
GPIO_Initure.Pull = GPIO_PULLUP;//上拉
GPIO_Initure.Speed = GPIO_SPEED_HIGH;//高速
HAL_GPIO_Init(LED_PORT,&GPIO_Initure);
LED_OFF();//初始化完成全部LED灯灭
}
④ key.c为LED模块上的按键驱动,Key_Init()中代码中设置IO口为上拉输入。
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_Initure;
KEY_IO_RCC();//使用IO端口时钟
GPIO_Initure.Pin = S1_PIN|S2_PIN;
GPIO_Initure.Mode = GPIO_MODE_INPUT;//输入
GPIO_Initure.Pull = GPIO_PULLUP;//上拉
GPIO_Initure.Speed = GPIO_SPEED_LOW;//低速
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
GPIO_Initure.Pin = S3_PIN|S4_PIN;
GPIO_Initure.Mode = GPIO_MODE_INPUT;//输入
GPIO_Initure.Pull = GPIO_PULLUP;//上拉
GPIO_Initure.Speed = GPIO_SPEED_LOW;//低速
HAL_GPIO_Init(GPIOB,&GPIO_Initure);
}
⑤ 按键扫描代码。
uint8_t KEY_Scan(void)
{
static uint8_t key_up=1;//按键松开标志
/*在按键松开的情况,有按键按下*/
if(key_up&&(S1_Read()==0||S2_Read()==0||S3_Read()==0||S4_Read()==0)){
HAL_Delay(10);//如果有按键按下延时10个毫秒消抖。
key_up=0;//按键己按下
if(S1_Read()==0){
return S1_PRES;//返回 S1 按下
}
else if(S2_Read()==0){
return S2_PRES;//返回 S2 按下
}
else if(S3_Read()==0){
return S3_PRES;//返回 S3 按下
}
else if(S4_Read()==0){
return S4_PRES;//返回 S4 按下
}
}
else if(S1_Read()==1&&S2_Read()==1&&S3_Read()==1&&S4_Read()==1){
/*按键全部松开了*/
key_up=1;
}
return 0;//无按键按下
}
常见问题
-
弹出警告窗口,不能下载程序。
- 请确认STLink驱动、STM32F103C8的DFP包是否安装。
- STLink仿真器是否正常接入。
-
下载代码后程序没观察到实验现象。
- 请重新上电,或者按下底座上的复位按键。
- 模块没有安装稳妥。
-
按键按下后无反应。
- 手指的发力点要在按键表面上。
实验思考
-
实现按键S1按下后,LED1亮1秒后熄灭。
-
实现按键S1按下后,LED1常亮,按键S2按键下LED1熄灭。