找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2481|回复: 2
收起左侧

求动态显示数字钟

[复制链接]
ID:250369 发表于 2017-11-17 12:06 来自手机 | 显示全部楼层 |阅读模式
使用2个四位共阴数码管做显示部分。-
上电的时候,L1发光二极管以1S闪烁。
可调时功能,有到点报时、闹铃功能。
最小系统:stc89c52rc,12M晶振,2*30P电容,10K电阻,10U电容;
外围芯片:轻触按键*5,4位共阴数码管*2,三极管8550*1,蜂鸣器*1,排阻4K7*3,插针接口若干,LED*1,74HC573*1。
回复

使用道具 举报

ID:229016 发表于 2017-11-19 20:11 | 显示全部楼层
描述:LCD万年历,TX-1C实验板 STC89C52RC,晶振11.0592MHz (如果晶振12MHz时间更准些) ********************************/ #include<reg52.h> #include<intrins.h> #define uchar unsigned char #define uint unsigned int sbit LCD_EN=P3^4;                                 //定义1602液晶LCDEN端,使能信号 sbit LCD_RS=P3^5;                                 //定义1602液晶RS端,数据/命令选择端(H/L) //sbit LCD_RW=P3^6;                         //定义1602液晶RW端,读/写选择端(H/L)已接地禁止读 sbit BUZZ=P2^3;                                 //定义蜂鸣器端,按键释放和整点响 sbit dula=P2^6;                                        //段端口 sbit wela=P2^7;                                        //位端口 sbit key_1=P3^0;                                //进入调试方式 sbit key_2=P3^1;                                //调试+ sbit key_3=P3^2;                                //调试- sbit key_4=P3^3;                                //退出调试方式 sbit MND_1=P3^7;                                //矩阵键盘模拟地 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;         //月、日、时、分、秒、周、年变量 uchar flag=0;        //功能键计数变量 uint count=0;        //中断计数变量 bit Cnt1s=0;        //秒标志 uchar code table[7][3]={"MON","TUE","WED","THU","FRI","SAT","SUN"};//显示周 /***********毫秒级延时函数**********/ 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; } /***********LCD1602忙等待**********/  /* uchar busycheck() {         uchar s;                        //临时变量         LCD_RS=0;                //允许写指令 //        LCD_RW=1;                //允许读数据(读写端已接地,禁止读)         LCD_EN=1;                //高电平使能读数据         delay(1);                //延时         s=P0;                                //读P0数据赋值s         LCD_EN=0;                //低跳变执行         return s;                //返回s值 s=0x80有效 } */ /***********液晶写指令函数**********/ void write_com(uchar com)  { //        while((busycheck()&0x80)==0x80);//忙等待         LCD_RS=0;        //允许写指令 //        LCD_RW=0;        //读写端已接地,禁止读         LCD_EN=0;        //初始设置LCD_EN低电平         P0=com;                //传递指令         delay(5);        //延时         LCD_EN=1;        //使能写入         delay(5);        //延时         LCD_EN=0;        //低跳变执行 } /***********液晶写数据函数**********/ void write_date(uchar date)  { //        while((busycheck()&0x80)==0x80);//忙等待         LCD_RS=1;        //允许写数据 //        LCD_RW=0;        //读写端已接地,禁止读          LCD_EN=0;        //初始设置LCD_EN低电平         P0 =date;        //传递数据         delay(5);        //延时         LCD_EN=1;        //使能写入         delay(5);        //延时         LCD_EN=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;                         //         dula=0;                                //关闭数码管段端口         wela=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');         //写数据'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=5;                                                //星期         ri=20;                                      //日         yue=5;                                      //月         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);                        //写入年 } /***********按键扫描函数**********/ void keyscan()  {         if(key_1==0) //功能键按下         {                  delay(10); //消抖                 if(key_1==0)//功能键确认按下                 {                         flag++; //记录功能键按下次数                         while(!key_1); //确认释放功能键                         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_4==0) //退出调节         {                 delay(10);                 if(key_4==0)                 {                         while(!key_4); //释放按键                         if(TR0==0)                         di(100); //只在调节时有按键释放蜂鸣器发出滴声                         flag=0; //功能键按键次数清零                         write_com(0x0c); //取消光标闪烁                         count=0;                         Cnt1s=0;                         TR0=1; //启动定时器                 }          }         if(flag!=0) //功能键按下后flag=1         {  //增大键                 if(key_2==0) //只有功能键按下后,增大和减少键才有效                 {                         delay(10);                         if(key_2==0)//确认增加按下                         {                                 while(!key_2); //释放按键                                 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_3==0) //减少键被按下                 {                         delay(10);                         if(key_3==0)//确认减少键被按下                         {                                 while(!key_3);//按键释放                                 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 LCD_Refresh() {         if(flag==0)                //调整时停止刷新         {                 if((ri>dxy(yue))||(ri<1)) //大小月匹配                         ri=1;                 write_yrsfm(9,ri); //日若变化则重新写入                 if(Cnt1s==1) //1秒时间到                 {                         Cnt1s=0; //清零                         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); //秒若变化则重新写入                 }         } } void Timer0Init()                                //100微秒@12.000MHz {         TMOD = 0x02;                                //设置定时器自动重载模式 //        TL0 = 0x9C;                                        //设置定时初值 //        TH0 = 0x9C;                                        //设置定时重载值         TL0=0xA4;                                         //定时器装初值 100微秒@11.0592MHz         TH0=0xA4;                                         //定时器装初值 100微秒@11.0592MHz         TF0 = 0;                                                //清除TF0标志         TR0 = 1;                                                //定时器0开始计时         EA=1;                                                 //开总中断         ET0=1;                                                 //开定时器0中断 } /***********主函数**********/ void main()  {         MND_1=0;                                                        //矩阵键盘模拟地         init();                                                                //初始化程序         Timer0Init();                                                //初始化定时器                                                 di(100);                                                                //开机蜂鸣器提示音         while(1)                                                         //不停地检测按键是否被按下         {                 keyscan();                                                //按键扫描程序                 LCD_Refresh();                                        //液晶屏显示刷新         } } /***********中断函数**********/ void timer0() interrupt 1 {         count++;                                         //11.0592MHz误差0.17%,12MHz误差0         if(count>=10017)                        //1秒/11.0592MHz //        if(count>=10000)                        //1秒/12MHz         {                 count=0;                                        //清0                 Cnt1s=1;                                        //1秒标标志置1         } }
回复

使用道具 举报

ID:229016 发表于 2017-11-19 20:11 | 显示全部楼层
具体参考这个,做适当修改就可以了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表