在此分享一个我写的单片机裸机按键长按判断程序,程序功能有一个按键
和一个led
,按键默认为低电平,按下时为高电平并且为中断上升沿触发,长按时让蜂鸣器开关状态反转一次,当蜂鸣器开关状态为关闭时,按按键时蜂鸣器不响,当蜂鸣器开关状态为打开时则每按一下按键蜂鸣器就会响一下。
类型定义
首先我们要定义一个结构体,这个结构体中包含各个用到的标志位和全局变量。
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
| #ifndef _SF_TYPES_H #define _SF_TYPES_H
#include "at32f435_437.h"
enum buzzer_t { BUZZER_FLAG_OFF, BUZZER_FLAG_ON };
struct sf_system_t { enum buzzer_t buzzer_flag; uint16_t key_state; uint16_t long_down_count; confirm_state led2_flag; };
extern struct sf_system_t sf_sys;
#endif
|
1 2 3 4 5 6 7 8 9
| #include "sf_types.h"
struct sf_system_t sf_sys = { .buzzer_flag = BUZZER_FLAG_OFF, .key_state = 0x0000, .long_down_count = 0 };
|
外部中断服务函数
1 2 3 4 5 6 7 8 9 10 11 12
| void EXINT15_10_IRQHandler(void) { if (exint_interrupt_flag_get(EXINT_LINE_13) != RESET){ sf_sys.key_state = SET_BIT(sf_sys.key_state, 14); exint_flag_clear(EXINT_LINE_13); }
}
|
滴答定时器中断服务函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| void SysTick_Handler(void) {
wk_timebase_handler();
if (GET_BIT(sf_sys.key_state, 12)) { sf_sys.long_down_count++; } else { sf_sys.long_down_count = 0; } }
|
主函数
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 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| int main(void) {
wk_system_clock_config();
wk_periph_clock_config();
wk_nvic_config();
wk_timebase_init();
wk_usart1_init();
wk_exint_config();
wk_gpio_config();
Line(); printf("初始化结束...\n"); Line();
while (1) { while (GET_BIT(sf_sys.key_state, 14) && (gpio_input_data_bit_read(SW1_GPIO_PORT, SW1_PIN) == SET)) { sf_sys.key_state = SET_BIT(sf_sys.key_state, 12);
if (sf_sys.long_down_count >= 1000) { printf("long_down_count>=500\n"); sf_sys.key_state = CLEAR_BIT(sf_sys.key_state, 12); sf_sys.key_state = CLEAR_BIT(sf_sys.key_state, 14); SELF_LOGICAL_NOT(sf_sys.buzzer_flag); BUZZER_ON(); wk_delay_ms(5); BUZZER_OFF(); wk_delay_ms(5); switch (sf_sys.buzzer_flag) { case BUZZER_FLAG_ON: printf("蜂鸣器已打开\n"); break; case BUZZER_FLAG_OFF: printf("蜂鸣器已关闭\n"); break; default: break; } } } sf_sys.key_state = CLEAR_BIT(sf_sys.key_state, 12);
if (GET_BIT(sf_sys.key_state, 14) && (gpio_input_data_bit_read(SW1_GPIO_PORT, SW1_PIN) == RESET)) { if (sf_sys.buzzer_flag == BUZZER_FLAG_ON) { BUZZER_ON(); wk_delay_ms(10); BUZZER_OFF(); wk_delay_ms(10); }
SELF_LOGICAL_NOT(sf_sys.led2_flag); gpio_bits_write(LED2_GPIO_PORT, LED2_PIN, sf_sys.led2_flag); sf_sys.key_state = CLEAR_BIT(sf_sys.key_state, 14); } } }
|
程序中用到的宏
1 2 3 4 5 6 7 8 9 10 11 12
| #ifndef __UTILS_H #define __UTILS_H
#define GetArrLen(array) sizeof(array) / sizeof(array[0]) #define SET_BIT(num, n) ((num) | (1 << (n))) #define CLEAR_BIT(num, n) ((num) & ~(1<<(n))) #define SELF_LOGICAL_NOT(num) (num = (!(num))) #define GET_BIT(num, bit_pos) ((num >> bit_pos) & 1)
#define Line() printf("===========================================\n")
#endif
|