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. 同时按住两个按键将三个灯全部点亮的功能