完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
独立按键
独立按键的原理图: 其中,S4,S5,S6,S7是独立按键,需要用跳线帽接右边: 一 只有短按的代码: key.h #ifndef _KEY_H_ #define _KEY_H_ #include ***it k4=P3^3; ***it k5=P3^2; ***it k6=P3^1; ***it k7=P3^0; extern unsigned char k4_press; extern unsigned char k5_press; extern unsigned char k6_press; extern unsigned char k7_press; void key_read(void); void key_control(void); #endif key.c /*独立按键采用了定时器扫描法*/ /*代码写的比较复杂,但是比较好看懂吧*/ #include unsigned char k4_press,k5_press,k6_press,k7_press; unsigned char key_sum; void key_read(void) { static unsigned char k4_time=0,k5_time=0,k6_time=0,k7_time=0; //一定要是static key_sum=0; /**********K4**********/ if(k4==0) //如果K4按下 { k4_time++; //k4_time用来判断按了多久 if(k4_time==1) //如果是一次的话 { key_sum=4; //得到key_sum为4,到key_control();函数中生成对应的press } else if(k4_time==20) //在定时器中断中30ms扫描一次,大概是按下0.6秒后 { k4_time=1; //只有短按,然他执行k4_time=1时候的操作 key_sum=0; //并且此时没有sum值 } } else k4_time=0; //没有按下按键则对应的time为0 if(k5==0) { k5_time++; if(k5_time==1) { key_sum=5; } else if(k5_time==20) { k5_time=1; key_sum=0; } } else k5_time=0; if(k6==0) { k6_time++; if(k6_time==1) { key_sum=6; } else if(k6_time==20) { k6_time=1; key_sum=0; } } else k6_time=0; if(k7==0) { k7_time++; if(k7_time==1) { key_sum=7; } else if(k7_time==20) { k7_time=1; key_sum=0; } } else k7_time=0; } //得到对应的press供主函数用 void key_control(void) { if(key_sum==4) k4_press=1; if(key_sum==5) k5_press=1; if(key_sum==6) k6_press=1; if(key_sum==7) k7_press=1; } main.c: #include #include #include unsigned char flag_key; void all_init(void) { P2=(P2&0X1F)|0XA0; P0=0X00; P2&=0X1F; P2=(P2&0X1F)|0X80; P0=0XFF; P2&=0X1F; } void main(void) { all_init(); while(1) { if(flag_key) //如果flag为1 { flag_key=0; //清零 key_read(); //执行这两个函数,扫描按键 key_control(); } //对应执行按键 if(k4_press) { k4_press=0; k4按下执行的任务 } if(k5_press) { k5_press=0; k5按下执行的任务 } if(k6_press) { k6_press=0; k6按下执行的任务 } if(k7_press) { k7_press=0; k7按下执行的任务 } } } void timer0_isr(void) interrupt 1 { static unsigned char flag_key_time=0; if(++flag_key_time==30) //每隔30ms扫描一次 { flag_key_time=0; //清零 flag_key=1; //每隔30ms flag=1 } } 二 长短按结合的代码: 上面那些代码在下面这里,如果k4_time=20时你可以另外算他一个sum值,再加一个press值,能实现长按,但是,这样的话,再判断出长按前,短按就被判断为真事件了,就会有影响: if(k4_time==20) { key_sum=; } 那么下面这个就改进了: key.c: #include #define S7 0X0E //按下s7拉低P30,下面同理 #define S6 0X0D #define S5 0X0B #define S4 0X07 //4~7为短按 //8~11是对应了4~7的长按 unsigned char key_sum=0,k4_press,k5_press,k6_press,k7_press,k8_press,k9_press,k10_press,k11_press; //用了这三个变量实现了长短按的逻辑 unsigned char flag_one=0,key_one=0,key_long=0; void key_read(void) { static unsigned char key_time=0; key_sum=0; P3=0X0F; //先让P30~P33拉高 if(P3!=0X0F) //如果不是这个值了就说明有按键按下 { key_time++; if(key_time==1) //按键按下很短时间,判断为初步判断为短按 { flag_one=1; //设立的按短按的flag变为1 if(P3==S7) key_sum=7; if(P3==S6) key_sum=6; if(P3==S5) key_sum=5; if(P3==S4) key_sum=4; } else if(key_time>33) { flag_one=0; //如果长时间按下,这里33X30大该是1秒,那么flag_one就变为0 key_long=1; //对应的长按就变为1 if(P3==S4) key_sum=8; else if(P3==S5) key_sum=9; else if(P3==S6) key_sum=10; else if(P3==S7) key_sum=11; } } else { key_time=0; //如果没按下,time为0 if(flag_one) //如果松开的时候flag_one是1,那么就说明为短按 { flag_one=0; //清零 key_one=1; //最终得到一个变量说明为短按,以便于主函数用 } key_long=0; //如果松开,长按就变为0 } } void key_control(void) //通过sum值,给出press { if(key_sum==4) k4_press=1; else if(key_sum==5) k5_press=1; else if(key_sum==6) k6_press=1; else if(key_sum==7) k7_press=1; else if(key_sum==8) k8_press=1; else if(key_sum==9) k9_press=1; else if(key_sum==10) k10_press=1; else if(key_sum==11) k11_press=1; } key.h: #ifndef _KEY_H_ #define _KEY_H_ #include extern unsigned char k4_press; extern unsigned char k5_press; extern unsigned char k6_press; extern unsigned char k7_press; extern unsigned char k8_press; extern unsigned char k9_press; extern unsigned char k10_press; extern unsigned char k11_press; extern unsigned char key_one; extern unsigned char key_long; void key_read(void); void key_control(void); #endif main.c #include #include #include void all_init(void) { P2=(P2&0X1F)|0XA0; P0=0X00; P2&=0X1F; P2=(P2&0X1F)|0X80; P0=0XFF; P2&=0X1F; } void main(void) { Timer0Init(); all_init(); while(1) { if(flag_key) { flag_key=0; key_read(); key_control(); } if(key_one) { key_one=0; if(k4_press) { k4_press=0; //短按k4的操作 } if(k5_press) { k5_press=0; //短按k5的操作 } if(k6_press) { k6_press=0; //短按k6的操作 } if(k7_press) { k7_press=0; //短按k7的操作 } } if(key_long) { key_long=0; if(k8_press) { k8_press=0; //长按k4的操作 } if(k9_press) { k9_press=0; //长按k5的操作 } if(k10_press) { k10_press=0; //长按k6的操作 } if(k11_press) { k11_press=0; //长按k7的操作 } } else k8_press=k9_press=k10_press=k11_press=0; } } void timer0_isr(void) interrupt1 { static unsigned char flag_key_time=0; if(++flag_key_time==30) { flag_key_time=0; flag_key=1; } } |
|
|
|
只有小组成员才能发言,加入小组>>
imx6ull 和 lan8742 工作起来不正常, ping 老是丢包
890 浏览 0 评论
3336 浏览 9 评论
3013 浏览 16 评论
3506 浏览 1 评论
9098 浏览 16 评论
1216浏览 3评论
631浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
619浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2361浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1926浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-11 15:58 , Processed in 1.088285 second(s), Total 79, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号