找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4369|回复: 3
打印 上一主题 下一主题
收起左侧

LED万年历制作AT89C51仿真

[复制链接]
跳转到指定楼层
楼主
静态显示万年历,需要的就赞一赞吧!


所有资料下载:
LED万年历的proteus仿真电路及C语言程序设计.zip (141.79 KB, 下载次数: 49)

单片机源程序:
  1. //Title:calendar
  2. #include <REGX51.H>
  3. #define uchar unsigned char
  4. #define uint     unsigned int
  5. sbit DATA=P1^2;            //数据(PA0)
  6. sbit SCK=P1^0;             //移位时钟(PA1)
  7. sbit RCK=P1^1;            //锁存时钟(PA2)
  8. sbit P20=P2^0;
  9. sbit P21=P2^1;
  10. sbit P33=P3^3;
  11. sbit  DS1302_CLK = P1^7;              //实时时钟时钟线引脚
  12. sbit  DS1302_IO  = P1^6;              //实时时钟数据线引脚
  13. sbit  DS1302_RST = P1^5;//实时时钟复位线引脚
  14. sbit  ACC0 = ACC^0;
  15. sbit  ACC7 = ACC^7;
  16. char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year;  //秒,分,时到日,月,年位闪的计数
  17. sbit Set = P3^0;       //模式切换键
  18. sbit Up = P3^1;        //加法按钮
  19. sbit Down = P3^2;      //减法按钮
  20. sbit out = P3^4;       //立刻跳出调整模式按钮

  21. char done,count,temp,flag,up_flag,down_flag;
  22. uchar DS1302[8]={4,5,6,7,8,6,9};  //秒,分,时,日,月,星期,年
  23. uint f;

  24. uchar t[14];
  25. uchar k;
  26. uchar code Seg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
  27. void display(uchar L1,uchar L2,uchar L3,uchar L4,uchar L5,uchar L6,uchar L7,uchar L8,
  28.   uchar L9,uchar L10,uchar L11,uchar L12,uchar L13,uchar L14);
  29. /***********DS1302时钟部分子程序******************/
  30. typedef struct __SYSTEMTIME__
  31. {
  32.         unsigned char Second;
  33.         unsigned char Minute;
  34.         unsigned char Hour;
  35.         unsigned char Week;
  36.         unsigned char Day;
  37.         unsigned char Month;
  38.         unsigned char  Year;
  39.         unsigned char DateString[14];
  40. }SYSTEMTIME;        //定义的时间类型
  41. SYSTEMTIME CurrentTime;



  42. #define DS1302_SECOND        0x81          //时钟芯片的寄存器位置,存放时间
  43. #define DS1302_MINUTE        0x83
  44. #define DS1302_HOUR                0x85
  45. #define DS1302_WEEK                0x8A
  46. #define DS1302_DAY                0x87
  47. #define DS1302_MONTH        0x89
  48. #define DS1302_YEAR                0x8D

  49. void DS1302InputByte(unsigned char d)         //实时时钟写入一字节(内部函数)
  50. {
  51.     unsigned char i;
  52.     ACC = d;
  53.     for(i=8; i>0; i--)
  54.     {
  55.         DS1302_IO = ACC0;                   //相当于汇编中的 RRC
  56.         DS1302_CLK = 1;
  57.         DS1302_CLK = 0;
  58.         ACC = ACC >> 1;
  59.     }
  60. }

  61. unsigned char DS1302OutputByte(void)         //实时时钟读取一字节(内部函数)
  62. {
  63.     unsigned char i;
  64.     for(i=8; i>0; i--)
  65.     {
  66.         ACC = ACC >>1;                                 //相当于汇编中的 RRC
  67.         ACC7 = DS1302_IO;
  68.         DS1302_CLK = 1;
  69.         DS1302_CLK = 0;//在下降沿数据从移位寄存器输出
  70.     }
  71.     return(ACC);
  72. }

  73. void Write1302(unsigned char ucAddr, unsigned char ucDa)        //ucAddr: DS1302地址, ucData: 要写的数据
  74. {
  75.     DS1302_RST = 0;
  76.     DS1302_CLK = 0;
  77.     DS1302_RST = 1;//只有在clk为低时,才能将rst置高
  78.     DS1302InputByte(ucAddr);               // 地址,命令
  79.     DS1302InputByte(ucDa);               // 写1Byte数据
  80.     DS1302_CLK = 1;//上升沿将数据写入DS1302内部移位寄存器
  81.     DS1302_RST = 0;
  82. }

  83. unsigned char Read1302(unsigned char ucAddr)        //读取DS1302某地址的数据
  84. {
  85.     unsigned char ucData;
  86.     DS1302_RST = 0;
  87.     DS1302_CLK = 0;
  88.     DS1302_RST = 1;//启动数据传送
  89.     DS1302InputByte(ucAddr|0x01);        // 地址,命令 ,读操作
  90.     ucData = DS1302OutputByte();         // 读1Byte数据,应在上升沿前读取
  91.     DS1302_CLK = 1;
  92.     DS1302_RST = 0;
  93.     return(ucData);
  94. }



  95. void DS1302_GetTime(SYSTEMTIME *Time)  //获取时钟芯片的时钟数据到自定义的结构型数组
  96. {
  97.         unsigned char ReadValue;
  98.         ReadValue = Read1302(DS1302_SECOND);
  99.         Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//16进制转为10进制
  100. ReadValue = Read1302(DS1302_MINUTE);
  101.         Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
  102.         ReadValue = Read1302(DS1302_HOUR);
  103.         Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
  104.         ReadValue = Read1302(DS1302_DAY);
  105.         Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);       
  106.         ReadValue = Read1302(DS1302_WEEK);
  107.         Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
  108.         ReadValue = Read1302(DS1302_MONTH);
  109.         Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
  110.         ReadValue = Read1302(DS1302_YEAR);
  111.         Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);       
  112. }
  113. void DateToStr(SYSTEMTIME *Time)    //将时间年,月,日,星期数据转换成液晶显示字符串,放到数组里DateString[]
  114. {   if(hide_year<5)                 //这里的if,else语句都是判断位闪烁,<2显示数据,>2就不显示,输出字符串为 2007/07/22
  115.     {                              
  116.           Time->DateString[0] = 2;
  117.           Time->DateString[1] = 0;         
  118.           Time->DateString[2] = Time->Year/10;
  119.           Time->DateString[3] = Time->Year%10;
  120.         }
  121.           else
  122.             {
  123.                               
  124.               Time->DateString[2] =10 ;
  125.               Time->DateString[3] =10 ;
  126.                 }

  127.         if(hide_month<5)
  128.         {
  129.           Time->DateString[4] = Time->Month/10;
  130.           Time->DateString[5] = Time->Month%10;
  131.         }
  132.           else
  133.           {
  134.             Time->DateString[4] =10;
  135.             Time->DateString[5] =10;
  136.           }

  137.         if(hide_day<5)
  138.         {
  139.           Time->DateString[6] = Time->Day/10;
  140.           Time->DateString[7] = Time->Day%10;
  141.         }
  142.           else
  143.           {
  144.             Time->DateString[6] =10;
  145.             Time->DateString[7] =10;            
  146.           }



  147.     if(hide_hour<5)
  148.     {
  149.           Time->DateString[8] = Time->Hour/10;
  150.           Time->DateString[9] = Time->Hour%10;
  151.         }
  152.           else
  153.             {
  154.               Time->DateString[8] =10;
  155.               Time->DateString[9] =10;
  156.                 }

  157.     if(hide_min<5)
  158.         {
  159.           Time->DateString[10] = Time->Minute/10;
  160.           Time->DateString[11] = Time->Minute%10;
  161.         }
  162.           else
  163.             {
  164.               Time->DateString[10] =10;
  165.               Time->DateString[11] =10;
  166.                }
  167.          
  168.     if(hide_sec<5)
  169.     {
  170.           Time->DateString[12] = Time->Second/10 ;
  171.           Time->DateString[13] = Time->Second%10 ;
  172.     }
  173.       else
  174.        {
  175.          Time->DateString[12] =10;
  176.              Time->DateString[13] =10;
  177.        }

  178. }
  179. void show_time()   //显示程序
  180. {     uchar i;
  181.    uchar j;
  182.   
  183. DS1302_GetTime(&CurrentTime);  //获取时钟芯片的时间数据
  184.      DateToStr(&CurrentTime);
  185.     for(j=0;j<14;j++)
  186. {t[j]=Seg[CurrentTime.DateString[13-j]];}
  187.    
  188.      RCK=0;//锁存置低

  189.       
  190. for(j=0;j<14;j++)
  191. {
  192.   for(i=0;i<8;i++)            
  193.        {
  194.        SCK=0;           //移位脉冲置低
  195.        DATA=t[j]&0x80;
  196.        t[j]=t[j]<<1;
  197.        SCK=1;//上升沿时数据寄存器的数据移位
  198.            }
  199.       }
  200.             
  201.       
  202.   RCK=1;    //上升沿时移位寄存器的数据进入数据存储寄存器           
  203.       
  204. }

  205. /*延时子程序*/
  206. void mdelay(uint delay)
  207. {        uint i;
  208.         for(;delay>0;delay--)
  209.                    {for(i=0;i<62;i++) //1ms延时.
  210.                        {;}
  211.                    }
  212. }


  213. void outkey()                    //跳出调整模式,返回默认显示
  214. { uchar Second;
  215.   if(out==0)         
  216.   { mdelay(8);
  217.         count=0;
  218.         hide_sec=0,hide_min=0,hide_hour=0,hide_day=0,hide_week=0,hide_month=0,hide_year=0;
  219.         Second=Read1302(DS1302_SECOND);

  220.         Write1302(0x80,Second&0x7f);

  221.         done=0;           
  222.         while(out==0);

  223.   }
  224. }
  225. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  226. void Upkey()//升序按键
  227. {          
  228.                 Up=1;
  229.                 if(Up==0)
  230.                           {
  231.                                    mdelay(8);

  232.                                        switch(count)
  233.                                           {/*case 1:
  234.                                   temp=Read1302(DS1302_SECOND);  //读取秒数
  235.                                                                   temp=temp+1;  //秒数加1
  236.                                   up_flag=1;    //数据调整后更新标志
  237.                                                                   if((temp&0x7f)>0x59)   //超过59秒,清零
  238.                                   temp=0;                                                                  
  239.                                                                   break;*/
  240.                                            case 2:
  241.                                   temp=Read1302(DS1302_MINUTE);  //读取分数
  242.                                                                   temp=temp+1;  //分数加1
  243.                                   up_flag=1;
  244.                                                                 if((temp&0x0F)>9)temp=temp+6;
  245.                                 if(temp>=0x60) temp=0;
  246.                                                                   break;
  247.                                            case 3:
  248.                                   temp=Read1302(DS1302_HOUR);  //读取小时数
  249.                                                                   temp=temp+1;  //小时数加1
  250.                                  if((temp&0x0F)>9)temp=temp+6;
  251.                                  if(temp>=0x24) temp=0;
  252.                                   up_flag=1;
  253.                                                                   
  254.                                                                   break;
  255.                                           
  256.                                            case 4:
  257.                                   temp=Read1302(DS1302_DAY);  //读取日数
  258.                                                                   temp=temp+1;  //日数加1
  259.                                   up_flag=1;
  260.                                                                   if((temp&0x0F)>9)temp=temp+6;
  261.                                  if(temp>=0x32) temp=1;
  262.                                                                   break;
  263.                                            case 5:
  264.                                   temp=Read1302(DS1302_MONTH);//  读取月数
  265.                                                                   temp=temp+1;  //月数加1
  266.                                   up_flag=1;
  267.                                                                    if((temp&0x0F)>9)temp=temp+6;
  268.                                  if(temp>=0x13) temp=1;
  269.                                                                   break;
  270.                                            case 6:
  271.                                   temp=Read1302(DS1302_YEAR);  //读取年数
  272.                                                                   temp=temp+1;  //年数加1
  273.                                   up_flag=1;
  274.                                                                  if((temp&0x0F)>9)temp=temp+6;
  275.                                  if(temp>=0xA0) temp=0;
  276.                                                                   break;
  277.                                                default:break;
  278.                                           }
  279.                                           
  280.                                    while(Up==0);
  281.                    
  282.                                   }
  283. }

  284. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  285. void Downkey()//降序按键
  286. {            
  287.                 Down=1;
  288.             if(Down==0)
  289.                           {
  290.                                    mdelay(8);
  291.                                      switch(count)
  292.                                           {/*case 1:
  293.                                   temp=Read1302(DS1302_SECOND);  //读取秒数
  294.                                                                   temp=temp-1;                                                    //秒数减1
  295.                                   down_flag=1;       //数据调整后更新标志
  296.                                                                   if(temp==0x7f)     //小于0秒,返回59秒
  297.                                                                   temp=0x59;
  298.                                                                   break;*/
  299.                                            case 2:
  300.                                   temp=Read1302(DS1302_MINUTE);  //读取分数
  301.                                                                   temp=temp-1;  //分数减1
  302.                                   down_flag=1;
  303.                                                                  if((temp&0x0F)>9)temp=temp-6;
  304.                                  if(temp==0) temp=0x59;
  305.                                                                   break;
  306.                                            case 3:
  307.                                   temp=Read1302(DS1302_HOUR);  //读取小时数
  308.                                                                   temp=temp-1;  //小时数减1
  309.                                   down_flag=1;
  310.                                                                   if((temp&0x0F)>9)temp=temp-6;
  311.                                  if(temp==0) temp=0x59;
  312.                                                                   break;
  313.                                           
  314.                                            case 4:
  315.                                   temp=Read1302(DS1302_DAY);  //读取日数
  316.                                                                   temp=temp-1;  //日数减1
  317.                                   down_flag=1;
  318.                                                                   if((temp&0x0F)>9)temp=temp-6;
  319.                                  if(temp==0) temp=0x31;
  320.                                                                   break;
  321.                                            case 5:
  322.                                   temp=Read1302(DS1302_MONTH);  //读取月数
  323.                                                                   temp=temp-1;  //月数减1
  324.                                   down_flag=1;
  325.                                                                  if((temp&0x0F)>9)temp=temp-6;
  326.                                  if(temp==0) temp=0x12;
  327.                                                                   break;
  328.                                            case 6:
  329.                                   temp=Read1302(DS1302_YEAR);  //读取年数
  330.                                                                   temp=temp-1;  //年数减1
  331.                                   down_flag=1;
  332.                                                                   if((temp&0x0F)>9)temp=temp-6;
  333.                                  if(temp==0) temp=0x50;
  334.                                                                   break;
  335.                                               default:break;
  336.                                          }
  337.                                          
  338.                                    while(Down==0);
  339.                                     
  340.                                   }
  341. }

  342. void Setkey()//模式选择按键
  343. {
  344.                 Set=1;
  345.                 if(Set==0)//有按键按下
  346.             {
  347.            mdelay(8);
  348.            count=count+1;         //Setkey按一次,count就加1
  349.                    done=1;                         //进入调整模式
  350.            while(Set==0);
  351.            
  352.                  }

  353. }

  354. void keydone()//按键功能执行
  355. {        uchar Second;
  356.                  if(flag==0)    //关闭时钟,停止计时
  357.          {
  358.            temp=Read1302(0x81);
  359.            Write1302(0x80,temp|0x80);//ch=1,时钟振荡停止
  360.                
  361.            flag=1;
  362.          }
  363.          Setkey();                                            //扫描模式切换按键
  364.                  switch(count)
  365.                  {case 1:do                                                //count=1,调整秒
  366.                           {
  367.                    outkey();                           //扫描跳出按钮
  368.                                    Upkey();                //扫描加按钮
  369.                                    Downkey();              //扫描减按钮
  370.                                    if(up_flag==1||down_flag==1)  //数据更新,重新写入新的数据
  371.                                    {
  372.                                     
  373.                                    Write1302(0x80,temp|0x80); //写入新的秒数
  374.                                     
  375.                                    up_flag=0;
  376.                                    down_flag=0;
  377.                                    }

  378.                                    hide_sec++;          //位闪计数
  379.                                    if(hide_sec>9)
  380.                                      hide_sec=0;
  381.                    show_time();         //液晶显示数据
  382.                                   }while(count==2);break;  
  383.                   case 2:do                                                //count=2,调整分
  384.                           {
  385.                                    hide_sec=0;
  386.                                    outkey();
  387.                                    Upkey();
  388.                                    Downkey();
  389.                                    if(temp>0x59)
  390.                                     temp=0;
  391.                                    if(up_flag==1||down_flag==1)
  392.                                    {
  393.                                  
  394.                                    Write1302(0x82,temp); //写入新的分数
  395.                                   
  396.                                    up_flag=0;
  397.                                    down_flag=0;
  398.                                    }
  399.                                    hide_min++;
  400.                                    if(hide_min>9)
  401.                                      hide_min=0;
  402.                    show_time();
  403.                                   }while(count==3);break;
  404.                   case 3:do                                                //count=3,调整小时
  405.                           {
  406.                    hide_min=0;
  407.                                    outkey();
  408.                                    Upkey();
  409.                                    Downkey();
  410.                                    if(up_flag==1||down_flag==1)
  411.                                    {
  412.                                   
  413.                                    Write1302(0x84,temp); //写入新的小时数
  414.                                   
  415.                                    up_flag=0;
  416.                                    down_flag=0;
  417.                                    }
  418.                                    hide_hour++;
  419.                                    if(hide_hour>9)
  420.                                      hide_hour=0;
  421.                    show_time();
  422.                                   }while(count==4);break;
  423.          
  424.                   case 4:do                                                //count=5,调整日
  425.                           {
  426.                                    hide_hour=0;
  427.                                    outkey();
  428.                                    Upkey();
  429.                                    Downkey();
  430.                                    if(up_flag==1||down_flag==1)
  431.                                    {
  432.                                     
  433.                                    Write1302(0x86,temp); //写入新的日数
  434.                                   
  435.                                    up_flag=0;
  436.                                    down_flag=0;
  437.                                    }
  438.                                    hide_day++;
  439.                                    if(hide_day>9)
  440.                                      hide_day=0;
  441.                    show_time();
  442.                                   }while(count==5);break;
  443.                   case 5:do                                                //count=6,调整月
  444.                           {
  445.                    hide_day=0;
  446.                                    outkey();
  447.                                    Upkey();
  448.                                    Downkey();
  449.                                    if(up_flag==1||down_flag==1)
  450.                                    {
  451.                                   
  452.                                    Write1302(0x88,temp); //写入新的月数
  453.                                   
  454.                                    up_flag=0;
  455.                                    down_flag=0;
  456.                                    }
  457.                                    hide_month++;
  458.                                    if(hide_month>9)
  459.                                      hide_month=0;
  460.                    show_time();
  461.                                   }while(count==6);break;
  462.                   case 6:do                                                //count=7,调整年
  463.                           {
  464.                    hide_month=0;
  465.                                    outkey();
  466.                                    Upkey();
  467.                                    Downkey();
  468.                                    if(up_flag==1||down_flag==1)
  469.                                    {
  470.                                    Write1302(0x8c,temp); //写入新的年数
  471.                                  
  472.                                    up_flag=0;
  473.                                    down_flag=0;
  474.                                    }
  475.                                    hide_year++;
  476.                                    if(hide_year>9)
  477.                                      hide_year=0;
  478.                    show_time();
  479.                                   }while(count==7);break;
  480.                   case 7: count=0;hide_year=0;  //count7, 跳出调整模式,返回默认显示状态
  481.                       Second=Read1302(DS1302_SECOND);
  482.                   
  483.                       Write1302(0x80,Second&0x7f);//ch=0时,时钟启动
  484.                       
  485.                                   done=0;
  486.                   break; //count=7,开启中断,标志位置0并退出
  487.                   default:break;

  488.                  }

  489. }



  490. main()
  491. {   
  492.    uchar i;
  493. flag=1;           //时钟停止标志
  494. up_flag=0;
  495.         down_flag=0;
  496.         done=0;           //进入默认显示
  497. for(i=0;i<=6;i++)  
  498. Write1302(0x80+2*i,DS1302[i]);  


  499.         while(1)
  500.         {   
  501.         P33=0;
  502.   while(done==1)
  503.           keydone();    //进入调整模式

  504.         while(done==0)
  505.             {
  506.           show_time();                 
  507.             flag=0;                  
  508.                       Setkey();                                 //扫描各功能键
  509.                 }
  510. }
  511. }

复制代码


评分

参与人数 2黑币 +58 收起 理由
slhslhhao + 8 共享资料的黑币奖励!
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶2 踩
回复

使用道具 举报

沙发
ID:140183 发表于 2018-1-19 22:06 | 只看该作者
很好!太谢谢啦!!!!!!!!
回复

使用道具 举报

板凳
ID:274729 发表于 2018-1-21 00:24 | 只看该作者
怎么下载了不是压缩包,是php文件
回复

使用道具 举报

地板
ID:198161 发表于 2018-6-12 15:48 | 只看该作者
新手看帖、膜拜一个
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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