完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
本帖最后由 月影狼迹 于 2013-6-9 14:15 编辑
初学者。用16F877A写的,能显示2001~2099年任意时间、日期和星期。用Protues仿真时,时间走的比电脑时钟慢。求大神分析一下! #include __CONFIG(0x3F39); #define RS RC0 #define RW RC1 #define E RC2 #define T1_50MS 15536 #define key1 RB0 #define key2 RB1 #define key3 RB2 #define key4 RB3 const char table0[]={'0','1','2','3','4','5','6','7','8','9',' '}; //显示查表表格 const char table1[]={'/',':',' '}; const char table2[]={'S','U','N','M','O','N','T','U','E','W','E','D','T','H','U','F','R','I','S','A','T'}; char num=0,num0=0,num1=0; //定时器计数变量 int sec=0,min=0,hour=0,Years=2000; //时分秒计数变量 char day=1,weekday=0,mon=1,year=1; //年月日计数变量 char num5=0,num6=0,num7=0; //按键延时计数变量 char count1,count2=0,count3=0,count4=0; //按键状态变量 char count5=0,count6=0,count7=0; char hh=0,hl=0,mh=0,ml=0,sh=0,sl=0,dd; //时分秒年月日高低位分解寄存 char nh=0,nl=1,yh=0,yl=1,rh=0,rl=1; char tmp,tmp_days; //星期几计算中间变量 /******************************************************************/ /* 函数声明 */ /******************************************************************/ void delayms(unsigned int ms) //ms延时子程序 { unsigned int x,y; for (x=ms;x>0;x--) for (y=110;y>0;y--); } /******************************************************************/ void delayus(char us) //us延时子程序 { char x; x=us; while(x>0) { x--; NOP();NOP();NOP();NOP(); } } /****************************************************************/ void write_com(char com) //LCD写命令子程序 { RS=0;NOP(); RW=0;NOP(); PORTD=com; delayms(1); E=1; delayms(1); E=0; } /****************************************************************/ void write_data(char d) //LCD写数据子程序 { RS=1;NOP(); RW=0;NOP(); PORTD=d; delayms(1); E=1; delayms(1); E=0;NOP(); RS=0; } /*********************************************************************/ void init() //初始化子程序 { TRISB=0b11111111; TRISC=0b00000000; TRISD=0b00000000; TMR0=(65536-50000)/256; OPtiON=0b10000111; INTCON=0b10100000; RS=1;NOP(); RW=0;NOP(); E=0; delayms(20); write_com(0b00110000); delayms(1); write_com(0b00110000); delayus(10); write_com(0b00110000); delayus(10); write_com(0b00110000); write_com(0b00111000); write_com(0b00001100); write_com(0b00000001); delayms(2); write_com(0b00000110); } /*********************************************************************/ void display() //扫描显示子程序 { write_com(0x80+0x00); delayus(10); write_data(table0[2]); delayus(10); write_data(table0[0]); delayus(10); write_data(table0[nh]); delayus(10); write_data(table0[nl]); delayus(10); write_data(table1[0]); delayus(10); write_data(table0[yh]); delayus(10); write_data(table0[yl]); delayus(10); write_data(table1[0]); delayus(10); write_data(table0[rh]); delayus(10); write_data(table0[rl]); delayus(10); write_com(0x80+0x0c); delayus(10); for(num=(3*weekday);num<(3*weekday+3);num++) write_data(table2[num]); write_com(0x80+0x40); delayus(10); write_data(table0[hh]); delayus(10); write_data(table0[hl]); delayus(10); write_data(table1[1]); delayus(10); write_data(table0[mh]); delayus(10); write_data(table0[ml]); delayus(10); write_data(table1[dd]); delayus(10); write_data(table0[sh]); delayus(10); write_data(table0[sl]); delayus(10); } /*********************************************************************/ void keyscan() { if(key1==0) //key1为选择按键 { num0++; if(num0>5) //50ms延时确认 num0=6; if(num0==2) { count1++; //count1==1,选择调整时针 ount1==4,选择调整当前年 if(count1==7) //count1==2,选择调整分针 ount1==5,选择调整当前月 count1=0; //count1==3,选择调整秒针 ount1==6,选择调整当前日 } } else num0=0; if(key2==0) //key2为时分秒年月日加1按键 { num5++; if(num5>5) num5=6; if(num5==2) { if(count1==1) { hour++; if(hour==24) hour=0; } if(count1==2) { min++; if(min==60) min=0; } if(count1==3) { sec++; if(sec==60) sec=0; } if(count1==4) { year++; if(year==100) year=1; } if(count1==5) { mon++; if(mon==13) mon=1; } if(count1==6) { Years=year+2000; switch (mon) { case 2: { day++; if(Years%4==0) { if(day==30) day=1; } else { if(day==29) day=1; } } break; case 1: case 3: case 5: case 7: case 8: case 10: case 12: { day++; if(day==32) day=1; } break; case 4: case 6: case 9: case 11: { day++; if(day==31) day=1; } break; } } } } else num5=0; if(key3==0) //key3为时分秒年月日减1按键 { num6++; if(num6>5) num6=6; if(num6==2) { if(count1==1) { hour--; if(hour== -1) hour=23; } if(count1==2) { min--; if(min== -1) min=59; } if(count1==3) { sec--; if(sec== -1) sec=59; } if(count1==4) { year--; if(year==0) year=99; } if(count1==5) { mon--; if(mon==0) mon=12; } if(count1==6) { Years=year+2000; switch (mon) { case 2: { day--; if(Years%4==0) { if(day==0) day=29; } else { if(day==0) day=28; } } break; case 1: case 3: case 5: case 7: case 8: case 10: case 12: { day--; if(day==0) day=31; } break; case 4: case 6: case 9: case 11: { day--; if(day==0) day=30; } break; } } } } else num6=0; if(key4==0) //key4为确认按键 { num7++; if(num7>5) num7=6; if(num7==2) count1=0; } else num7=0; } /*********************************************************************/ void timer() { if(num1<10) dd=1; else dd=2; if(num1>=20) //中断20次,时间计满1s { num1=0; sec++; //秒针加1 if(sec>=60) //计满60秒,秒针归零 { sec=0; min++; } //分针加1 sh=sec/10; //秒针高低位分解 sl=sec%10; if(min>=60) //计满60分,分针归零 { min=0; hour++; } //时针加1 mh=min/10; //分针高低位分解 ml=min%10; if(hour>=24) //计满24小时,时针归零 { hour=0; day++; } //日期加1 hh=hour/10; //时针高低位分解 hl=hour%10; switch(mon) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: { if(day>31) { //月大日期计满31天,日期归1 day=1; mon++; } //月份加1 rh=day/10; //日期高低位分解 rl=day%10; } break; case 4: case 6: case 9: case 11: //月小日期计满30天,日期归1 { if(day>30) { day=1; mon++; } //月份加1 rh=day/10; //日期高低位分解 rl=day%10; } break; case 2: { Years=year+2000; if(Years%4==0) { if(day>29) //润年二月日期计满29天,日期归1 { day=1; mon++; } //月份加1 rh=day/10; //日期高低位分解 rl=day%10; } else { if(day>28) //平年二月日期计满29天,日期归1 { day=1; mon++; } //月份加1 rh=day/10; //日期高低位分解 rl=day%10; } } break; } if(mon>12) { //月份计满12,月份归1 mon=1; year++; } //年份加1 yh=mon/10; //月份高低位分解 yl=mon%10; if(year>99) //年份计满99,年份归1 year=1; nh=year/10; //年份高低位分解 nl=year%10; } } /*********************************************************************/ void time_change() { if(count1==1) //等于1表示有调整时针请求 { dd=1; if(count2>=20) //时针500ms闪烁 count2=0; if(count2<10) { hh=10; hl=10; } else { hh=hour/10; hl=hour%10; } } if(count1==2) //等于2表示有调整分针请求 { hh=hour/10; //时秒针年月日正常显示 hl=hour%10; dd=1; if(count3>=20) count3=0; if(count3<10) //分针500ms闪烁 { mh=10; ml=10; } else { mh=min/10; ml=min%10; } } if(count1==3) //等于3表示有调整秒针请求 { mh=min/10; ml=min%10; dd=1; if(count4>=20) count4=0; if(count4<10) //秒针500ms闪烁 { sh=10; sl=10; } else { sh=sec/10; sl=sec%10; } } if(count1==4) //等于4表示有调整年份请求 { sh=sec/10; sl=sec%10; dd=1; if(count5>=20) count5=0; if(count5<10) //年份500ms闪烁 { nh=10; nl=10; } else { nh=year/10; nl=year%10; } } if(count1==5) //等于5表示有调整月份请求 { nh=year/10; nl=year%10; dd=1; if(count6>=20) count6=0; if(count6<10) //月份500ms闪烁 { yh=10; yl=10; } else { yh=mon/10; yl=mon%10; } } if(count1==6) //等于6表示有调整日期请求 { yh=mon/10; yl=mon%10; dd=1; if(count7>=20) count7=0; if(count7<10) //日期500ms闪烁 { rh=10; rl=10; } else { rh=day/10; rl=day%10; } } } /*********************************************************************/ void weekdays(char day,char mon,char year) { Years=year+2000; tmp=(Years-1)/4+1; //计算当前年1月1日为星期几? tmp=(Years-tmp)+tmp*2; weekday=(tmp+5)%7; tmp_days=0; for(tmp=1;tmp if(tmp==1 || tmp==3 || tmp==5 || tmp==7 || tmp==8 || tmp==10) tmp_days=tmp_days+31; else if(tmp==4 || tmp==6 || tmp==9 || tmp==11) tmp_days=tmp_days+30; else if(tmp==2) { if(Years%4==0) tmp_days=tmp_days+29; else tmp_days=tmp_days+28; } } tmp_days=tmp_days+day-1; weekday=(weekday+tmp_days%7)%7+1; //计算当前日期为星期几? if(weekday==7) weekday=0; } /*********************************************************************/ void main(void) //主程序 { init(); while(1) { display(); timer(); time_change(); keyscan(); weekdays(day,mon,year); } } /*********************************************************************/ /*********************************************************************/ void interrupt T0(void) { if(T0IF==1) { T0IF=0; TMR0=(65536-50000)/256; if(count1==0) //等于0表示没有时间调整按键请求,正常走时 num1++; if(count1==1) //等于1表示有调整时针请求 count2++; if(count1==2) //等于2表示有调整分针请求 count3++; if(count1==3) //等于3表示有调整秒针请求 count4++; if(count1==4) //等于4表示有调整年份请求 count5++; if(count1==5) //等于5表示有调整月份请求 count6++; if(count1==6) //等于6表示有调整日期请求 count7++; } }
|
|
相关推荐
2个回答
|
|
计数频率低.这个是要算过才可用的
|
|
|
|
我有经过计算的,预分频比1:256,TMR0=(256*256-50000)/256。50ms计一次,计20次为1s。 请指出哪里计算错误,谢谢! |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
464 浏览 0 评论
478 浏览 1 评论
基于瑞萨FPB-RA4E2智能床头灯项目——1编译环境搭建与点亮驱动ws2812全彩LED
439 浏览 0 评论
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-LCD显示图片编程示例之介绍mmap
994 浏览 0 评论
《DNESP32S3使用指南-IDF版_V1.6》第二章 常用的C语言知识点
1056 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11779 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-25 01:00 , Processed in 0.565480 second(s), Total 77, Slave 57 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号