STM32 实现流水灯(基于 STM32F103C6T6 + HAL 库)

一、硬件准备

1. STM32F103C6T6A + STLink 仿真器

2. LED 3 只

3. 杜邦线若干(20条以内)

4. 面包板一块

5. 立式微动开关 2 只


二、线路连接

1. STM32 核心板 PA4 PA5 PA6 分别接三只 LED

2. PB5 PB6 分别接两个开关一端

3. 保证所有开关、LED 负极与核心板共地


三、端口配置

1. PA4 PA5 PA6 设置为输出

2. PB5 PB6 设置为输入


 

四、代码编写

1. led.h

 1 #ifndef __LED_H
 2 #define __LED_H
 3 
 4 #define LED1_RED_PIN GPIO_PIN_4
 5 #define LED2_YELLOW_PIN GPIO_PIN_5
 6 #define LED3_GREEN_PIN GPIO_PIN_6
 7 
 8 #define LED_PORT GPIOA
 9 
10 #endif // !__LED_H

2. key.h

1 #ifndef __KEY_H
2 #define __KEY_H
3 
4 #define KEY1_DOWN_PIN GPIO_PIN_5
5 #define KEY2_UP_PIN GPIO_PIN_6
6 
7 #define KEY_PORT GPIOB
8 
9 #endif // !__KEY_H

按键功能是亮灯方向向上或向下,当两键同时按下,则亮所有灯。

这里两个头文件仅是用于改变量名,源文件仍可进行优化。

3. 修改 GPIO 初始化函数,将 PB5 PB6 的电平设置为 GPIO_PULLUP。

意思是保持高电平状态,当按键按下,相当于端口接地,电平被拉低,所以检测到输入低电平时表示按键动作。

4. 主函数初始化部分:

1 unsigned char ch_flow = 2U;
2 const unsigned int uint_delay = 250U;
3 HAL_GPIO_WritePin(LED_PORT, LED2_YELLOW_PIN, GPIO_PIN_SET);

line1 中定义 ch_flow 是用于代表当前是第几个灯亮,2 代表第二个灯亮,故 line3 中将第二个灯的端口设为高电平。

line2 设置延时消抖,如果不设置延时或延时过低,就会造成操作过度响应,反之则会响应变慢。

5. 主函数循环部分:

 1 GPIO_PinState down_key_state = HAL_GPIO_ReadPin(KEY_PORT, KEY1_DOWN_PIN);
 2 GPIO_PinState up_key_state = HAL_GPIO_ReadPin(KEY_PORT, KEY2_UP_PIN);
 3 // two key pressed at same time
 4 if (GPIO_PIN_RESET == (up_key_state | down_key_state))
 5 {
 6     HAL_GPIO_WritePin(LED_PORT, LED1_RED_PIN, GPIO_PIN_SET);
 7     HAL_GPIO_WritePin(LED_PORT, LED2_YELLOW_PIN, GPIO_PIN_SET);
 8     HAL_GPIO_WritePin(LED_PORT, LED3_GREEN_PIN, GPIO_PIN_SET);
 9     HAL_Delay(uint_delay);
10     continue;
11 }
12 // flow down
13 if (GPIO_PIN_RESET == down_key_state)
14 {
15     switch(ch_flow)
16     {
17         case 1U:
18             HAL_GPIO_WritePin(LED_PORT, LED1_RED_PIN, GPIO_PIN_RESET);
19             HAL_GPIO_WritePin(LED_PORT, LED2_YELLOW_PIN, GPIO_PIN_SET);
20             ch_flow = 2U;
21             HAL_Delay(uint_delay);
22             continue;
23         case 2U:
24             HAL_GPIO_WritePin(LED_PORT, LED2_YELLOW_PIN, GPIO_PIN_RESET);
25             HAL_GPIO_WritePin(LED_PORT, LED3_GREEN_PIN, GPIO_PIN_SET);
26             ch_flow = 3U;
27             HAL_Delay(uint_delay);
28             continue;
29         case 3U:
30             HAL_GPIO_WritePin(LED_PORT, LED3_GREEN_PIN, GPIO_PIN_RESET);
31             HAL_GPIO_WritePin(LED_PORT, LED1_RED_PIN, GPIO_PIN_SET);
32             ch_flow = 1U;
33             HAL_Delay(uint_delay);
34             continue;
35     }
36 }
37 // flow up
38 if (GPIO_PIN_RESET == up_key_state)
39 {
40     switch(ch_flow)
41     {
42         case 3U:
43             HAL_GPIO_WritePin(LED_PORT, LED3_GREEN_PIN, GPIO_PIN_RESET);
44             HAL_GPIO_WritePin(LED_PORT, LED2_YELLOW_PIN, GPIO_PIN_SET);
45             ch_flow = 2U;
46             HAL_Delay(uint_delay);
47             break;
48         case 2U:
49             HAL_GPIO_WritePin(LED_PORT, LED2_YELLOW_PIN, GPIO_PIN_RESET);
50             HAL_GPIO_WritePin(LED_PORT, LED1_RED_PIN, GPIO_PIN_SET);
51             ch_flow = 1U;
52             HAL_Delay(uint_delay);
53             break;
54         case 1U:
55             HAL_GPIO_WritePin(LED_PORT, LED1_RED_PIN, GPIO_PIN_RESET);
56             HAL_GPIO_WritePin(LED_PORT, LED3_GREEN_PIN, GPIO_PIN_SET);
57             ch_flow = 3U;
58             HAL_Delay(uint_delay);
59             break;
60     }
61 }

五、测试运行

1. 通过单独按任意一个键向某一方向流动亮灯的功能

2. 同时按住两个按键将三个灯全部点亮的功能


 

posted @ 2024-11-28 15:06  永恒月华  阅读(116)  评论(0编辑  收藏  举报