完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
/**********************************************************************************************
* 描述:时间显示器 *功能按键:STC12C5A60S2右边方向键 右键为功能键 (按下选择年月日时分秒的设置) 左键为退出功能键 上键为加一键 下键为减一键 **********************************************************************************************/ #include #include #define uchar unsigned char #define uint unsigned int ***it BUZZ=P1^6; //定义蜂鸣器端,按键释放和整点响 ***it ENLCD=P1^5; //定义1602液晶LCDEN端,使能信号 ***it ADDR0=P1^0; //定义1602液晶RS端,数据/命令选择端(H/L) ***it ADDR1=P1^1; //定义1602液晶RW端,读/写选择端(H/L) uchar code keycode[] = {0x11,0x12,0x14,0x18,0x21,0x22,0x24,0x28, 0x41,0x42,0x44,0x48,0x81,0x82,0x84,0x88};//键位置 uchar yue,ri,shi,fen,miao,week,nian,flag,count; uchar code table[7][3]={"MON","TUE","WED","THU","FRI","SAT","SUN"}; //数字 //char code dat[]={"0123456789"}; /***********毫秒级延时函数**********/ void delay(uint x) { uint y,z; for(y=x;y>0;y--) for(z=110;z>0;z--); } /***********蜂鸣器发声函数**********/ void di(uint dd) { BUZZ=0; delay(dd); BUZZ=1; } /***********按键判断函数**********/ uchar key_scan() {uchar i,k,kcode,scode; P2 = 0xf0; if((P2&0xf0)!=0xf0) {delay(500); if((P2&0xf0)!=0xf0) {scode = 0xfe; for(k=0;k<4;k++) {P2 = scode; if((P2&0xf0)!=0xf0) {kcode = ~P2; for(i=0;i<16;i++) if(kcode == keycode[i]) return i; } else scode =_crol_(scode,1); } } } return(16); } /***********LCD1602忙等待**********/ uchar busycheck() {uchar s; ADDR0=0; ADDR1=1; ENLCD=1; delay(1); s=P0; ENLCD=0; return s; } /***********液晶写命令函数**********/ void write_com(uchar com) { while((busycheck()&0x80)==0x80); ADDR0=0; ADDR1=0; ENLCD=0; P0=com; delay(5); ENLCD=1; delay(5); ENLCD=0; } /***********液晶写数据函数**********/ void write_date(uchar date) { while((busycheck()&0x80)==0x80); ADDR0=1; ADDR1=0; ENLCD=0; P0=date; delay(5); ENLCD=1; delay(5); ENLCD=0; } /***********写年函数**********/ void write_nian(uchar add,uchar date)reentrant //reentrant定义为可重入函数,允许被递归调用 { uint bai,shi,ge; bai=date/100; shi=date%100/10; ge=date%100%10; write_com(0x80+add); //设置显示位置 write_date(0x30+bai); //0~9对应的字符码是0x30~0x39 write_date(0x30+shi); write_date(0x30+ge); /*write_date(dat[bai]); write_date(dat[shi]); write_date(dat[ge]);*/ } /***********大小月份设置**********/ uchar dxy(uchar r) { uchar k; switch(r) { case 1:k=31;break; case 2: //闰年29天, 平年28天 if((2000+nian)%100==0) if((2000+nian)%400==0) k=29; else k=28; else if((2000+nian)%4==0) k=29; else k=28; break; case 3:k=31;break; case 4:k=30;break; case 5:k=31;break; case 6:k=30;break; case 7:k=31;break; case 8:k=31;break; case 9:k=30;break; case 10:k=31;break; case 11:k=30;break; case 12:k=31;break; } return k; } /***********写月、日、时、分、秒函数**********/ void write_yrsfm(uchar add,uchar date) { uchar shi,ge; shi=date/10; ge=date%10; write_com(0x80+add); //设置显示位置 write_date(0x30+shi); write_date(0x30+ge); /*write_date(dat[shi]); write_date(dat[ge]);*/ } /***********写星期函数**********/ void write_week(uchar add,uchar date) { uchar i; write_com(0x80+add); //设置显示位置 for(i=0;i<3;i++) { write_date(table[date][i]); delay(5); } } /***********初始化函数**********/ void init() { count=0; P0=0xff; //关闭发光二极管、数码管 write_com(0x38); //设置16*2显示,5*7点阵,8位数据接口 write_com(0x0c); //设置开显示,不显示光标 write_com(0x06); //写一个字符后地址指针加1 write_com(0x01); //显示清零,数据指针清零 write_com(0x80); //设置显示初始位置 write_com(0x80+1); //写出年份的最高位“2” write_date('2'); write_com(0x80+5); //写出日期显示部分的的两个“-” write_date('-'); write_com(0x80+8); write_date('-'); write_com(0x80+0x40+6); //写出时间显示部分的的两个“:” write_date(':'); write_com(0x80+0x40+9); write_date(':'); miao=0; //秒 fen=0; //分 shi=0; //时 week=2; //星期 ri=12; //日 yue=4; //月 nian=17; //年 write_yrsfm(0x40+10,miao);//分别送去液晶显示 write_yrsfm(0x40+7,fen); write_yrsfm(0x40+4,shi); write_week(12,week); //写入星期 write_yrsfm(9,ri); write_yrsfm(6,yue); write_nian(2,nian); TMOD=0x01; //设置定时器0工作模式1 :16位定时器/计数器 TH0=0x4c; //定时器装初值 TL0=0x00; EA=1; //开总中断 ET0=1; //开定时器0中断 TR0=1; //启动定时器0 } /***********按键扫描函数**********/ void keyscan() { uchar key; key=key_scan(); if(key==12) //功能键按下 { delay(10); //消抖 if(key==12) //功能键确认按下 { flag++; //记录功能键按下次数 while(key!=12); //确认释放功能键 di(100); //每当有按键释放蜂鸣器发出滴声提醒 if((flag==1)||(flag==8)) //第一次按下功能键光标闪烁到秒位置 { TR0=0; //关闭定时器 write_com(0x80+0x40+11); //光标定位到秒位置 write_com(0x0f); //光标开始闪烁 } if(flag==2) //第二次按下功能键光标闪烁到分钟位置 { write_com(0x80+0x40+8); } if(flag==3) //第三次按下功能键光标闪烁到时位置 { write_com(0x80+0x40+5); } if(flag==4) //第四次按下功能键光标闪烁到星期位置 { write_com(0x80+12); } if(flag==5) //第五次按下功能键光标闪烁到日位置 { write_com(0x80+10); } if(flag==6) //第六次按下功能键光标闪烁到月位置 { write_com(0x80+7); } if(flag==7) //第七次按下功能键光标闪烁到年位置 { write_com(0x80+4); } if(flag==8) //第八次按下功能键退出功能键 flag=1; //记录变成1;光标重新回到秒位置 } } if(key==14) //退出调节 {delay(10); if(key==14) { while(key!=14); //释放按键 if(TR0==0) di(100); //只在调节时有按键释放蜂鸣器发出滴声 flag=0; //功能键按键次数清零 write_com(0x0c); //取消光标闪烁 TR0=1; //启动定时器 } } if(flag!=0) { //增大键 if(key==15) //只有功能键按下后,增大和减少键才有效 { delay(10); if(key==15) //确认增加按下 { while(key!=15); //释放按键 di(100); //每当有按键释放蜂鸣器发出滴声提醒 if(flag==1) //功能键第一次按下调节秒 { miao++; //秒加1 if(miao>59) miao=0; write_yrsfm(0x40+10,miao); //每调节一次送液晶显示一下 write_com(0x80+0x40+11); //显示位置重新回到调节处 } if(flag==2) //功能键第二次按下调节分 { fen++; if(fen>59) fen=0; write_yrsfm(0x40+7,fen); write_com(0x80+0x40+8); } if(flag==3) //功能键第三次按下调节时 { shi++; if(shi>23) shi=0; write_yrsfm(0x40+4,shi); write_com(0x80+0x40+5); } if(flag==4) //功能键第四次按下调节星期 { week++; if(week>6) week=0; write_week(12,week); write_com(0x80+12); } if(flag==5) //功能键第五次按下调节日 { ri++; if(ri>(dxy(yue))) ri=1; write_yrsfm(9,ri); write_com(0x80+10); } if(flag==6) //功能键第六次按下调节月份 { yue++; if(yue>12) yue=1; write_yrsfm(6,yue); write_com(0x80+7); } if(flag==7) //功能键第七次按下调节年份 { nian++; write_nian(2,nian); write_com(0x80+4); } } } //减少键 if(key==13) { delay(10); if(key==13) //确认减少键被按下 { while(key!=13); //按键释放 di(100); //每当有按键释放蜂鸣器发出滴声 if(flag==1) //功能键第一次按下调节秒 { //秒减1 miao--; if((miao==(-1))||(miao>59)) //59到0循环递减; miao=59; write_yrsfm(0x40+10,miao); //每调节一次送液晶显示一下 write_com(0x80+0x40+11); //显示位置重新回到调节处 } if(flag==2) //功能键第二次按下调节分 { fen--; if((fen==(-1))||(fen>59)) fen=59; write_yrsfm(0x40+7,fen); write_com(0x80+0x40+8); } if(flag==3) //功能键第三次按下调节时 { shi--; if((shi==(-1))||(shi>23)) shi=23; write_yrsfm(0x40+4,shi); write_com(0x80+0x40+5); } if(flag==4) //功能键第四次按下调节星期 { week--; if((week==(-1))||(week>6)) week=6; write_week(12,week); write_com(0x80+12); } if(flag==5) //功能键第五次按下调节日 { ri--; if((ri==0)||ri>dxy(yue)) ri=dxy(yue); write_yrsfm(9,ri); write_com(0x80+10); } if(flag==6) //功能键第六次按下调节月份 { yue--; if((yue==0)||(yue>12)) yue=12; write_yrsfm(6,yue); write_com(0x80+7); } if(flag==7) //功能键第七次按下调节年份 { nian--; write_nian(2,nian); write_com(0x80+4); } } } } } /***********主函数**********/ void main() { init(); while(1) //不停地检测按键是否被按下 { keyscan(); } } /***********中断函数**********/ void timer0() interrupt 1 //定时器0工作模式1 :16位定时器/计数器 { TH0=0x4c; //重装初值;65536=2^16(高八位,低八位),45872=50ms/(12*1/(11.0592MHz))us TL0=0x00; count++; //count每加一次为50毫秒 if((ri>dxy(yue))||(ri<1)) //大小月匹配 ri=1; write_yrsfm(9,ri); //日若变化则重新写入 if(count==20) //1秒时间到 { count=0; //清零重新再计20次 miao++; //秒、分、时、星期、日、月、年自动调节功能运行 if(miao==60) { miao=0; fen++; if(fen==60) { fen=0; di(500); //整点提醒 shi++; if(shi==24) { shi=0; week++; ri++; if(week>6) week=0; write_week(12,week); //星期若变化则重新写入 if(ri>dxy(yue)) { ri=1; yue++; if(yue==13) { yue=1; nian++; write_nian(2,nian); //年份若变化则重新写入 } write_yrsfm(6,yue); //月份若变化则重新写入 } write_yrsfm(9,ri); //日若变化则重新写入 } write_yrsfm(0x40+4,shi); //时若变化则重新写入 } write_yrsfm(0x40+7,fen); //分若变化则重新写入 } write_yrsfm(0x40+10,miao); //秒若变化则重新写入 } }
|
|
相关推荐
4 个讨论
|
|
|
不会的,仿真和版是相反的。我这个单片机上运行过
|
|
|
|
|
|
|
|
435 浏览 0 评论
464 浏览 0 评论
450 浏览 0 评论
806 浏览 0 评论
RT-Thread与英飞凌(infineon)合作得板子PSOC 6 板子学习
748 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
17022 浏览 31 评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-12 20:27 , Processed in 0.818647 second(s), Total 56, Slave 43 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
2959