irpas技术客

单片机按键功能:单击、双击、长按、三击_起疯了、、_单片机按键功能怎么实现

未知 4712

/*== ========================/*功能:单击 */ =================================*/

void key_det(void) { ?? ?if(key_1 == 0) //按下 ?? ?{ ?? ??? ?if(++key_cnt>6) ? //主循环10ms进来一次 ?作用:按下消抖 ? ?? ??? ?{ ?? ??? ??? ?if(key_flag == 0) //防止重复进入 ?? ??? ??? ?{ ?? ??? ??? ??? ?key_flag = 1; ?? ??? ??? ??? ?led_1 = ~led_1;? ?//单击事件 ?? ??? ??? ?} ?? ??? ?} ?? ?} ?? ?else ? ?//松开 ?? ?{

????????if(key_cnt >= 6) key_cnt = 6; ?? ??? ?if(key_cnt != 0) --key_cnt;//防止松开抖动 ?? ? ?? ??? ?if(key_cnt == 0)?? ?//防止重复进入 ?? ??? ?{ ?? ??? ??? ?if(key_flag) ?? ??? ??? ?{ ?? ??? ??? ??? ?key_flag = 0; ?? ??? ??? ?} ?? ??? ?} ?? ?} }

/*=============================/* 单击 双击 */================================*/

void key_det_2(void) { ?? ? ?? ?if(click_flag) ? //单击? ?? ?{ ?? ??? ?click_flag = 0; ?? ??? ?led_1 = ~led_1; ?? ?} ?? ? ?? ?if(double_click_flag) //双击? ?? ?{ ?? ??? ?double_click_flag = 0; ?? ??? ?led_2 = ~led_2; ?? ?} ?? ? ?? ?if(key_1 == 0)? ? //按下 ?? ?{ ?? ??? ?if(++key_cnt_2 > 6)//主循环10ms进来一次 作用:按下消抖 ?? ?? ??? ?{ ?? ??? ??? ?key_double_click_cnt = 0; ?? ??? ??? ?if(key_flag_2 == 0) ?//防止重复进入 ?? ??? ??? ?{ ?? ??? ??? ??? ?key_flag_2 = 1; ?? ??? ??? ?} ?? ??? ??? ?else if(key_flag_2_1 == 1) ?? ??? ??? ?{ ?? ??? ??? ??? ?key_flag_2_1 = 0; ?? ??? ??? ??? ?double_click_flag = 1; ? //300ms以内再次按下就判断为 双击事件 ?? ??? ??? ??? ?key_double_flag = 1; ? ?//该标志位置1 为了不触发单击 ?? ??? ??? ??? ?key_flag_2 = 0; ?? ??? ??? ?} ?? ??? ?} ?? ?} ?? ?else ?? ?{ ?? ??? ?if(key_flag_2) ?//防止重复进入 ?? ??? ?{ ?? ??? ??? ?key_flag_2_1 = 1; ?? ??? ??? ?if(++key_double_click_cnt >= 30) //300ms ?双击间隔时间改这里 ?? ??? ??? ?{ ?? ??? ??? ??? ?key_double_click_cnt = 0; ?? ??? ??? ??? ?if(key_double_flag == 0)? ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?click_flag = 1; //300ms以内没有再次按下按键就判断为 单击事件 ?? ??? ??? ??? ?} ?? ??? ??? ??? ?key_flag_2_1 = 0; ?? ??? ??? ??? ?key_double_flag = 0; ?? ??? ??? ??? ?key_flag_2 = 0; ?? ??? ??? ?} ?? ??? ?}?? ? ?? ?} }

/*=============================/* 单击 长按*/================================*/

void key_det_3(void) { ?? ?if(key_flag_1) ? //单击 亮灭led_1 ?? ?{ ?? ??? ?key_flag_1 = 0; ?? ??? ?led_1 = ~led_1; ?? ?} ?? ?if(key_long) //长按 亮灭led_2 ?? ?{ ?? ??? ?key_long = 0; ?? ??? ?led_2 = ~led_2; ?? ?} ?? ? ?? ?if(key_1 == 0)? ?//按下 ?? ?{ ?? ??? ?if(++key_cnt > 6) //主循环10ms进来一次 作用:按下消抖 ? ?? ??? ?{ ? ?? ??? ??? ?if(key_flag == 0 && key_long_flag == 0) //防止重复进入 ?? ??? ??? ?{ ?? ??? ??? ??? ?key_flag = 1; ?? ??? ??? ?} ?? ??? ??? ? ?? ??? ??? ?if((++key_cnt_1 > 200) && key_long_flag == 0) //长按时间 ?? ??? ??? ?{ ?? ??? ??? ??? ?key_cnt_1 = 0; ?? ??? ??? ??? ?key_flag = 0; //防止触发单击 ?? ??? ??? ??? ?key_long = 1; //长按事件 ?? ??? ??? ??? ?key_long_flag = 1; ?? ??? ??? ?} ?? ??? ?} ?? ?} ?? ?else ?? ?{ ?? ??? ?if(key_cnt >= 6) key_cnt = 6; ?? ??? ?if(key_cnt !=0) --key_cnt; ?? ??? ?key_long_flag = 0; ?? ??? ?key_cnt_1 = 0; ?? ??? ?if(key_cnt == 0) ?? ??? ?{ ?? ??? ??? ?if(key_flag) //防止重复进入 ?? ??? ??? ?{ ?? ??? ??? ??? ?key_flag = 0; ?? ??? ??? ??? ?key_flag_1 = 1; ?//单击事件 ?? ??? ??? ?} ?? ??? ?} ?? ?} }

以下两种写法:适用于一个按键实现多种功能、简单易懂、移植性高修改性高、可以运用到实际的项目开发

/*===========================/* 单击 双击 长按 */=============================*/

void key_det_1(void) {

?? ?if(key_flag_1 == 1) ?//单击? ?? ?{ ?? ??? ?key_flag_1 = 0; ?? ??? ?led_1 = ~led_1; ?? ?} ?? ?else if(key_flag_1 == 2) //双击 ?? ?{ ?? ??? ?key_flag_1 = 0; ?? ??? ?led_2 = ~led_2; ?? ?} ?? ?else if(key_flag_1 == 3) //长按 ?? ?{ ?? ??? ?key_flag_1 = 0; ?? ??? ?led_3 = ~led_3; ?? ?} ?? ? ?? ?switch(key_state) ?? ?{ ?? ??? ?case 0: ?? ??? ??? ?if(key_1 == 0)?? ??? ??? ??? ? //按下 ?? ??? ??? ?{ ?? ??? ??? ??? ?if(++key_cnt_1 > 6)?? ??? ? //主循环10ms进来一次 ?作用:按下消抖 ? ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?key_cnt_1 = 0; ?? ??? ??? ??? ??? ?key_state = 1; ?? ??? ??? ??? ?} ?? ??? ??? ?} ?? ??? ??? ?else ?? ??? ??? ?{ ?? ??? ??? ??? ?key_cnt_1 = 0; ?? ??? ??? ?} ?? ??? ?break; ?? ??? ?case 1: ?? ??? ??? ?if(key_1 == 1)?? ??? ??? ??? ? //松开 ?? ??? ??? ?{ ?? ??? ??? ??? ?key_cnt_1 = 0; ?? ??? ??? ??? ?key_state = 2; //?? ??? ??? ??? ?key_flag_1 = 1;?? ??? ? ? ? //单击判断不能放这里,不然会触发单击和双击 ?? ??? ??? ??? ?return;? ?? ??? ??? ?} ?? ??? ??? ?if(++key_cnt_1 >= 200)?? ??? ? //主循环10ms进来一次 = 2S ?? ??? ??? ?{ ?? ??? ??? ??? ?key_cnt_1 = 0; ?? ??? ??? ??? ?key_state = 3; ?? ??? ??? ??? ?key_flag_1 = 2;?? ??? ??? ?//长按事件 ?? ??? ??? ??? ?return;? ?? ??? ??? ?} ?? ??? ?break; ?? ??? ?case 2: ?? ??? ??? ?if(key_1 == 0)?? ??? ??? ??? ?//按下 ?? ??? ??? ?{ ?? ??? ??? ??? ?key_cnt_1 = 0; ?? ??? ??? ??? ?key_state = 3; ?? ??? ??? ??? ?key_flag_1 = 3;?? ??? ??? ? //双击判断 ?? ??? ??? ??? ?return;? ?? ??? ??? ?} ?? ??? ??? ?if(++key_cnt_1 >= 40)?? ??? ? // 计时超过400ms判断为单击事件 ?? ??? ??? ?{ ?? ??? ??? ??? ?key_cnt = 0; ?? ??? ??? ??? ?key_flag_1 = 1;?? ??? ??? ? //单击事件 ?? ??? ??? ??? ?key_state = 3; ?? ??? ??? ??? ?return; ? ?? ??? ??? ?} ?? ??? ?break; ?? ??? ?case 3: ?? ??? ??? ?if(key_1 == 1)?? ??? ??? ??? ?//松开 ?? ??? ??? ?{ ?? ??? ??? ??? ?key_state = 0; ?? ??? ??? ?} ?? ??? ?break; ?? ??? ?default: ?? ??? ??? ?key_state = 0;?? ??? ??? ? ?? ?} ?? ? ?? ?key_flag_1 = 0;?? ? }

/*========================?/* 单击 双击 长按? 三击*/? ?===========================*/

void key_det_1_1(void) {

?? ?if(key_flag_1 == 1) ?//单击? ?? ?{ ?? ??? ?key_flag_1 = 0; ?? ??? ?led_1 = ~led_1; ?? ?} ?? ?else if(key_flag_1 == 2) //双击 ?? ?{ ?? ??? ?key_flag_1 = 0; ?? ??? ?led_2 = ~led_2; ?? ?} ?? ?else if(key_flag_1 == 3) //长按 ?? ?{ ?? ??? ?key_flag_1 = 0; ?? ??? ?led_3 = ~led_3; ?? ?} ?? ?else if(key_flag_1 == 4) //三击 ?? ?{ ?? ??? ?key_flag_1 = 0; ?? ??? ?led_4 = ~led_4; ?? ?} ?? ? ?? ?switch(key_state) ?? ?{ ?? ??? ?case 0: ?? ??? ??? ?if(key_1 == 0) ? ? ? ? ? ? ? //按下 ?? ??? ??? ?{ ?? ??? ??? ??? ?if(++key_cnt_1 > 6) ? ? //主循环10ms进来一次 ?作用:按下消抖 ? ?? ??? ??? ??? ?{ ?? ??? ??? ??? ??? ?key_cnt_1 = 0; ?? ??? ??? ??? ??? ?key_state = 1; ?? ??? ??? ??? ?} ?? ??? ??? ?} ?? ??? ??? ?else ?? ??? ??? ?{ ?? ??? ??? ??? ?key_cnt_1 = 0; ?? ??? ??? ?} ?? ??? ?break; ?? ??? ?case 1: ?? ??? ??? ?if(key_1 == 1) ? ? ? ? ? ? ? //松开 ?? ??? ??? ?{ ?? ??? ??? ??? ?key_cnt_1 = 0; ?? ??? ??? ??? ?key_state = 2; //?? ??? ??? ??? ?key_flag_1 = 1;?? ??? ??? ? //单击判断不能放这里,不然会触发单击和双击 ?? ??? ??? ??? ?return;? ?? ??? ??? ?} ?? ??? ??? ?if(++key_cnt_1 >= 200)?? ??? ?//主循环10ms进来一次 = 2S ?? ??? ??? ?{ ?? ??? ??? ??? ?key_cnt_1 = 0; ?? ??? ??? ??? ?key_state = 5; ?? ??? ??? ??? ?key_flag_1 = 2;?? ??? ??? ?//长按事件 ?? ??? ??? ??? ?return;? ?? ??? ??? ?} ?? ??? ?break; ?? ??? ?case 2: ?? ??? ??? ?if(key_1 == 0)?? ??? ??? ??? ?//按下 ?? ??? ??? ?{ ?? ??? ??? ??? ?key_cnt_1 = 0; ?? ??? ??? ??? ?key_state = 3; ?? ??? ??? ??? ?return; ? ?? ??? ??? ?} ?? ??? ??? ?if(++key_cnt_1 >= 40)?? ??? ?// 计时超过400ms判断为单击事件 ?? ??? ??? ?{ ?? ??? ??? ??? ?key_cnt = 0; ?? ??? ??? ??? ?key_state = 5; ?? ??? ??? ??? ?key_flag_1 = 1;?? ??? ??? ?//单击事件 ? ?? ?? ??? ??? ??? ?return; ? ?? ??? ??? ?} ?? ??? ?break; ?? ??? ?case 3: ?? ??? ??? ?if(key_1 == 1)?? ??? ??? ??? ? //松开 ?? ??? ??? ?{ ?? ??? ??? ??? ?key_cnt_1 = 0; ?? ??? ??? ??? ?key_state = 4; ?? ??? ??? ??? ?return; ?? ??? ??? ?} ?? ??? ??? ?if(++key_cnt_1 >= 40)?? ??? ? // 计时超过400ms判断为双击事件 ?? ??? ??? ?{ ?? ??? ??? ??? ?key_cnt = 0; ?? ??? ??? ??? ?key_state = 5; ?? ??? ??? ??? ?key_flag_1 = 3;?? ??? ??? ?//双击事件 ? ? ?? ??? ??? ??? ?return; ?? ? ?? ??? ??? ?} ?? ??? ?break; ?? ??? ?case 4: ?? ??? ??? ?if(key_1 == 0)?? ??? ??? ??? ? //按下 ?? ??? ??? ?{ ?? ??? ??? ??? ?key_cnt_1 =0; ?? ??? ??? ??? ?key_state = 5; ?? ??? ??? ??? ?key_flag_1 = 4;?? ??? ??? ?//三击事件 ?? ??? ??? ??? ?return; ?? ??? ??? ?} ?? ??? ??? ?if(++key_cnt_1 >= 40)?? ??? ? // 计时超过400ms判断为双击事件 ?? ??? ??? ?{ ?? ??? ??? ??? ?key_cnt = 0; ?? ??? ??? ??? ?key_state = 5; ?? ??? ??? ??? ?key_flag_1 = 3;?? ??? ??? ? //双击事件 ? ? ?? ??? ??? ??? ?return; ?? ? ?? ??? ??? ?} ?? ??? ?break; ?? ??? ?case 5: ?? ??? ??? ?if(key_1 == 1)?? ??? ??? ??? ?//松开 ?? ??? ??? ?{ ?? ??? ??? ??? ?key_state = 0; ?? ??? ??? ?} ?? ??? ?break; ?? ??? ?default: ?? ??? ??? ?key_state = 0;?? ??? ??? ? ?? ?} ?? ? ?? ?key_flag_1 = 0;

}

/*=======================================================================*/

以上几种按键的写法是利用上班摸鱼时间整理出来的所以函数和变量的命名比较随意。

希望这篇文章能帮助到各位,如有更好的写法可以互相学习交流一下。

????????????????????????

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? 从事单片机软件开发大半年的小白


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #单片机按键功能怎么实现 #功能单击 #void #key_detvoid #ifkey_1