STM32小实验四--按键控制LED灯
1.实验目的
按下 KEY1,翻转 LED1 状态;按下 KEY2 ,翻转 LED2 状态。
2.硬件清单
- STM32
- ST-Link
3.原理图
4.代码
在Drivers/BSP新建文件夹命名为key在这个文件夹中新建key.c和key.h。
4.1key.c
#include "key.h"
#include "sys.h"
#include "delay.h"
//初始化GPIO口
void key_init(void)
{GPIO_InitTypeDef gpio_initstruct;//打开时钟__HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA时钟//初始化GPIO函数gpio_initstruct.Mode = GPIO_MODE_INPUT; //输入模式gpio_initstruct.Pin = GPIO_PIN_0 | GPIO_PIN_1; //两个按键的引脚gpio_initstruct.Pull = GPIO_PULLUP; //上拉gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH; //高速HAL_GPIO_Init(GPIOA, &gpio_initstruct);
}//按键扫描函数
uint8_t key_scan(void)
{//检测按键1是否按下if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET ){//消抖delay_ms(10);//再次判断按键1是否按下if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET ){//如果确实是按下的状态,等待按键松开while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET){}//返回按键的值return 1;}}//检测按键2是否按下if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET ){//消抖delay_ms(10);//再次判断按键2是否按下if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET ){//如果确实是按下的状态,等待按键松开while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET){}//返回按键的值return 2;}}//如果前面情况都不是返回默认值return 0;}
初始化GPIO和之前一样,但是模式改为输入模式(gpio_initstruct.Mode = GPIO_MODE_INPUT),gpio_initstruct.Pull = GPIO_PULLUP,这个模式是根据原理图,按键未被按下时的状态是什么,这个就是什么,因为如果按下是上拉,那么初始化时就要设置为下拉。
按键扫描函数编写的步骤:
1.检测按键是否被按下
使用HAL_GPIO_ReadPin库函数读取电平,根据原理图当按下按钮时为低电平,所以使用if语句判断HAL_GPIO_ReadPin是否等于GPIO_PIN_RESET也就是低电平。
2.消抖
就是直接延时10ms。
3.再次判断按键是否被按下
和第一次检测按键是否被按下一样。
4.如果确实是按下的状态,等待按键松开
等待按键松开的方法是使用while循环如果按键没有松开(为低电平)就一直在while循环里,如果按键松开(为高电平)就跳出while循环。
5.返回按键的值
然后使用return返回数值
6.如果前面情况都不是返回默认值
如果没有按下按键就return 0。
检测按键2是否被按下就和按键1一样只需要将pin值修改即可
4.2key.h
#ifndef __KEY_H__
#define __KEY_H__#include "sys.h"void key_init(void);
uint8_t key_scan(void);#endif
.h文件就是将函数名写进去就行,需要注意的是第二个函数的返回值是uint8_t是包含在stm32f1xx.h这个头文件中的,所以要#include “stm32f1xx.h”,又因为sys.h中也有stm32f1xx.h,所以我直接就#include "sys.h"了。
4.3main.c
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "key.h"int main(void)
{HAL_Init(); /* 初始化HAL库 */stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */led_init();key_init();uint8_t key_num = 0; while(1){ key_num = key_scan();if(key_num == 1){led1_toggle();}if(key_num == 2){led2_toggle();}}
}
这里面就是调用上面写好的函数,将返回值保存到key_num变量中,然后判断它的值,再进行具体操作。
注意尽量不要直接key_scan() == 1或key_scan() == 2,这样判断,因为这样判断就相当于每循环一次将要调用两次key_scan()函数,这样按键操作就有很大的延迟,所以我们之间调用一次将返回值存到一个变量中就行。
完结