外观
三、按键控制LED灯
1 电路分析
在桌面温湿度仪上,有一个功能按键,通过这个按键可以用于执行各类操作,比如控制LED灯、读取温湿度或显示电池电量等信息;
本次实验通过按键按下来控制LED灯点亮或熄灭来测试GPIO的输入功能。
注
在按键的左侧连接是GND,右侧连接的是GPIO-PB5,也就是说,当按键按下时,是低电平。如果想要单片机能够准确的知道按下的状态,则未按下时需要时引脚保持高电平,这样才有变化。
2 代码编写
2.1 创建工程
打开STM32CubeMx软件
2.2 设置参数
根据上方原理图,设置晶振引脚、下载引脚、按键引脚与LED测试引脚的参数;
对于LED引脚,需要配置为推挽输出模式,没有使用上下拉,且一开始就输出低电平,这样方便测试LED灯是否正常工作。
对于按键引脚,需要设置为输入模式,上拉(默认是高电平);
配置时钟树,这里主晶振没有使用外部而是内部晶振,外部低速晶振暂时没有使用,先不需要配置;
最后填写输出工程的名称,选择工程输出路径以及适配的IDE;
生成相关文件的.c与.h文件;
选择HAL库;
创建工程,随后打开,这个Cubemx软件就可以关闭了;
2.3 编译配置工程
正常应该是0错误0警告;
点击魔术棒,选择debug,选择合适的下载器,并配置下载器选项;
2.4 编写测试代码
在gpio.c文件的用户区编写测试代码,LED相关的代码直接照搬之前的即可;新增一个按键扫描函数,读取引脚电平;
若为低电平,则进行消抖,机械按键通常都有抖动,这里进行10ms消抖,若10ms过后还有按键按下,此时确定是真的有按键按下,等待按键送上随后返回TRUE;否则返回FALSE;
在主函数中定义一个变量接受按键值,并进行处理翻转LED灯,注意在主函数中不要加入延时函数,否则会干扰按键判断。
C
/*
函数内容:扫描按键
函数参数:无
返回值:如果按键按下,返回TRUE,否则返回FALSE
*/
uint8_t Scanf_Key(void)
{
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_5) == GPIO_PIN_RESET)
{
HAL_Delay(10);
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_5) == GPIO_PIN_RESET)
{
while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_5) == GPIO_PIN_RESET);
return TRUE;
}
}
return FALSE;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
C
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* USER CODE BEGIN Private defines */
#define TRUE 0x01
#define FALSE 0x02
/* USER CODE END Private defines */
void MX_GPIO_Init(void);
/* USER CODE BEGIN Prototypes */
void Open_Led(void);
void Close_Led(void);
void Toggle_LED(void);
uint8_t Scanf_Key(void);
/* USER CODE END Prototypes */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
C
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t key_value = 0;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
HAL_DeInit();
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
key_value = Scanf_Key(); //扫描按键
if(key_value == TRUE){ //如果有按键按下
Toggle_LED(); //翻转LED
key_value = FALSE; //复位按键状态
}
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46