From 416609dcd0988f34e992271392feb32b2453e7f9 Mon Sep 17 00:00:00 2001 From: Zhangwen <13970730+mkc46119@user.noreply.gitee.com> Date: Thu, 27 Feb 2025 10:21:19 +0800 Subject: [PATCH] =?UTF-8?q?feature:1.=E6=9B=B4=E6=8D=A2=E6=8C=89=E9=94=AE?= =?UTF-8?q?=E7=9A=84BSP=EF=BC=88=E4=BD=BF=E7=94=A8=E5=AE=9A=E6=97=B6?= =?UTF-8?q?=E5=99=A80=E4=B8=AD=E6=96=AD/10ms=EF=BC=89=E5=92=8CTASK?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=E9=95=BF=E6=8C=89=E5=92=8C=E7=9F=AD?= =?UTF-8?q?=E6=8C=89=E6=A0=87=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 4 +- source/app/main.c | 18 ++++----- source/app/task_btn.c | 44 +++++++++++++++++++++ source/app/task_btn.h | 23 +++++++++++ source/app/task_key.c | 14 +++---- source/app/task_key.h | 2 +- source/bsp/bsp_btn.c | 84 +++++++++++++++++++++++++++++++++++++++++ source/bsp/bsp_btn.h | 39 +++++++++++++++++++ source/bsp/bsp_config.h | 2 + source/ctask/time.c | 5 +++ 10 files changed, 217 insertions(+), 18 deletions(-) create mode 100644 source/app/task_btn.c create mode 100644 source/app/task_btn.h create mode 100644 source/bsp/bsp_btn.c create mode 100644 source/bsp/bsp_btn.h diff --git a/.vscode/settings.json b/.vscode/settings.json index d5b773d..1a4b429 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -25,6 +25,8 @@ "task_key.h": "c", "task_game.h": "c", "app_config.h": "c", - "type_traits": "c" + "type_traits": "c", + "task_btn.h": "c", + "bsp_btn.h": "c" } } \ No newline at end of file diff --git a/source/app/main.c b/source/app/main.c index 903f112..fc3df0c 100644 --- a/source/app/main.c +++ b/source/app/main.c @@ -49,11 +49,11 @@ void L0_main_init(void) //w600任务初始化 // L3_task_gm35_flow_init(W600_ST); //按键任务初始化 - L0_key_init(); + // L0_key_init(); //笔头任务初始化 L1_oid_init(); //语音模块初始化 - // L3_task_speech_init(); + L3_task_speech_init(); //tcp轮询任务初始化 L3_task_tcp_init(); L3_task_tcp_control_init(); @@ -91,7 +91,7 @@ void main(void) { s_nos_tick.t1s_heartbeat = 0;//置0清空 D_print_heartbeat() - L0_uart0_uc('.'); + L0_uart0_uc('.'); } #if 0 // 串口2的 接收数据 测试 @@ -119,7 +119,6 @@ void main(void) // s_uart1_rec.buf= 传感器数据 /// ff 08 xh xl yh yl zh zl /// s_uart1_rec.ok =1; - } /// L2_sd_save(); #endif ///////////////////////////////////////// @@ -149,25 +148,26 @@ void main(void) L3_task_game_handler(&_s_task_game); //笔头数据采集 - L3_task_oid_handle(&ts_task_oid); + // L3_task_oid_handle(&ts_task_oid); //WIFI // L3_uart2_exp_protocol(&s_uart2_at); - L2_task_gm35_flow_handle(&s_task_gm35_flow); + // L2_task_gm35_flow_handle(&s_task_gm35_flow); //寄存器值监控 - L3_task_reglisten_handle(&s_task_reglisten); + // L3_task_reglisten_handle(&s_task_reglisten); //输出,响应485协议 //L3_task_modbus_handler(&s_uart0_rec); //语音模块 - L3_task_speech_handle(&ts_speech); + // L3_task_speech_handle(&ts_speech); //按键处理 - L3_task_key_handle(&s_task_key_handle); + task_btn(); + // L3_task_key_handle(&s_task_key_handle); //L3_task_modbus_handler2(&s_uart2_rec); #if 1 diff --git a/source/app/task_btn.c b/source/app/task_btn.c new file mode 100644 index 0000000..f7cf894 --- /dev/null +++ b/source/app/task_btn.c @@ -0,0 +1,44 @@ +#include "task_btn.h" +#include "../bsp/bsp_btn.h" +#include "../bsp/bsp_config.h" +#include "../msp/UART0.h" + +void task_btn(void) +{ + switch(g_Key) + { + case KEY_UP: + if(g_KeyActionFlag == LONG_KEY) + { + L0_uart0_uc('#'); + L0_uart0_uchex(g_Key); + L0_uart0_0d0a(); + g_Key = KEY_NULL; + g_KeyActionFlag = NULL_KEY; + } + else if(g_KeyActionFlag == SHORT_KEY) + { + L0_uart0_uc('@'); + L0_uart0_uchex(g_Key); + L0_uart0_0d0a(); + LED1 = ~LED1; + g_Key = KEY_NULL; + g_KeyActionFlag = NULL_KEY; + } + break; + case KEY_DOWN: + LED2 = ~LED2; + L0_uart0_uchex(g_Key); + L0_uart0_0d0a(); + g_Key = KEY_NULL; + break; + case KEY_PWR: + LED4 = ~LED4; + L0_uart0_uchex(g_Key); + L0_uart0_0d0a(); + g_Key = KEY_NULL; + break; + default: break; + } +} + diff --git a/source/app/task_btn.h b/source/app/task_btn.h new file mode 100644 index 0000000..0389358 --- /dev/null +++ b/source/app/task_btn.h @@ -0,0 +1,23 @@ +/** + * 使用定时器来轮询Key_Scan()函数,定时节拍为2ms, + * 状态转换时间为10ms,即每次进入switch case语句的时间差为10ms + * 利用该10ms的间隙跳过按键抖动 + */ +#ifndef _app_task_btn_H +#define _app_task_btn_H + +// struct _s_task_key_ +// { +// TS_task task; +// vU8 key1_ok; +// vU8 key2_ok; +// vU8 key3_ok; +// vU8 time1; +// vU16 time2; +// vU8 time3; +// }; +// extern struct _s_task_key_ s_task_key_handle; +// extern void L0_key_init(void); +// extern void L3_task_key_handle(struct _s_task_key_ *p); +extern void task_btn(void); +#endif \ No newline at end of file diff --git a/source/app/task_key.c b/source/app/task_key.c index 1e51e55..237612e 100644 --- a/source/app/task_key.c +++ b/source/app/task_key.c @@ -91,7 +91,7 @@ void L3_task_key_handle(struct _s_task_key_ *p) while(!key1) { p->time1++; - // L0_uart0_uchex(p->time1); + L0_uart0_uchex(p->time1); } } } @@ -147,11 +147,11 @@ void L3_task_key_handle(struct _s_task_key_ *p) } if(p->key2_ok == 1) //if(p->key2_ok) 这里的p->key2_ok总是被赋值为0xFB,原因未知 { - L0_uart0_sendstr("p->key2_ok = "); - L0_uart0_uchex(p->key2_ok); - L0_uart0_0d0a(); - if(p->time2>=10) - { + if((p->time2)/100>=20) + { + L0_uart0_sendstr("p->time2 = "); + L0_uart0_ushex(p->time2); + L0_uart0_0d0a(); L0_uart0_sendstr("zbt"); L0_uart0_0d0a(); L0_uart3_sendArray((U8 *)&audio_zbt,9); @@ -202,7 +202,7 @@ void L3_task_key_handle(struct _s_task_key_ *p) //Lc_delay_ms(10);//按键防抖 if(key3 == 0) { - p->key3_ok = 1; + p->key3_ok = 1; while(!key3) { p->time3++; diff --git a/source/app/task_key.h b/source/app/task_key.h index 0f011a5..6240a9d 100644 --- a/source/app/task_key.h +++ b/source/app/task_key.h @@ -25,7 +25,7 @@ struct _s_task_key_ vU8 key2_ok; vU8 key3_ok; vU8 time1; - vU8 time2; + vU16 time2; vU8 time3; }; extern struct _s_task_key_ s_task_key_handle; diff --git a/source/bsp/bsp_btn.c b/source/bsp/bsp_btn.c new file mode 100644 index 0000000..c1aadde --- /dev/null +++ b/source/bsp/bsp_btn.c @@ -0,0 +1,84 @@ +/* + * 多个按键检测短按和长按事件 + * 短按:时间 10ms < T < 1 s, 长按:时间 T >1 s + * 功能:使用状态机方式,扫描单个按键;扫描周期为10ms,10ms刚好跳过抖动; + * 状态机使用switch case语句实现状态之间的跳转 + * lock变量用于判断是否是第一次进行按键确认状态 + * :按键释放后才执行按键事件 + */ + +#include "bsp_btn.h" +#include "bsp_config.h" +#include "bsp_config.h" +#include "../msp/UART0.h" + +extern KEY_STATE KeyState = KEY_CHECK; // 初始化按键状态为检测状态 +KEY_TYPE g_KeyActionFlag = NULL_KEY; // 用于区别长按和短按 +KEY_VALUE g_Key = KEY_NULL; +u8 g_KeyFlag = 0; // 按键有效标志,0 无效 1 有效 + +static u8 TimeCnt = 0; //10ms为颗粒 +static u8 lock = 0; //lock变量用于判断是否是第一次进行按键确认状态 + +void Key_Scan(void) +{ + static u8 TimeCnt = 0; //10ms为颗粒 + static u8 lock = 0; + switch (KeyState) + { + //按键未按下状态,此时判断Key的值 + case KEY_CHECK: + if(!Key) //如果按键Key值为0,说明按键开始按下,进入下一个状态 + { + KeyState = KEY_COMFIRM; + } + TimeCnt = 0; //计数复位 + lock = 0; + break; + //按键按下状态确认: + case KEY_COMFIRM: + if(!Key) //查看当前Key是否还是0,再次确认是否按下 + { + if(!lock) lock = 1; //第一次进来置1 + TimeCnt ++; + // 多按键判断 + if(0 == key1) g_Key = KEY_UP; + else if(0 == key2) g_Key = KEY_DOWN; + else if(0 == key3) g_Key = KEY_PWR; + + if(TimeCnt > 200) // 长按 2 s + { + L0_uart0_uc('#'); + g_KeyActionFlag = LONG_KEY; + TimeCnt = 0; + lock = 0; //重新检查 + KeyState = KEY_RELEASE; // 需要进入按键释放状态 + } + // ??????????????????????? + + } + else + { + if(lock) //不是第一次进入,释放按键才执行 + { + g_KeyActionFlag = SHORT_KEY; // 短按 + KeyState = KEY_RELEASE; // 需要进入按键释放状态 + } + else // 当前Key值为1,确认为抖动,则返回上一个状态 + { + KeyState = KEY_CHECK; // 返回上一个状态 + } + } + break; + //按键释放状态 + case KEY_RELEASE: + if(Key) //当前Key值为1,说明按键已经释放,返回开始状态 + { + KeyState = KEY_CHECK; + } + break; + default: + break; + } +} + diff --git a/source/bsp/bsp_btn.h b/source/bsp/bsp_btn.h new file mode 100644 index 0000000..4817709 --- /dev/null +++ b/source/bsp/bsp_btn.h @@ -0,0 +1,39 @@ +/** + * 使用定时器来轮询Key_Scan()函数,定时节拍为2ms, + * 状态转换时间为10ms,即每次进入switch case语句的时间差为10ms + * 利用该10ms的间隙跳过按键抖动 + */ +#ifndef _bsp_btn_H +#define _bsp_btn_H + + +// 区分长按和短按 +typedef enum +{ + NULL_KEY = 0, + SHORT_KEY = 1, + LONG_KEY = 2, +}KEY_TYPE; + +// 按键状态:检测、确认、释放 +typedef enum +{ + KEY_CHECK = 0, + KEY_COMFIRM = 1, + KEY_RELEASE = 2, +}KEY_STATE; + +// 按键值 +typedef enum +{ + KEY_NULL, + KEY_UP, + KEY_DOWN, + KEY_PWR, +}KEY_VALUE; + +extern KEY_VALUE g_Key; +extern KEY_TYPE g_KeyActionFlag; + +extern void Key_Scan(void); + diff --git a/source/bsp/bsp_config.h b/source/bsp/bsp_config.h index f1e86ca..c1e21f1 100644 --- a/source/bsp/bsp_config.h +++ b/source/bsp/bsp_config.h @@ -178,6 +178,8 @@ #define key1 P32 //音量增大 #define key2 P33 //音量减小 #define key3 P40 //开关机 + #define Key (key1 && key2 && key3) + //EEP存储地址定义 #define D_EEP_SECTOR_SIZE 0x200 //每个扇区0x200==512bytes #define D_EEP_SECTOR_BLOCK_SIZE 0x40 //扇区中每个数据块0x40==64bytes,可选值[32,64,128]等 diff --git a/source/ctask/time.c b/source/ctask/time.c index 8c13fd2..757677c 100644 --- a/source/ctask/time.c +++ b/source/ctask/time.c @@ -1,5 +1,6 @@ #include "time.h" #include "../msp/uartx.h" +#include "../bsp/bsp_btn.h" #define D_TIMER_COUNT(t,clk,timeInUs) (U16)(65536 - 1.0 * (clk) / 1000 * (1.0 * timeInUs / 1000) / t) //#define D_TIMER_COUNT(t,clk,timeInUs) (U16)(65536 - (clk) / 1000 * timeInUs / 1000 / t) @@ -39,6 +40,8 @@ void timer0_isrHandle (void) D_SERVE_TIMER0 L1_tick_tick(); ///系统中的1sflag 和以10ms为颗粒的延时使用 为tdelay服务 + Key_Scan(); + //串口回调 for(i = 0; i < SERIAL_MAX_NUM; i++) { @@ -48,6 +51,8 @@ void timer0_isrHandle (void) D_SERVE_TIMER0 } } + + #endif /// BITN_1(DR_who_wakeup, DRB_who_wakeup_timer0); NOP(); NOP(); NOP();