找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3466|回复: 14
收起左侧

12864+DS1302+DS18B20大字符时钟原理图与源程序

  [复制链接]
ID:669769 发表于 2019-12-21 14:12 | 显示全部楼层 |阅读模式
12864+DS1302 +DS18B20 大字符时钟供大家学习。

               电子智能时钟程序
                单 片 机:STC89C52RC
                晶    振:12MHz
                时钟芯片:DS1302
                液 晶 屏:LCM-12864-ST7920
                时    间:2019年11月26修改完成
                LCM12864使用并口连接方式,PSB、RST接高电平   

制作出来的实物图如下:
131469080663881995.jpg

电路原理图如下:
51hei.png

单片机源程序如下:
  1. /*---------------------------------------------------------------------------
  2.                 电子智能时钟程序
  3.                 单 片 机:STC89C52RC
  4.                 晶    振:12MHz
  5.                 时钟芯片:DS1302
  6.                 液 晶 屏:LCM-12864-ST7920
  7.                 时    间:2019年11月26修改完成
  8.                 LCM12864使用并口连接方式,PSB、RST接高电平   
  9. ------------------------------------------------------------------------------*/

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

  21. /*----------------------------定义按键---------------------------------------*/
  22. sbit K1  = P2^3; //K1-设置  
  23. sbit K2  = P2^2; //K2-确认、返回   
  24. sbit K3  = P2^1; //K3-加         
  25. sbit K4  = P2^0; //K4-减         
  26. //sbit K5  = P3^7; //液晶背光控制按键,按一下亮,再按一下灭                 
  27. //sbit BLK = P3^7; //液晶背光控制输出,低电平有效,PNP三极管控制。

  28. /*---------------------函数声明------------------------------*/
  29. void DelayM(uint);              
  30. void ds_w(void);
  31. void Conver_week(bit c,uchar year,uchar month,uchar day);
  32. /*-----------------------------定义全局变量------------------------------*/
  33. bit q=0, w=0;    //调时标志位
  34. unsigned char yy,mo,dd,xq,hh,mm,ss,month_moon,day_moon,week,tiangan,dizhi,moontemp1,moontemp2;//定义时间映射全局变量(专用寄存器)
  35. signed char address,item,max,mini;

  36. /*-----------------------------延时函数 1MS/次-------------------------------*/
  37. void DelayM(uint a)              
  38. {
  39.         uchar i;
  40.         while( --a != 0) { for(i = 0; i < 125; i++); }                                     
  41. }
  42. /*-----------------------------日期、时间设置函数-----------------------------*/

  43. void tiaozheng(void){
  44.         yy = read_clock(0x8d);//调用1302时钟数据中的年数据,从地址0x8d中   
  45.         mo = read_clock(0x89);//调用1302时钟数据中的月数据,从地址0x89中   
  46.         dd = read_clock(0x87);//从1302芯片中读取日数据,从地址0x87中   
  47.         week = read_clock(0x8b);//从1302芯片中读取星期数据,从地址0x8b中   
  48.         lcm_w_test(0,0x80);

  49.         lcm_w_word("20");//显示内容字符20
  50.         write_data(yy/16+0x30);//函数参数1,代表本行写数据,YY/16+0X30得出年十位数字的显示码地址,送显示       
  51.         write_data(yy%16+0x30);//函数?
  52.         lcm_w_word("年");

  53.         write_data(mo/16+0x30);
  54.         write_data(mo%16+0x30);//与16取余数,得到月份的个位数,加0x30得到该数字的液晶内定显示码送显示
  55.         lcm_w_word("月");     //调用字符显示函数,显示文字 月   

  56.         write_data(dd/16+0x30);
  57.         write_data(dd%16+0x30);//第一个1参数,表示本行写数据,日数据与16取余得个位数,加0x30得到显示码
  58.         lcm_w_word("日");//显示字符 日

  59.         if(read_clock(0x85) != hh){  //如果程序中的小时与1302芯片中的不同,
  60.                 hh = read_clock(0x85);  //刷新程序中的小时数据   
  61.         }
  62.         lcm_w_test(0,0x91);//第一个参数0,表示本行写入LCM的是指令,指定显示位置91H(第三行左端)
  63.         write_data(hh/16+0x30);  //显示十位
  64.          
  65.         write_data(hh%16+0x30);  //显示个位
  66.         lcm_w_word("时");

  67.         if(read_clock(0x83) != mm){//如果1302芯片中的分钟数据与程序中的分钟变量不相等               
  68.                 mm = read_clock(0x83);//刷新程序中的分钟数据
  69.         }
  70.         write_data(mm/16+0x30);//向液晶写数据,显示分钟的十位数
  71.         write_data(mm%16+0x30);//向液晶写数据,显示分钟的个位数
  72.         lcm_w_word("分");

  73.         if(read_clock(0x81) != ss){//如果1302芯片中的分钟数据与程序中的秒钟变量不相等               
  74.                 ss = read_clock(0x81);//刷新程序中的秒钟数据
  75.         }
  76.         write_data(ss/16+0x30);//向液晶写数据,显示分钟的十位数
  77.         write_data(ss%16+0x30);//向液晶写数据,显示分钟的个位数
  78.         lcm_w_word("秒");         

  79. }

  80. /**********************************************************************************************************/
  81. //调整时间子函数,设置键、数据范围、上调加一,下调减一功能。
  82. void Set_time(unsigned char sel){ //根据选择调整的相应项目加1并写入DS1302,函数参数是按动设置键的次数
  83.   
  84.         write_com(0x30); write_com(0x06);

  85.         lcm_w_test(0,0x98);//第一参数0表示本行写入指令,指定下面行的 调整 显示起始位置为98H
  86.         lcm_w_word("★调整");//调用字符显示函数,显示 调整字样
  87.   
  88. /*        if(sel==6)  {lcm_w_word("星期");address=0x8a; max=7;mini=1;          
  89.      tiaozheng();
  90.      ds_w();
  91.      tiaozheng();
  92.           }
  93. */
  94. //////////////////////////////////////////////////////////////
  95.         if(sel==5)  {lcm_w_word("秒钟");address=0x80; max=59;mini=0;          
  96.                 tiaozheng();  //调用日期、时间调整函数
  97.            ds_w();                  //被调数据加一或减一函数
  98.            tiaozheng();
  99.                                             
  100.         }        //秒7,按动7次显示 调整秒钟   
  101.                 //并指定秒钟数据写入1302芯片的地址是0x82,秒钟数据的最大值是59,最小值是0
  102.    /////////////////////////////////////////////////////////////////////////
  103.         if(sel==4)  {lcm_w_word("分钟");address=0x82; max=59;mini=0;
  104.            tiaozheng();
  105.            ds_w();
  106.            tiaozheng();
  107.   
  108.         }        //分钟6,按动6次显示 调整分钟
  109.                 //并指定分钟数据写入1302芯片的地址是0x82,分钟数据的最大值是59,最小值是0


  110.         if(sel==3)  {lcm_w_word("小时");address=0x84; max=23;mini=0;
  111.         /***********************************************************/
  112.                  if(address > 12){
  113.                                            address = address-12;        }
  114.          /********************************************************/
  115.             tiaozheng();
  116.            ds_w();
  117.            tiaozheng();
  118.   
  119.         }        //小时5,按动5次显示 调整小时
  120.                 //规定小时数据写入1302芯片的位置是0x84,小时数据最大值23,最小值是0
  121.   

  122.         if(sel==2)  {lcm_w_word("日期");
  123.                 address=0x86;

  124.                 mo = read_clock(0x89);//读月数据
  125.                 moontemp1=mo/16;
  126.                 moontemp2=mo%16;
  127.                 mo=moontemp1*10+moontemp2;//转换成10进制月份数据

  128.       yy = read_clock(0x8d);//读年数据
  129.         moontemp1=yy/16;
  130.                 moontemp2=yy%16;
  131.                 yy=moontemp1*10+moontemp2;//转换成10进制年份数据

  132.         if(mo==2&&yy%4!=0){max=28;mini=1;}//平年2月28天
  133.                 if(mo==2&&yy%4==0){max=29;mini=1;}//闰年2月29天
  134.                 if(mo==1||mo==3||mo==5||mo==7||mo==8||mo==10||mo==12){max=31;mini=1;}//31天的月份
  135.                 if(mo==4||mo==6||mo==9||mo==11){max=30;mini=1;}//30天的月份
  136.                 tiaozheng();
  137.                 ds_w();
  138.                 tiaozheng(); //调用日期、时间调整函数

  139.   }        //日3,按动3次显示 调整日期
  140.                 //规定日期数据写入1302的位置地址是0x86,日期最大值31,最小值是1



  141.   if(sel==1)  {lcm_w_word("月份");address=0x88; max=12;mini=1;
  142.      tiaozheng();
  143.      ds_w();
  144.      tiaozheng();
  145.   
  146.    }        //月2,按动2次显示 调整月份          
  147.                 //规定月份写入1302的位置地址是0x88,月份最大值12,最小值1


  148.   if(sel==0)  {lcm_w_word("年份");address=0x8c; max=99; mini=0;
  149.      tiaozheng();
  150.      ds_w();                //被调数据加一或减一函数
  151.      tiaozheng();        //调用日期、时间调整函数

  152.    }        //年1,按动1次显示 调整年份,
  153.                 //规定年份写入1302的地址是0x8c,年份的最大值99,最小值0

  154. }

  155. /*****************************************************************************/
  156. //被调数据加一或减一,并检查数据范围,写入1302指定地址保存
  157. void ds_w(void){

  158.         item=((read_clock(address+1))/16)*10 + (read_clock(address+1))%16;
  159.         if(K3 == 0){ //如果按动上调键
  160.                 item++;  //数加 1  
  161.         }                                                                                                                 
  162.         if(K4 == 0){  //如果按动下调键
  163.                   item--;   //数减 1
  164.         }
  165.         if(item>max) item=mini;//查看数值是否在有效范围之内   
  166.         if(item<mini) item=max;//如果数值小于最小值,则自动等于最大值           
  167.         write_clock(0x8e,0x00);//允许写1302芯片操作
  168.         write_clock(address,(item/10)*16+item%10);//转换成16进制写入1302
  169.         write_clock(0x8e,0x80);//写保护,禁止写操作
  170. }

  171. /****可参考***********可参考**************可参考***************以上是调试********

  172. /*主函数---------------------------------------------------------------------*/
  173. void main()
  174. {                            
  175.         uchar e=0;
  176.         K1=1;K2=1;K3=1;K4=1;//BLK=0;//K5=1;

  177.         Init_1302();                //时钟芯片初始化  
  178.         lcm_init();                        //液晶初始化
  179.         welcome();                    //调用欢迎信息
  180.         DelayM(4000);                 //欢迎信息 延时时间  
  181.         lcm_clr();            //清屏
  182.         Clean_12864_GDRAM();         //清屏
  183.         while(1)
  184.         {
  185.                 if (w == 0)                  //正常走时
  186.                 {
  187.                         displaydate();         //显示日期
  188. //                        displaynl();         //显示农历
  189.                         nongli();                 //显示农历
  190. //                        displayjieqi(); //显示节气
  191.                         displaytime();         //显示时间
  192.                         read_temp();         //读取温度
  193.                         ds1820disp();          //显示温度
  194.                         displayxq();         //显示星期
  195.                 }       
  196.                 else {}            //否则启动调时  

  197. /*----------------------------设置时间--------------------------------------*/               
  198.                 if (K1 == 0)         
  199.                 {
  200.                         DelayM(20);                       //按键消抖
  201.                         if(K1 == 0 && w == 1)      //当是调时状态 本键用于调整下一项   
  202.                         {
  203.                                 e++;
  204.                                 if (e >= 7 ) {e = 0;}
  205.                            while(! K1 );            //等待键松开
  206.                                 Set_time(e);           //调整                               
  207.                         }                       
  208.                         if(K1 == 0 && w == 0)      //当是正常状态时就进入调时状态   
  209.                         {
  210.                                 lcm_clr();            
  211.                                 Clean_12864_GDRAM();   //清屏
  212.                                 w=1;                       //进入调时
  213.                                 Set_time(e);
  214.                         }
  215.                            while(K1 == 0);            //等待键松开
  216.                 }
  217. /*--------------------------------------------------------------------------*/               
  218.                 if (K2 == 0)                   // 当在调时状态时就退出调时
  219.                 {
  220.                         DelayM(20);
  221.                         if(K2 == 0 && w == 1)
  222.                         {                               
  223.                                 w = 0;                       //退出调时
  224.                                 e = 0;                           //"下一项"计数器清0                                                               
  225.                         }
  226.                         if(K2 == 0 && w == 0)
  227.                         {                               
  228.                                 lcm_clr(); Clean_12864_GDRAM();
  229.                                 write_com(0x30); write_com(0x06);
  230.                                 welcome();                               
  231.                                 while(K2 == 0);  
  232.                         }
  233.                         lcm_clr(); Clean_12864_GDRAM();
  234.                         displaydate();
  235.                         displayxq();
  236.                         displaynl();
  237.                         displaytime();
  238.                         read_temp();
  239.                         ds1820disp();
  240.                         while(K2 == 0);  
  241.                 }
  242. /*加调整--------------------------------------------------------------------*/               
  243.                 if (K3 == 0 && w == 1)
  244.                 {
  245.                         DelayM(20);
  246.                         if(K3 == 0 && w == 1) { Set_time(e); }
  247.                         while(K3 == 0);
  248.                         while(! K3 );
  249.                 }
  250. /*减调整--------------------------------------------------------------------*/               
  251.                 if (K4 == 0 && w == 1)
  252.                 {              
  253.                         DelayM(20);
  254.                         if(K4 == 0 && w == 1) { Set_time(e); }
  255.                         while(K4 == 0);
  256.                         while(! K4 );
  257.                 }
  258. /*液晶背光控制,按一下亮,再按一下灭----------------------------------------*/
  259. /*                if(K5 == 0)        
  260.                 {
  261.                         DelayM(20); q = ~q;      //标志位取反
  262.                          if(q){BLK = BLK | 1;}   
  263.                                  else {BLK = BLK & 0;}   
  264.                         while(K5 == 0);           
  265.                 }                          */
  266.         }
  267. }
  268. /*结束----------------------------------------------------------------------*/
复制代码

所有资料51hei提供下载:
12864大字符时钟原理图.rar (16.91 KB, 下载次数: 66)

评分

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

查看全部评分

回复

使用道具 举报

ID:669769 发表于 2019-12-24 10:27 | 显示全部楼层
管理员你好!如何修改已发的帖子?
回复

使用道具 举报

ID:56002 发表于 2019-12-25 11:01 | 显示全部楼层
这是杜洋程序,贴出请注明出处! 电子制作其乐无穷!
回复

使用道具 举报

ID:669769 发表于 2019-12-30 15:33 | 显示全部楼层
oplink 发表于 2019-12-25 11:01
这是杜洋程序,贴出请注明出处! 电子制作其乐无穷!

没有听懂你的意思啊?
回复

使用道具 举报

ID:59151 发表于 2020-1-22 23:59 | 显示全部楼层
正在学习中,谢谢分享!
回复

使用道具 举报

ID:59151 发表于 2020-1-23 00:00 | 显示全部楼层
正在学习中,谢谢分享!
回复

使用道具 举报

ID:634466 发表于 2020-1-25 13:02 | 显示全部楼层
谢谢分享
回复

使用道具 举报

ID:400262 发表于 2020-1-28 22:46 | 显示全部楼层
背光控制那里,注释掉了,去掉注释重新编译是不是就可以用了?
回复

使用道具 举报

ID:208733 发表于 2020-2-1 17:07 | 显示全部楼层
这里面是不是有源程序
回复

使用道具 举报

ID:200118 发表于 2020-2-2 17:47 | 显示全部楼层
谢谢分享。。。
回复

使用道具 举报

ID:200118 发表于 2020-2-2 17:51 | 显示全部楼层
谢谢分享。。。
回复

使用道具 举报

ID:288930 发表于 2020-2-3 11:59 | 显示全部楼层
东西不错,谢谢分享!
回复

使用道具 举报

ID:669769 发表于 2020-2-4 15:18 | 显示全部楼层
不吃草的牛 发表于 2020-2-1 17:07
这里面是不是有源程序

12864+DS1302 +DS18B20 大字符时钟.rar 有的
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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