找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于51单片机LCD12864大字符校时万年历带高考倒计时程序

  [复制链接]
跳转到指定楼层
楼主
基于51单片机LCD12864大字符校时万年历带高考倒计时程序,感觉不错就分享给大家。

全部源码下载:
基于51单片机LCD12864大字符校时万年历带高考倒计时程序.zip (258.11 KB, 下载次数: 121)



主程序预览:
  1. /*---------------------------------------------------------------------------
  2.         电子时钟程序
  3.         单 片 机:STC89C58RC
  4.         晶    振:12MHz
  5.         时钟芯片:DS1302
  6.         液 晶 屏:LCM-12864-ST7920
  7.         功能描述: 大数字显示时间;能显示农历、设置闹铃;
  8.         说          明:LCM12864使用并口连接方式,PSB、RST接高电平

  9. ------------------------------------------------------------------------------*/

  10. /*-------------------------------头文件---------------------------------------*/
  11. #include <reg52.h>
  12. #include <intrins.h>
  13. #include "LCD12864.h"
  14. #include "DS1302.h"
  15. #include "nongli.h"
  16. #include "displaytime.h"
  17. #include "zk.h"
  18. #include "bell.h"
  19. #include "HW.H"
  20. #include "delay.h"
  21. #include "DS18B20.h"
  22. #define uint  unsigned int
  23. #define uchar unsigned char

  24. /*--------------------定义按键-----------------------------------------------*/
  25. sbit K1  = P2^3; //K1-设置
  26. sbit K2  = P2^4; //K2-确认、返回
  27. sbit K3  = P2^5; //K3-加
  28. sbit K4  = P2^6; //K4-减
  29. sbit K5  = P2^7; //K5-控制闹钟的打开与关闭,在"hw.h"中定义
  30. sbit K6  = P2^2; //背光控制
  31. sbit LED = P2^0; //背光灯
  32. /*---------------------函数声明------------------------------*/             
  33. void ds_w(void);
  34. void Conver_week(bit c,uchar year,uchar month,uchar day);
  35. /*-----------------------------定义全局变量------------------------------*/
  36. bit  w=0;    //调时标志位

  37. unsigned char yy,mo,dd,xq,hh,mm,ss,month_moon,day_moon,week,tiangan,dizhi,moontemp1,moontemp2;//定义时间映射全局变量(专用寄存器)
  38. signed char address,item,item0,max,mini;
  39. unsigned char clk_ala[2]={0x05,0x2f};//闹钟数据存放初,始值为05:27
  40. unsigned char zwc=0,fwc=0,CKTIME_1=0,timp,timp0,timp1,timp2,hhh,mmm,sss;//用于校时
  41. unsigned char hour=0,minute=0,time=0;//用于闹铃的设置
  42. unsigned char gCount;


  43. /*-----------------------------调整界面设置函数-----------------------------*/

  44. void tiaozheng(void){
  45.         yy = read_clock(0x8d);//调用1302时钟数据中的年数据,从地址0x8d中
  46.         mo = read_clock(0x89);//调用1302时钟数据中的月数据,从地址0x89中
  47.         dd = read_clock(0x87);//从1302芯片中读取日数据,从地址0x87中
  48.         week = read_clock(0x8b);//从1302芯片中读取星期数据,从地址0x8b中
  49.         //----------------------------------
  50.         lcm_w_test(0,0x80);
  51.         lcm_w_word("20");
  52.         lcm_w_test(1,(yy/16)+0x30);
  53.         lcm_w_test(1,yy%16+0x30);
  54.         lcm_w_word("-");
  55.         //----------------------------------
  56.         lcm_w_test(1,(mo/16)+0x30);
  57.         lcm_w_test(1,mo%16+0x30);
  58.         lcm_w_word("-");
  59.         //----------------------------------
  60.         lcm_w_test(1,(dd/16)+0x30);
  61.         lcm_w_test(1,dd%16+0x30);
  62.         //----------------------------------
  63.         if(read_clock(0x85) != hh){hh = read_clock(0x85);}
  64.         lcm_w_test(0,0x88);
  65.         lcm_w_test(1,(hh/16)+0x30);
  66.         lcm_w_test(1,hh%16+0x30);
  67.         lcm_w_word(":");
  68.         //----------------------------------
  69.         if(read_clock(0x83) != mm){mm = read_clock(0x83);}
  70.         lcm_w_test(1,(mm/16)+0x30);//向液晶写数据,显示分钟的十位数
  71.         lcm_w_test(1,mm%16+0x30);//向液晶写数据,显示分钟的个位数
  72.         lcm_w_word(":");
  73.         //----------------------------------
  74.         if(read_clock(0x81) != ss){ss = read_clock(0x81);}
  75.         lcm_w_test(1,(ss/16)+0x30);
  76.         lcm_w_test(1,ss%16+0x30);

  77.         //=========显示设置闹钟的时间===================       
  78.         if(read_clock(0xc7) != hour){hour = read_clock(0xc7);}
  79.         if(read_clock(0xc9) != minute){minute = read_clock(0xc9);}
  80.         lcm_w_test(0,0x8d);
  81.         lcm_w_test(1,(hour/16)+0x30);//显示闹钟小时十位
  82.         lcm_w_test(1,(hour%16)+0x30);//显示闹钟小时个位
  83.           lcm_w_word(":");
  84.         lcm_w_test(1,(minute/16)+0x30);//显示闹钟分钟的十位
  85.         lcm_w_test(1,(minute%16)+0x30);//显示闹钟分钟的个位

  86.         //=========显示设置时间校正===================       
  87.         if(read_clock(0xc5) != zwc){zwc = read_clock(0xc5);}         //加减标志
  88.         if(read_clock(0xc3) != fwc){fwc = read_clock(0xc3);} //调整多少秒
  89.         lcm_w_test(0,0x90);
  90.         lcm_w_word("每天零点时");
  91.         lcm_w_test(0,0x95);       
  92.         if(zwc==0){lcm_w_word("加");}
  93.         if(zwc==1){lcm_w_word("减");}
  94.         lcm_w_test(0,0x96);       
  95.         lcm_w_test(1,(fwc/16)+0x30);
  96.         lcm_w_test(1,(fwc%16)+0x30);
  97.     lcm_w_test(0,0x97);       
  98.         lcm_w_word("秒");
  99. }

  100. void displayNaozh()                  //闹钟显示
  101. {   
  102.         if(read_clock(0xc7) != hour){       
  103.                 hour = read_clock(0xc7);
  104.         }
  105.         if(read_clock(0xc9) != minute){       
  106.                 minute = read_clock(0xc9);
  107.         }
  108.         lcm_w_test(0,0x85);
  109.         lcm_w_test(1,(hour/16)+0x30);//显示小时十位
  110.         lcm_w_test(1,(hour%16)+0x30);//显示小时个位
  111.           lcm_w_word(":");
  112.         lcm_w_test(1,(minute/16)+0x30);//显示分钟的十位
  113.         lcm_w_test(1,(minute%16)+0x30);//显示分钟的个位
  114.         lcm_w_word(" ");
  115. }

  116. void ds_w(void)                 //被调数据加一或减一,并检查数据范围,写入1302指定地址保存
  117. {
  118.         item0=time;
  119.         item=((read_clock(address+1))/16)*10 + (read_clock(address+1))%16;//时间的调整
  120.         if(K3 == 0||key_add==1){//如果按动上调键
  121.          item++;//数加 1  
  122.         }
  123.         if(K4 == 0||key_minish==1){//如果按动下调键
  124.            item--;//数减 1
  125.         }
  126.         if(item>max)  item=mini;//查看数值是否在有效范围之内   
  127.         if(item<mini) item=max;//如果数值小于最小值,则自动等于最大值           
  128.         write_clock(0x8e,0x00);//允许写1302芯片操作
  129.         write_clock(address,(item/10)*16+item%10);//转换成16进制写入1302
  130.         write_clock(0x8e,0x80);//写保护,禁止写操作
  131.         time=item0;//调整后的时间重新赋值给time(Tt为Hh或Mm),这步很重要,没有将无法更新闹钟数据
  132. }
  133. /**********************************************************************************************************/
  134. void Set_time(unsigned char sel){
  135. //根据选择调整的相应项目加1并写入DS1302,函数参数是按动设置键的次数
  136.         write_com(0x30); write_com(0x06);
  137.         lcm_w_test(0,0x98);
  138.         lcm_w_word("调整>");//调用字符显示函数,显示 调整字样
  139.   
  140. //================================================================
  141.         lcm_w_test(0,0x9c);
  142.         if(sel==9)  {lcm_w_word("调整多少");address=0xc2; max=29;mini=0;
  143.      tiaozheng();
  144.      ds_w();
  145.      tiaozheng();
  146.           }                                    //按动10次显示 调整多少秒
  147.         if(sel==8)  {lcm_w_word("加减调整");address=0xc4;max=1;mini=0;          
  148.          tiaozheng();                        //显示调整前的内容
  149.      ds_w();                             //设置闹钟
  150.      tiaozheng();                        //显示调整后的内容                                            
  151.           }                                    //按动9次显示 快还是慢
  152. //================================================================
  153.         lcm_w_test(0,0x9c);
  154.         if(sel==7)  {lcm_w_word("闹钟分钟");address=0xc8;max=59;mini=0;          //数据写入1302芯片的写入地址是0xc8,最大值是59,最小值是0
  155.          tiaozheng();                        //显示调整前的内容
  156.      ds_w();                             //设置闹钟
  157.      tiaozheng();                        //显示调整后的内容                                            
  158.           }                                    //按动8次显示 调整闹钟的分钟部分
  159.         if(sel==6)  {lcm_w_word("闹钟小时");address=0xc6; max=23;mini=0;
  160.      tiaozheng();
  161.      ds_w();
  162.      tiaozheng();
  163.           }                                    //按动7次显示 调整闹钟的小时部分
  164. //================================================================

  165.         if(sel==5)  {lcm_w_word("调整秒钟");address=0x80; max=59;mini=0;          
  166.         tiaozheng();
  167.            ds_w();               
  168.            tiaozheng();
  169.         }
  170.         if(sel==4)  {lcm_w_word("调整分钟");address=0x82; max=59;mini=0;
  171.            tiaozheng();
  172.            ds_w();
  173.            tiaozheng();
  174.         }
  175.         if(sel==3)  {lcm_w_word("调整小时");address=0x84; max=23;mini=0;
  176.   
  177.             tiaozheng();
  178.            ds_w();
  179.            tiaozheng();
  180.         }
  181.         if(sel==2)  {lcm_w_word("调整日期");address=0x86;
  182.                 mo = read_clock(0x89);//读月数据
  183.                 moontemp1=mo/16;
  184.                 moontemp2=mo%16;
  185.                 mo=moontemp1*10+moontemp2;//转换成10进制月份数据

  186.         yy = read_clock(0x8d);//读年数据
  187.         moontemp1=yy/16;
  188.                 moontemp2=yy%16;
  189.                 yy=moontemp1*10+moontemp2;//转换成10进制年份数据

  190.       if(mo==2&&yy%4!=0){max=28;mini=1;}//平年2月28天
  191.                 if(mo==2&&yy%4==0){max=29;mini=1;}//闰年2月29天
  192.                 if(mo==1||mo==3||mo==5||mo==7||mo==8||mo==10||mo==12){max=31;mini=1;}//31天的月份
  193.                 if(mo==4||mo==6||mo==9||mo==11){max=30;mini=1;}//30天的月份
  194.                 tiaozheng();
  195.                 ds_w();
  196.                 tiaozheng();

  197.   }
  198.   if(sel==1)  {lcm_w_word("调整月份");address=0x88; max=12;mini=1;
  199.      tiaozheng();
  200.      ds_w();
  201.      tiaozheng();
  202.   
  203.    }
  204.   if(sel==0)  {lcm_w_word("调整年份");address=0x8c; max=99; mini=0;
  205.          tiaozheng();
  206.      ds_w();       
  207.      tiaozheng();
  208.    }
  209. }
  210. //------------------------------------------------------
  211. void BiasAmend()        //时间修正函数
  212. {
  213.         hhh = (read_clock(0x85)/16)*10+read_clock(0x85)%16;
  214.     mmm = (read_clock(0x83)/16)*10+read_clock(0x83)%16;
  215.     sss = (read_clock(0x81)/16)*10+read_clock(0x81)%16;
  216.     timp0= 30+((fwc/16)*10+fwc%16);
  217.         timp= 30-((fwc/16)*10+fwc%16);
  218.         if((hhh==0)&&(mmm==1)&&(sss==0)){CKTIME_1=0;}
  219.                 if((hhh==0)&&(mmm==0)&&(sss==30)&&CKTIME_1==0)
  220.                         {
  221.         if(        zwc==0)                                                                   //加调整
  222.             {                                                
  223.                         write_clock(0x8e,0x00);           //允许写操作
  224.                         write_clock(0x80,(timp0/10)*16+timp0%10);    //对秒进行调整。
  225.                         write_clock(0x8e,0x80);           //禁止写操作       
  226.                         CKTIME_1=1;                                            //保证只调整一次
  227.                 }                                 
  228.         if(        zwc==1)                                                    //减调整
  229.                 {       
  230.                     write_clock(0x8e,0x00);           //允许写操作
  231.                         write_clock(0x80,(timp/10)*16+timp%10);     //对秒进行调整
  232.                         write_clock(0x8e,0x80);           //禁止写操作
  233.                         CKTIME_1=1;                                           //保证只调整一次
  234.                 }                                                                                  
  235.         }
  236. }
  237. // -----------------------------------------------------
  238. void naozbiaoz()        //闹钟标志函数
  239. {
  240.                 if(read_clock(0xcb) != ala_flag){ala_flag = read_clock(0xcb);}         //闹钟标志
  241.                 if(ala_flag==1)                            //闹钟标志位
  242.                         {set1616pic(5,1,0,2);}                //显示"喇叭"
  243.             else
  244.                         {set1616pic(5,1,0,1);}        //关闭"喇叭"显示

  245. }


  246. /*********************************************************************
  247. **********************************************************************
  248. **************             主函数                                  ****************
  249. **********************************************************************
  250. /********************************************************************/
  251. void main()
  252. {       
  253.         unsigned char ala_flag=1,e=0,f=0;                     

  254.     IE = 0x81;    //允许总中断中断,使能 INT0 外部中断
  255.     TCON = 0x01;  //触发方式为脉冲负边沿触发   
  256.     IRIN=1;       //IO口初始化
  257.     BEEP=1;
  258.         K1=1;K2=1;K3=1;K4=1;LED=0;
  259.        
  260.         Init_1302();                //时钟芯片初始化
  261.         lcm_init();                        //液晶初始化

  262.         welcome0();  //调用欢迎信息1
  263.         DelayM(1000);//延时

  264.         lcm_clr();            //清屏
  265.         Clean_12864_GDRAM();         //清屏

  266.         while(1)
  267.         {
  268.                 if (w == 0)                  //正常走时
  269.                 {       
  270.             hhh = (read_clock(0x85)/16)*10+read_clock(0x85)%16;
  271.         mmm = (read_clock(0x83)/16)*10+read_clock(0x83)%16;
  272.         sss = (read_clock(0x81)/16)*10+read_clock(0x81)%16;
  273.             clk_ala[0]=(read_clock(0xc7)/16)*10+read_clock(0xc7)%16;       
  274.             clk_ala[1]=(read_clock(0xc9)/16)*10+read_clock(0xc9)%16;        

  275.                 if ((sss==1)||(sss==2)||(sss==5)||(sss==6)||(sss==9)||(sss==10)||(sss==13)||(sss==14)||(sss==17)||(sss==18)||(sss==21)||(sss==22)||(sss==25)||(sss==26)||(sss==29)||(sss==30)||(sss==33)||(sss==34)||(sss==37)||(sss==38)||(sss==41)||(sss==42)||(sss==45)||(sss==46)||(sss==49)||(sss==50)||(sss==53)||(sss==54)||(sss==57)||(sss==58))
  276.                     {displaydate(); displayJr(); displayNaozh(); }  //显示日期           显示农历    显示闹钟
  277.                 if ((sss==3)||(sss==4)||(sss==7)||(sss==8)||(sss==11)||(sss==12)||(sss==15)||(sss==16)||(sss==19)||(sss==20)||(sss==23)||(sss==24)||(sss==27)||(sss==28)||(sss==31)||(sss==32)||(sss==35)||(sss==36)||(sss==39)||(sss==40)||(sss==43)||(sss==44)||(sss==47)||(sss==48)||(sss==51)||(sss==52)||(sss==55)||(sss==56)||(sss==59)||(sss==0))
  278.                         {displaynl(); displayGK();{read_temp();        ds1820disp(); }  //显示农历         显示高考         //读取温度            //显示温度

  279.                         displaytime();         //显示时间
  280.                         naozbiaoz();        // 闹钟标志
  281.                         displayxq();         //显示星期
  282.                         BiasAmend(); //时间校正函数

  283.                 }       


  284.                 //=================以下是闹钟的相关处理===================

  285.            if((clk_ala[0]==hhh)&&(clk_ala[1]==mmm)&&(sss<10)&&(ala_flag==1))
  286.                            { alarmbeep();DelayM(200);}
  287.                     //{        BEEP=0;}
  288.                         else BEEP=1;
  289.                
  290.                 }                           
  291.             else {} //========否则启动调时=========================
  292.          
  293.    
  294. /*---------------按键及红外遥控设置时间------------------------------*/               
  295.                 if (K1 == 0||key_manue==1)         
  296.                 {                 
  297.                        
  298.                         DelayM(8);                       //按键消抖
  299. /*当是调时状态 本键用于调整下一项---------------------------------------------------*/               
  300.                         if((K1 == 0 && w == 1)||(key_manue==1&&w==1))      //
  301.                         {
  302.                                        
  303.                                 e++;
  304.                                 if (e >= 10 ) {e = 0;}
  305.                              while(! K1 );            //等待键松开
  306.                           key_manue=0;
  307.                                 Set_time(e); beep();          //调整                               
  308.                         }
  309. /*当是正常状态时就进入调时状态---------------------------------------------------*/               
  310.                         if((K1 == 0 && w == 0)||(key_manue==1&&w==0))  //
  311.                         {       
  312.                                 key_manue=0;
  313.                                 lcm_clr();            
  314.                                 Clean_12864_GDRAM();   //清屏
  315.                                 w=1;                       //进入调时
  316.                                 Set_time(e);beep();
  317.                         }
  318.                         key_manue=0;
  319.                            while(K1 == 0);            //等待键松开
  320.                 }
  321. /*当在调时状态时就退出调时---------------------------------------------------*/               
  322.                 if (K2 == 0||key_ok==1)                   //
  323.                 {        beep();
  324.                         DelayM(8);
  325.                         if((K2 == 0 && w == 1)||(key_ok==1&&w==1))
  326.                         {                       
  327.                                 w = 0;                       //退出调时
  328.                                 e = 0;                           //"下一项"计数器清0       
  329.                                 lcm_clr();            //清屏
  330.                     Clean_12864_GDRAM();         //清屏
  331.                         }
  332.                 }
  333. /*加调整--------------------------------------------------------------------*/               
  334.                 if ((K3 == 0 && w == 1)||(key_add==1&&w==1))
  335.                 {        
  336.                          DelayM(8);
  337.                         if((K3 == 0 && w == 1)||(key_add==1&&w==1))
  338.                                 {
  339.                                   Set_time(e);
  340.                                   beep();
  341.                                   while(!K3);
  342.                                   key_add=0;
  343.                                 }
  344.                         key_add=0;
  345.                         while(! K3 );
  346.                 }
  347. /*减调整--------------------------------------------------------------------*/               
  348.                 if ((K4 == 0 && w == 1)||(key_minish==1&&w==1))
  349.                 {             
  350.                         DelayM(10);          
  351.                         if((K4 == 0 && w == 1)||(key_minish==1&&w==1))
  352.                           {
  353.                                 Set_time(e);
  354.                             beep();
  355.                                 while(! K4 );
  356.                                 key_minish=0;
  357.                           }
  358.                         key_minish=0;
  359.                         while(! K4 );
  360.                 }
  361. /*----------------------------------------------------------------*/
  362.          if(K5 == 0 )//闹钟的开与关的设置标志位
  363.            {
  364.                 DelayM(20);
  365.                 if(K5 == 0 )
  366.                   { beep();
  367.                         while(!K5);//松手检测
  368.                         ala_flag=!ala_flag;
  369.                         if(ala_flag==0)
  370.                         {
  371.                         write_clock(0x8e,0x00);//允许写1302芯片操作
  372.                 write_clock(0xca,0x00);//转换成16进制写入1302
  373.                 write_clock(0x8e,0x80);//写保护,禁止写操作
  374.                         }
  375.                         if(ala_flag==1)
  376.                         {
  377.                         write_clock(0x8e,0x00);//允许写1302芯片操作
  378.                 write_clock(0xca,0x01);//转换成16进制写入1302
  379.                 write_clock(0x8e,0x80);//写保护,禁止写操作
  380.                         }
  381.                   }
  382.                     while(!K5);//松手检测
  383.                         key_alarm=0;       
  384.            }
  385. /*----------------------------------------------------------------*/
  386.         if(K6 == 0)       
  387.                 {
  388.                 DelayM(20);
  389.                 if(K6 == 0 )
  390.                   { beep();
  391.                         while(!K6);//松手检测
  392.                          LED=!LED;
  393.                           gCount = 0;
  394.                   }
  395.                     while(!K6);//松手检测
  396.            }
  397.        
  398.         }
  399.   
  400. }


  401. /*结束----------------------------------------------------------------------*/
复制代码




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

使用道具 举报

沙发
ID:741842 发表于 2020-4-30 16:58 | 只看该作者
你好,有硬件电路图吗?
回复

使用道具 举报

板凳
ID:741842 发表于 2020-5-25 22:07 来自手机 | 只看该作者
soarw 发表于 2020-4-30 16:58
你好,有硬件电路图吗?

硬件电路图就是购买单片机开发板的电路图,我没有改变原设计,这应该都是标准通用的。开发版留有12864的插排接口,直接把20针的显示屏LCD插上去就行了。
回复

使用道具 举报

地板
ID:138443 发表于 2020-5-27 21:12 | 只看该作者
支持51hei论坛,谢谢
回复

使用道具 举报

5#
ID:753283 发表于 2020-5-31 21:53 来自手机 | 只看该作者
soarw 发表于 2020-5-25 22:07
硬件电路图就是购买单片机开发板的电路图,我没有改变原设计,这应该都是标准通用的。开发版留有12864的 ...

楼主,可以把电路图发出来吗?
回复

使用道具 举报

6#
ID:755390 发表于 2020-6-7 13:16 | 只看该作者
楼主 电路图可以上传吗?
回复

使用道具 举报

7#
ID:753283 发表于 2020-6-8 19:29 来自手机 | 只看该作者
楼主可以发下电路图吗
回复

使用道具 举报

8#
ID:611988 发表于 2024-8-31 09:19 | 只看该作者
楼主 电路图可以上传吗?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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