完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
|
|
相关推荐
28个回答
|
|
你不会是要我们帮你整个程序都写出来吧
|
|
|
|
你不是这样吧,这样伸手,随便搜索一下都有吧
|
|
|
|
|
|
|
|
|
|
|
|
想问一下你的按键检测程序是不是这种模式:if(key == 0) { delay_ms(20); while(!key); } 这个由于引入了延时,延时期间,单片机什么事情都没做,浪费CPU,你应该要让单片机实现延时功能,确又能在延时期间做一些其他事情,再一个是实现按键短按与长按。 |
|
|
|
楼上为什么不选择定时呢?
|
|
|
|
利用定时器怎么说?如果说利用外部中断,让按键成为脉冲触发,这个确实应该是可以的,但是我现在问题是线路固定好了,只能用单片机的P0口来完成,没想到好的触发,我现在想到的一个程序是 void main() { P2=0xfe; num=P2; while(1) { while(P0==0xff); btn=P0; if(btn==0xfe) { num=_crol_(num,1); delay(300); P2=num; } if(btn==0xfd) { num=_cror_(num,1); delay(300); P2=num; } } } 这段程序能实现效果,靠的延时,但是总感觉不好一样 |
|
|
|
按键是弹性按键,按下后弹起,不分长按还是短按,楼下有我想到的一些程序,也是靠延时,能实现效果,但是感觉不咋好,这里有个更好的给你看看,我看的不清楚#include unsigned char scan_key(); void proc_key(unsigned char key_v); void delayms(unsigned char ms); ***it K1 = P0^0; //对应按钮K1 ***it K2 = P0^1; //对应按钮K2 main() { unsigned char key_s,key_v; key_v = 0x03; P2 = 0xfe; while(1) { key_s = scan_key(); if(key_s != key_v) { delayms(10); key_s = scan_key(); if(key_s != key_v) { key_v = key_s; proc_key(key_v); } } } } unsigned char scan_key() { unsigned char key_s; key_s = 0x00; key_s |= K2; key_s <<= 1; key_s |= K1; return key_s; } void proc_key(unsigned char key_v) { if((key_v & 0x01) == 0) { P2 = _cror_(P2,1); } else if((key_v & 0x02) == 0) { P2 = _crol_(P2, 1); } } void delayms(unsigned char ms) // 延时子程序 { unsigned char i; while(ms--) { for(i = 0; i < 120; i++); } } |
|
|
|
下面是我写的程序,你参考一下,你那个程序感觉可读性不是很强 #include /*按键程序,不采用任何空循环延时*/ ***it K1 = P0^0; ***it K2 = P0^1; unsigned char KeyValue = 0; //按键键值 unsigned char KeyShortDown = 0; //按键短按 unsigned char KeyLongDown = 0; //按键长按 unsigned char KeyUpFlag = 0; unsigned int KeyDownTime=0; //按键按下时间 void Time0Init(void); //定时器0初始化 unsigned char GetKeyValue(void); unsigned char IsKeyUp(void); //有按键松手 void main(void) { Time0Init(); P0 = 0xff; while(1) { if(KeyUpFlag == 1)//有按键松手 { KeyUpFlag = 0; KeyDownTime=0; switch (KeyValue) { case 1: if(KeyShortDown == 1) P1 ^= 0x01; if(KeyLongDown == 1) P1 ^= 0x02; KeyShortDown = 0; KeyLongDown = 0; break; case 2: if(KeyShortDown == 1) P1 ^= 0x04; if(KeyLongDown == 1) P1 ^= 0x08; KeyShortDown = 0; KeyLongDown = 0; break; default:break; } } } } void Time0Init(void) { TMOD |= 0x01; //定时器0方式1 TH0 = 0x8A; TL0 =0xCF; //定时器0定时30ms ET0 = 1; TR0 = 1; EA = 1; } unsigned char GetKeyValue(void) { if(0 == K1)return 1; if(0 == K2)return 2; return 0; //若没有按键按下则返回0 } unsigned char IsKeyUp(void) { if((K1 == 1)&&(K2 == 1))return 1; else return 0; } void Time0(void) interrupt 1 { unsigned char TempValue; TH0 = 0x8A; TL0 = 0xCF; //定时器0定时30ms TempValue = GetKeyValue(); //这里引入TempValue变量是因为松开手时GetKeyValue返回0, //若直接KeyValue=GetKeyValue那么松手时KeyValue=0了 if(TempValue != 0) { KeyValue = TempValue; KeyDownTime++; } if(KeyDownTime > 1) //30ms 去抖动 { if(0 != IsKeyUp()) //有按键松手 { KeyUpFlag = 1; if(KeyDownTime < 20) KeyShortDown = 1; //按键短按 if(KeyDownTime >= 20) KeyLongDown = 1; //按键长按 } } } |
|
|
|
你可以参考一下我写的程序,也可以对比一下吧。在你的程序中执行一次按键检测程序总时间有20ms左右吧,20ms中有90%的时间是空出来什么都没做的,这个时间我指的是执行这些语句所需要的时间。再看看我的程序吧,执行定时器中断中所有程序算200us左右吧,在主函数中也算200us左右吧,执行一次按键程序所需语句时间为400us左右吧,其他时间CPU自由扩展,按键一直按下对其他程序没什么影响,因为中断程序时间太短了 |
|
|
|
首先非常感谢你这么认真为我回答问题,你写的很不错,但是我感觉有点繁琐点了,我主要就是用一个按键直接控制一个灯的亮灭,按键连到P0^0,LED接在P2^0,如果说用到外部中断,那就非常简答,现在不能用这个,你说的我的程序可读性不高,那应该是8楼的吧,但是9楼的程序可读性应该是很好的,你不妨看下九楼的程序。非常感谢你的回答 |
|
|
|
e ,不好意思,我可能看错了点,是控制流水灯的实现,用两个开关 |
|
|
|
不用谢啊,写程序要多积累点东西,到网上多找点好资料,c语言方面看一下《c与指针》《c缺陷与陷阱》,还有一点是程序风格很重要,我所说的可读性是指变量名和函数名的命名规则,比如不能用aa,bb,cc,dd这样的方式来命名,几个月后可能自己都看不到自己的程序了,另外一个我推荐的是不要使用延时是因为在大的项目中不方便,会带来很多的麻烦。另外推荐使用状态机编程,这样程序执行会更加好,可读性和可靠性高,调试非常方便 |
|
|
|
这个貌似很简单的
|
|
|
|
|
|
|
|
恩,多谢,受教了 |
|
|
|
|
|
|
|
|
|
|
|
{:12:}
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
277 浏览 0 评论
【敏矽微ME32G070开发板免费体验】之原厂2812测试例程解析
368 浏览 0 评论
766 浏览 2 评论
《DNESP32S3使用指南-IDF版_V1.6》第二十六章 INFRARED_RECEPTION实验
592 浏览 0 评论
879 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
12034 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-25 22:32 , Processed in 1.026660 second(s), Total 107, Slave 91 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号