单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1272|回复: 7
收起左侧

单片机数字电子钟课程设计 含源码,原理图,仿真图

[复制链接]
1291934342 发表于 2018-5-7 00:49 | 显示全部楼层 |阅读模式
这是花了几天时间做的课程设计,里面包含原理图,
代码,
仿真图,
程序,
大家请多多指教。

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
@}WY5%D$XX%{CV50J77CMLK.png 0.jpg

单片机源程序如下:
  1. #include<reg52.h>//包含52单片机头文件
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. sbit rs=P2^0;  //定义1602液晶RS端
  5. sbit lcden=P2^2;//定义1602液晶LCDEN端
  6. sbit rd=P2^1;        //定义1602液晶rd端
  7. sbit s1=P3^0;   //定义按键--功能键
  8. sbit s2=P3^1;        //定义按键--增加键
  9. sbit s3=P3^2;        //定义按键--减小键
  10. sbit beep=P2^3; //定义蜂鸣器端
  11. uchar count,s1num;
  12. char miao,shi,fen,nian,yue,ri,zhou,num,tian;
  13. char yizhou[8][4]={"MON","TUE","WEN","THU","FRI","SAT","SUN"};
  14. int pingnian[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
  15. int ruinian[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
  16. void delay(uint z)  //延时函数
  17. {
  18.         uint x,y;
  19.         for(x=z;x>0;x--)
  20.                 for(y=110;y>0;y--);
  21. }
  22. void di()
  23. {
  24.         uchar i;
  25.         for(i=0;i<100;i++)
  26.         {
  27.                  beep = ~beep;
  28.                 delay(1);
  29.         }
  30.         beep = 0;
  31. }
  32. void write_com(uchar com)//液晶写命令函数
  33. {
  34.         rs=0;
  35.         lcden=0;
  36.         P0=com;
  37.         delay(5);
  38.         lcden=1;
  39.         delay(5);
  40.         lcden=0;       
  41. }
  42. void write_date(uchar date)//液晶写数据函数
  43. {
  44.         rs=1;
  45.         lcden=0;
  46.         P0=date;
  47.         delay(5);
  48.         lcden=1;
  49.         delay(5);
  50.         lcden=0;       
  51. }
  52. void write_sfm(uchar add,uchar date)//写时分秒函数
  53. {
  54.         uchar shi,ge;
  55.         shi=date/10;//分解一个2位数的十位和个位
  56.         ge=date%10;
  57.         write_com(0x80+0x40+add);//设置显示位置
  58.         write_date(0x30+shi);//送去液晶显示十位
  59.         write_date(0x30+ge); //送去液晶显示个位
  60. }
  61. void write_nyr(uchar add,uchar date)//写年月日函数
  62. {
  63.         uchar shi,ge;
  64.         shi=date/10;//分解一个2位数的十位和个位
  65.         ge=date%10;
  66.         write_com(0x80+add);//设置显示位置
  67.         write_date(0x30+shi);//送去液晶显示十位
  68.         write_date(0x30+ge); //送去液晶显示个位
  69. }
  70. void init()//初始化函数
  71. {
  72.         num=0;
  73.         rd=0;  
  74.         lcden=0;
  75.         fen=0; //初始化分变量值
  76.         miao=0;
  77.         shi=0;
  78.         nian=1;
  79.         yue=1;
  80.         ri=1;
  81.         zhou=0;
  82.         count=0;
  83.         s1num=0;
  84.         write_com(0x38);//初始化1602液晶
  85.         write_com(0x0c);
  86.         write_com(0x06);
  87.         write_com(0x01);
  88.         write_com(0x80+1);//设置显示初始坐标
  89.         write_date('2');
  90.         write_com(0x80+2 );
  91.         write_date('0');
  92.         write_com(0x80+0x40+6);//写出时间显示部分的两个冒号
  93.         write_date(':');
  94.         delay(5);
  95.         write_com(0x80+0x40+9);
  96.         write_date(':');
  97.         delay(5);
  98.         write_com(0x80+5);//写出时间显示部分的两个-
  99.         write_date('-');
  100.         delay(5);
  101.         write_com(0x80+8);
  102.         write_date('-');
  103.         delay(5);
  104.         write_com(0x80+12);
  105.         for(num=0;num<3;num++)
  106.         {
  107.                 write_date(yizhou[zhou][num]);
  108.                 delay(5);
  109.         }        
  110.         write_nyr(3,nian);
  111.         write_nyr(6,yue);
  112.         write_nyr(9,ri);
  113.         write_sfm(10,miao);
  114.         write_sfm(7,fen);
  115.         write_sfm(4,shi);
  116.         TMOD=0x01;//设置定时器0工作模式1
  117.         TH0=(65536-50000)/256;//定时器装初值
  118.         TL0=(65536-50000)%256;
  119.         EA=1;        //开总中断
  120.         ET0=1;        //开定时器0中断
  121.         TR0=1;        //启动定时器0
  122. }
  123. void keyscan()//按键扫描函数
  124. {
  125.         if(s1==0)       
  126.         {
  127.                 delay(5);
  128.                 if(s1==0)//确认功能键被按下
  129.                 {        s1num++;//功能键按下次数记录
  130.                         while(!s1);//释放确认
  131.                         di();//每当有按键释放蜂鸣器发出滴声
  132.                         if(s1num==1)//第一次被按下时
  133.                         {
  134.                                 TR0=0;  //关闭定时器
  135.                                 write_com(0x80+0x40+11);//光标定位到秒位置
  136.                                 write_com(0x0f); //光标开始闪烁
  137.                         }
  138.                         if(s1num==2)//第二次按下光标闪烁定位到分钟位置
  139.                         {
  140.                                 write_com(0x80+0x40+8);
  141.                         }
  142.                         if(s1num==3)//第三次按下光标闪烁定位到小时位置
  143.                         {
  144.                                 write_com(0x80+0x40+5);
  145.                         }
  146.                         if(s1num==4)//第四次按下光标闪烁定位到周位置
  147.                         {
  148.                                 write_com(0x80+14);
  149.                         }
  150.                         if(s1num==5)//第五次按下光标闪烁定位到日位置
  151.                         {
  152.                                 write_com(0x80+10);
  153.                         }
  154.                         if(s1num==6)//第六次按下光标闪烁定位到月位置
  155.                         {
  156.                                 write_com(0x80+7);
  157.                         }
  158.                         if(s1num==7)//第七次按下光标闪烁定位到年位置
  159.                         {
  160.                                 write_com(0x80+4);
  161.                         }
  162.                         if(s1num==8)//第八次按下
  163.                         {
  164.                                 s1num=0;//记录按键数清零
  165.                                 write_com(0x0c);//取消光标闪烁
  166.                                 TR0=1;        //启动定时器使时钟开始走
  167.                         }               
  168.                 }
  169.         }
  170.         if(s1num!=0)//只有功能键被按下后,增加和减小键才有效
  171.         {
  172.                 if(s2==0)
  173.                 {
  174.                         delay(5);
  175.                         if(s2==0)//增加键确认被按下
  176.                         {
  177.                                 while(!s2);//按键释放
  178.                                 di();//每当有按键释放蜂鸣器发出滴声
  179.                                 if(s1num==1)//若功能键第一次按下
  180.                                 {
  181.                                         miao++; //则调整秒加1
  182.                                         if(miao>=60)//若满60后将清零
  183.                                                 miao=0;
  184.                                         write_sfm(10,miao);//每调节一次送液晶显示一下
  185.                                         write_com(0x80+0x40+11);//显示位置重新回到调节处
  186.                                 }
  187.                                 if(s1num==2)//若功能键第二次按下
  188.                                 {
  189.                                         fen++;//则调整分钟加1
  190.                                         if(fen>=60)//若满60后将清零
  191.                                                 fen=0;
  192.                                         write_sfm(7,fen);//每调节一次送液晶显示一下
  193.                                         write_com(0x80+0x40+8);//显示位置重新回到调节处
  194.                                 }
  195.                                 if(s1num==3)//若功能键第三次按下
  196.                                 {
  197.                                         shi++;//则调整小时加1
  198.                                         if(shi>=24)//若满24后将清零
  199.                                                 shi=0;
  200.                                         write_sfm(4,shi);;//每调节一次送液晶显示一下
  201.                                         write_com(0x80+0x40+5);//显示位置重新回到调节处
  202.                                 }
  203.                                 if(s1num==4)//若功能键第四次按下
  204.                                 {       
  205.                                         zhou++;
  206.                                         if(zhou>=7)//若满7后将清零
  207.                                                 zhou=0;
  208.                                         write_com(0x80+12);//设置显示初始坐标
  209.                                         for(num=0;num<3;num++)
  210.                                         {
  211.                                                 write_date(yizhou[zhou][num]);
  212.                                                 delay(5);
  213.                                         }
  214.                                 }
  215.                                 if(s1num==5)//若功能键第二次按下
  216.                                 {
  217.                                         ri++;//则调整日加1
  218.                                         if((2000+nian)%400==0||(2000+nian)%4==0&&(2000+nian)%100!=0)
  219.                                         tian=ruinian[yue];
  220.                                         else nian=pingnian[yue];
  221.                                         if(ri>tian)
  222.                                                 ri=1;
  223.                                         write_nyr(9,ri);//每调节一次送液晶显示一下
  224.                                         write_com(0x80+10);//显示位置重新回到调节处
  225.                                 }
  226.                                 if(s1num==6)//若功能键第二次按下
  227.                                 {
  228.                                         yue++;//则调整月加1
  229.                                         if(yue>12)//若满12后将清零
  230.                                                 yue=1;
  231.                                         write_nyr(6,yue);//每调节一次送液晶显示一下
  232.                                         write_com(0x80+7);//显示位置重新回到调节处
  233.                                 }
  234.                                 if(s1num==7)//若功能键第二次按下
  235.                                 {
  236.                                         nian++;//则调整nian加1
  237.                                         if(nian>50)//若满50后将清零
  238.                                                 nian=0;
  239.                                         write_nyr(3,nian);//每调节一次送液晶显示一下
  240.                                         write_com(0x80+4);//显示位置重新回到调节处
  241.                                 }
  242.                         }
  243.                 }
  244.                 if(s3==0)
  245.                 {
  246.                         delay(5);
  247.                         if(s3==0)//确认减小键被按下
  248.                         {
  249.                                 while(!s3);//按键释放
  250.                                 di();//每当有按键释放蜂鸣器发出滴声
  251.                                 if(s1num==1)//若功能键第一次按下
  252.                                 {
  253.                                         miao--; //则调整秒加1
  254.                                         if(miao<0)//若满60后将清零
  255.                                                 miao=59;
  256.                                         write_sfm(10,miao);//每调节一次送液晶显示一下
  257.                                         write_com(0x80+0x40+11);//显示位置重新回到调节处
  258.                                 }
  259.                                 if(s1num==2)//若功能键第二次按下
  260.                                 {
  261.                                         fen--;//则调整分钟加1
  262.                                         if(fen<0)//若满60后将清零
  263.                                                 fen=59;
  264.                                         write_sfm(7,fen);//每调节一次送液晶显示一下
  265.                                         write_com(0x80+0x40+8);//显示位置重新回到调节处
  266.                                 }
  267.                                 if(s1num==3)//若功能键第三次按下
  268.                                 {
  269.                                         shi--;//则调整小时加1
  270.                                         if(shi<0)//若满24后将清零
  271.                                                 shi=23;
  272.                                         write_sfm(4,shi);;//每调节一次送液晶显示一下
  273.                                         write_com(0x80+0x40+5);//显示位置重新回到调节处
  274.                                 }
  275.                                 if(s1num==4)//若功能键第四次按下
  276.                                 {       
  277.                                         zhou--;
  278.                                         if(zhou<0)//若满7后将清零
  279.                                                 zhou=6;
  280.                                         write_com(0x80+12);//设置显示初始坐标
  281.                                         for(num=0;num<3;num++)
  282.                                         {
  283.                                                 write_date(yizhou[zhou][num]);
  284.                                                 delay(5);
  285.                                         }
  286.                                 }
  287.                                 if(s1num==5)//若功能键第二次按下
  288.                                 {
  289.                                         ri--;//则调整日加1
  290.                                         if((2000+nian)%400==0||(2000+nian)%4==0&&(2000+nian)%100!=0)
  291.                                         tian=ruinian[yue];
  292.                                         else nian=pingnian[yue];
  293.                                         if(ri<1)
  294.                                         ri=tian;
  295.                                         write_nyr(9,ri);//每调节一次送液晶显示一下
  296.                                         write_com(0x80+10);//显示位置重新回到调节处
  297.                                 }
  298.                                 if(s1num==6)//若功能键第二次按下
  299.                                 {
  300.                                         yue--;//则调整月加1
  301.                                         if(yue<1)//若满12后将清零
  302.                                                 yue=12;
  303.                                         write_nyr(6,yue);//每调节一次送液晶显示一下
  304.                                         write_com(0x80+7);//显示位置重新回到调节处
  305.                                 }
  306.                                 if(s1num==7)//若功能键第二次按下
  307.                                 {
  308.                                         nian--;//则调整nian加1
  309.                                         if(nian<0)//若满50后将清零
  310.                                                 nian=50;
  311.                                         write_nyr(3,nian);//每调节一次送液晶显示一下
  312.                                         write_com(0x80+4);//显示位置重新回到调节处
  313.                                 }
  314.                         }
  315.                 }
  316.         }
  317. }
  318. void main()//主函数
  319. {
  320.         init();//首先初始化各数据
  321.         while(1)//进入主程序大循环
  322.         {
  323.                 keyscan();//不停的检测按键是否被按下
  324.         }
  325. }
  326. void timer0() interrupt 1//定时器0中断服务程序
  327. {
  328.         TH0=(65536-50000)/256;//再次装定时器初值
  329.         TL0=(65536-50000)%256;
  330.         count++;                //中断次数累加
  331.         if(count==20) //20次50毫秒为1秒
  332.         {
  333.                 count=0;
  334.                 miao++;
  335.                 if(miao>=60)//秒加到60则进位分钟
  336.                 {
  337.                         miao=0;//同时秒数清零
  338.                         fen++;
  339.                         if(fen>=60)//分钟加到60则进位小时
  340.                         {
  341.                                 fen=0;//同时分钟数清零
  342.                                 shi++;
  343.                                 if(shi>=24)//小时加到24则小时清零
  344.                                 {
  345.                                         shi=0;
  346.                                         ri++;
  347.                                         zhou++;
  348.                                         if(zhou>6)//若满7后将清零
  349.                                                 zhou=0;
  350.                                         write_com(0x80+12);//设置显示初始坐标
  351.                                         for(num=0;num<3;num++)
  352.                                         {
  353.                                                 write_date(yizhou[zhou][num]);
  354.                                                 delay(5);
  355.                                         }
  356.                                         if((2000+nian)%400==0||(2000+nian)%4==0&&(2000+nian)%100!=0)
  357.                                         tian=ruinian[yue];
  358. ……………………

  359. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
DZZ.zip (81.76 KB, 下载次数: 62)

评分

参与人数 3黑币 +65 收起 理由
aoshibaku + 12 赞一个!
瘦成大鸡腿 + 3 很给力!
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

感动是一种养分 发表于 2018-5-12 11:10 | 显示全部楼层
资料无法下载
回复

使用道具 举报

无效楼层,该帖已经被删除
zdnf2333 发表于 2019-1-3 00:15 | 显示全部楼层
牛逼 完美的程序
回复

使用道具 举报

aoshibaku 发表于 2019-1-7 16:22 | 显示全部楼层
真的非常棒了,完美
回复

使用道具 举报

aoshibaku 发表于 2019-1-7 16:47 | 显示全部楼层
有个地方不对就是月不调整的话日只能调整为1或0,楼主看看能不能解决
回复

使用道具 举报

方山里 发表于 2019-1-10 12:19 | 显示全部楼层
很厉害的仿真
回复

使用道具 举报

MENGYANG123 发表于 2019-1-12 19:08 | 显示全部楼层
多谢!
回复

使用道具 举报

MENGYANG123 发表于 2019-1-12 19:08 | 显示全部楼层
谢谢  非常感谢
回复

使用道具 举报

lemon.mdx 发表于 2019-3-10 11:13
下了两次扣了两次也没下下来。

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

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51黑电子论坛单片机. 联系QQ:125739409;技术交流QQ群582644647

Powered by 单片机教程网

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