dzbj 发表于 2017-11-2 15:53 这个程序什样改才精准运行呢 楼主能够修改程序粘贴上传看看吗谢谢 |
不用while等待按键松开 直接写个死延时 用for 死等20ms然后看按键状态 如果还是按下 就认为有效 然后执行led亮或灭 这样就和你是否松开按键没关系了 |
C语言不会,汇编的话是在判断按键有没有放开,没有放开就去执行亮灯程序,然后在回来判断按键有没有放开,放开就执行下一条程序。 |
//这个程序是按你的电路图和元件编号重新改的,简洁明了,有详细注释。没有读懂前不要改变电路和程序。 #include <reg52.h> #define uchar unsigned char #define uint unsigned int #define key (P1 & 0x0f) //按键端口宏定义(P1的低4位) //sbit key1=P1^3; //按键1定义 //sbit key2=P1^2; //按键2定义 //sbit key3=P1^1; //按键3定义 //sbit key4=P1^0; //按键4定义 sbit led1=P1^4; //led1端口 sbit led2=P1^5; //led2端口 sbit led3=P1^6; //led3端口 sbit led4=P1^7; //led4端口 void keyscan() //按键扫描程序 { static bit sign=0; //按键有效标志 static uint count=0; //消抖计数变量 uchar num=0; //临时变量 if(key!=0x0f) //检测有键按下 { count++; //消抖计数 if(count>=1000) //100~1000,根据主循环周期调整约10~20ms { count=1000; //防止溢出 if(sign==0) //测试按键有效标志0 { sign=1; //按键有效标志置1 num=key; //保存P1低4位值0000 xxxx ,x为0或1 switch(num) { case 0x0e: led4=~led4; break; case 0x0d: led3=~led3; break; case 0x0b: led2=~led2; break; case 0x07: led1=~led1; break; default: break; } } } } else //键抬起 { sign=0; //按键有效标志清0 count=0; //消抖计数清0 } } void main() { while(1) //程序循环执行 { keyscan(); //按键扫描,子函数 } } |
![]() |
楼主在学习的过程中过于死板了,应灵活的去变通,可以用流程图去分析! |
去单片机的书上找 |
有此一问,说明楼主并未真正掌握防止键弹动的原理,或者是学习太死板。 建议楼主好好回顾并弄清这个原理,再出手,估计你自己就能解决了。 想不通,可以语音问我。 画出框图,再写程序,试试。 |
不用写那么多,给你改了一下,你试试。 #include <reg52.h> //定义一下,方便使用 #define uchar unsigned char #define uint unsigned int //sbit key1=P2^4; //按键1定义 //sbit key2=P2^5; //按键2定义 //sbit key3=P2^6; //按键3定义 //sbit key4=P2^7; //按键4定义 sbit led1=P3^0; //led1端口 sbit led2=P3^1; //led2端口 sbit led3=P3^2; //led3端口 sbit led4=P3^3; //led4端口 void keyscan() //按键扫描程序 { static bit sign=0; //按键有效标志 static uint count=0; //消抖计数变量 uchar num=0; //临时变量 if((P2&0xf0)!=0xf0) //检测按键有效 { count++; //消抖计数 if(count>=500) //100~1000,根据主循环周期调整约10~20ms { count=500; if(sign==0) //测试按键有效标志0 { sign=1; //按键有效标志置1 num=(P2&0xf0); //保存P2高4位值xxxx 0000,x为0或1 switch(num) { case 0xe0: led1=~led1; break; case 0xd0: led2=~led2; break; case 0xb0: led3=~led3; break; case 0x70: led4=~led4; break; default: break; } } } } else //键抬起 { sign=0; //按键有效标志清0 count=0; //消抖计数清0 } } void main() { while(1) //程序循环执行 { keyscan(); //按键扫描,子函数 } } |
gb302 发表于 2017-10-29 22:12 可以俢改后截图看看吗 |
学习了新思路。在这我也分享一下我通常处理这种问题的方法: 1、如果只有亮灭两种情况的话,可以考虑使用LED = ~LED; 2、如果情况大于三种以上,可以考虑求余方法,key_count % 3 == 0;key_count % 3 == 1;key_count % 3 == 2; |
gb302 发表于 2017-10-29 22:12 要什样取反执行lled1-4 呢 |
很好,很好,很好啊。 |
uchar keyflag_1=0; //按键标志位 uchar keyflag_2=0; //按键标志位 uchar keyflag_3=0; //按键标志位 uchar keyflag_4=0; //按键标志位 这些变量定义的类型也有问题,第三次key_flag==3怎么执行? |
每次按键被识别后,执行lled1-4取反不就可以了吗? |