1
完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
学了一个多月51了,终于整了个电子钟出来,个人感觉还是比较有趣的。
需要注意的是我用的是普中的板子,板子类型不同,io口的功能可能会有所差异。然后我这个k1开关和k2开关是接反了的,原本k1应该是接P3^0,k2接P3^1的,结果我一测试才知道k1接到了P3^1,k2接到P3^0了,不过这不要紧,用***it定义位变量时注意换一下就可以了。然后大概讲讲功能,用8个数码管显示目前时间和闹铃时间,然后用4个独立按键对目前时间和闹铃时间进行调整(k2是加,k3是减 ,k4是用来停止闹铃的),第一次按k1是对目前时间秒数调整,第2次按k1是对目前时间分钟数调整,第三次按k1是对目前时间小时数调整,第4次按k1是对闹铃秒数调整,第5次按k1是对闹铃时间分钟数调整,第6次按k1是对闹铃秒数调整,第7次按k1是调整完毕,进去非调整状态即实时显示目前时间(不过有点差异,时间走的快了一点)。主要用到了数码管动态显示,独立按键,定时器中断这些。 代码如下: #include typedef unsigned int u16; typedef unsigned char u8; ***it led=P2^0; ***it lsa=P2^2; ***it l***=P2^3; ***it lsc=P2^4; ***it beep=P1^5; ***it k1=P3^1; ***it k2=P3^0; ***it k3=P3^2; ***it k4=P3^3; ***it dian=P0^7; u8 keyvalue,alarmexist=0; u8 smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67,0x00};//段选码,分别对应0到无 u16 cnt=0,i=0,j=0,flag=0,time[]={0,0,0,0,0,0,0,0};//只用数码管0,1 3,4 6,7 u16 alarm[]={0,0,0,0,0,0,1,0}; u16*p; void delay(u16 mmp); void t0andt1init(); void addproct(int x); void addproca(int x); void reduceproct(int x); void reduceproca(int x); void keyscan(); void jia(); void jian(); void main() { led=0; t0andt1init(); P0=0x00; while(1) { if(time[0]==alarm[0]&&time[1]==alarm[1]&&time[3]==alarm[3]&&time[4]==alarm[4]&&time[6]==alarm[6]&&time[7]==alarm[7])//满足条件 蜂鸣器以一定的时间间隔响,只到K4按键并松开,此时数码管任然正常显示当前时间 { alarmexist=0; while(k4) { beep=~beep; delay(25); beep=~beep; delay(25); } } keyscan(); } } void delay(u16 mmp) { while(mmp--); } void t0andt1init() { TMOD=0x11; TH0=0xfc; TL0=0x67;//赋定时器初始值,定时1ms TH1=0xfc; TL1=0x67; TR0=1;//T0定时器开始定时 EA=1; ET0=1; ET1=1; } void addproct(int x) //对非调整状态和调整状态的加1处理(仅用于对当前时间) { if(x==0||x==3||x==6) if(time[x]==10) { time[x]=0; time[x+1]=time[x+1]+1; addproct(x+1); } if(x==1||x==4) if(time[x]==6) { time[x]=0; time[x+2]=time[x+2]+1; addproct(x+2); } if(time[6]==4&&time[7]==2) time[6]=time[7]=0; } void addproca(int x) //对调整状态的加1处理(仅用于对闹钟时间) { if(x==0||x==3||x==6) if(alarm[x]==10) { alarm[x]=0; alarm[x+1]=alarm[x+1]+1; addproca(x+1); } if(x==1||x==4) if(alarm[x]==6) { alarm[x]=0; alarm[x+2]=alarm[x+2]+1; addproca(x+2); } if(alarm[6]==4&&alarm[7]==2) alarm[6]=alarm[7]=0; } void reduceproct(int x) // 对调整状态的减1处理(仅用于对当前时间) { if(time[0]==0&&time[1]==0&&time[3]==0&&time[4]==0&&time[6]==0&&time[7]==0) { time[0]=time[3]=9; time[1]=time[4]=5; time[6]=3; time[7]=2; return ; } if(x==0||x==3||x==6) { if(time[x]>=1) time[x]=time[x]-1; else { if(time[7]==0&&x==6) { time[6]=3; time[7]=2; } else { time[x]=9; reduceproct(x+1); } } } else { if(time[x]>=1) time[x]=time[x]-1; else { time[x]=5; if(x!=7) reduceproct(x+2); else time[x]=1; } } } void reduceproca(int x) // 对调整状态的减1处理(仅用于对闹钟时间) { if(alarm[0]==0&&alarm[1]==0&&alarm[3]==0&&alarm[4]==0&&alarm[6]==0&&alarm[7]==0) { alarm[0]=alarm[3]=9; alarm[1]=alarm[4]=5; alarm[6]=3; alarm[7]=2; return ; } if(x==0||x==3||x==6) { if(alarm[x]>=1) alarm[x]=alarm[x]-1; else { if(alarm[7]==0&&x==6) { alarm[6]=3; alarm[7]=2; } else { alarm[x]=9; reduceproca(x+1); } } } else { if(alarm[x]>=1) alarm[x]=alarm[x]-1; else { alarm[x]=5; if(x!=7) reduceproca(x+2); else alarm[x]=1; } } } void keyscan() { flag=0; keyvalue=0; if(k1==0) { TR0=0;//不在显示当前时间 TR1=1; delay(1000); if(k1==0) { while(!k1) ; delay(1000); led=~led; keyvalue++; } else return ; while(keyvalue!=7) { if(k1==0) { delay(1000); if(k1==0) { while(!k1) ; led=~led; keyvalue++; if(keyvalue==4) flag=1; } } if(k2==0) { delay(1000); if(k2==0) { while(!k2) ; led=~led; jia(); } } if(k3==0) { delay(1000); if(k3==0) { while(!k3) ; led=~led; jian(); } } } TR0=1; TR1=0; if(((alarm[6]+alarm[7]*10)*60+alarm[3]+alarm[4]*10)>((time[6]+time[7]*10)*60+time[3]+time[4]*10))//判断闹钟时间是否大于当前时间, alarmexist=1; else alarmexist=0; } } void jia() { switch(keyvalue) { case 1:time[0]=time[0]+1;addproct(0);break; case 2:time[3]=time[3]+1;addproct(3);break; case 3:time[6]=time[6]+1;addproct(6);break; case 4:alarm[0]=alarm[0]+1;addproca(0);break; case 5:alarm[3]=alarm[3]+1;addproca(3);break; case 6:alarm[6]=alarm[6]+1;addproca(6);break; } } void jian() { switch(keyvalue) { case 1:reduceproct(0);break; case 2:reduceproct(3);break; case 3:reduceproct(6);break; case 4:reduceproca(0);break; case 5:reduceproca(3);break; case 6:reduceproca(6);break; } } void Timer0() interrupt 1//非调整时,执行的中断服务程序 { TH0=0xfc; TL0=0x67;//赋定时器初始值,定时1ms cnt++; if(1000==cnt) { cnt=0; time[0]=time[0]+1; addproct(0); } P0=0X00; switch(i) { case 0:lsa=0;l***=0;lsc=0;P0=smgduan[time[0]];dian=(alarmexist==1)?1:0;i++;break; case 1:lsa=1;l***=0;lsc=0;P0=smgduan[time[1]];i++;i++;break; case 3:lsa=1;l***=1;lsc=0;P0=smgduan[time[3]];i++;break; case 4:lsa=0;l***=0;lsc=1;P0=smgduan[time[4]];i++;i++;break; case 6:lsa=0;l***=1;lsc=1;P0=smgduan[time[6]];i++;break; case 7:lsa=1;l***=1;lsc=1;P0=smgduan[time[7]];i=0;break; } } void Timer1() interrupt 3 //调整时,执行的中断服务程序 ,flag=0显示正在调整的time,为1显示正在调整的alarm { TH1=0xfc; TL1=0x67;//赋定时器初始值,定时1ms if(flag==0) p=time; else p=alarm; P0=0X00; switch(j) { case 0:lsa=0;l***=0;lsc=0;P0=smgduan[p[0]];j++;break; case 1:lsa=1;l***=0;lsc=0;P0=smgduan[p[1]];j++;j++;break; case 3:lsa=1;l***=1;lsc=0;P0=smgduan[p[3]];j++;break; case 4:lsa=0;l***=0;lsc=1;P0=smgduan[p[4]];j++;j++;break; case 6:lsa=0;l***=1;lsc=1;P0=smgduan[p[6]];j++;break; case 7:lsa=1;l***=1;lsc=1;P0=smgduan[p[7]];j=0;break; } } |
|
|
|
只有小组成员才能发言,加入小组>>
2548 浏览 0 评论
1145浏览 2评论
744浏览 1评论
498浏览 0评论
263浏览 0评论
424浏览 0评论
小黑屋| 手机版| Archiver| 德赢Vwin官网 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-21 17:00 , Processed in 1.226879 second(s), Total 77, Slave 59 queries .
Powered by 德赢Vwin官网 网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
德赢Vwin官网 观察
版权所有 © 湖南华秋数字科技有限公司
德赢Vwin官网 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号