找回密码
 立即注册

QQ登录

只需一步,快速开始

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

LCD12864和PCF8563 IIC总线(万年历)显示时间的单片机源码

  [复制链接]
跳转到指定楼层
楼主
刚学51单片机IIC以及万年历的源码
下面直接放东西,就是个简单的万年历,请各位大神指教



单片机源程序如下:
  1. /*
  2. LCD12864和PCF8563显示时间 !!!
  3. 徐逸夫
  4. 2016-5-16  ~  5-18
  5. */
  6. /* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序 */
  7. #include <STC15.H>
  8. #include <stdio.h>
  9. #include "GPIO.h"                                                        
  10. #include "12864.h"
  11. #include "LCD_draw.h"
  12. #include "IIC.h"
  13. #include "Infrared.h"
  14. sbit        HC595_SER   = P4^0;        //pin 14        SER                data input
  15. sbit        HC595_LCLK  = P5^4;        //pin 12        RCLk        store (latch) clock
  16. sbit        HC595_SCLK = P4^3;        //pin 11        SRCLK        Shift data clock

  17. /*************  红外接收程序变量声明    **************/
  18. //sbit    P_IR_RX = P3^6;         //定义红外接收输入IO口
  19. u8  IR_SampleCnt;       //采样计数
  20. u8  IR_BitCnt;          //编码位数
  21. u8  IR_UserH;           //用户码(地址)高字节
  22. u8  IR_UserL;           //用户码(地址)低字节
  23. u8  IR_data;            //数据原码
  24. u8  IR_DataShit;        //数据移位

  25. bit P_IR_RX_temp;       //Last sample
  26. bit B_IR_Sync;          //已收到同步标志
  27. bit B_IR_Press;         //安键动作发生
  28. u8  IR_code;            //红外键码
  29. u16 UserCode;           //用户码
  30. /*****************************************************/

  31. u8 week0[] = {"一"},week1[] = {"二"},week2[] = {"三"};
  32. u8 week3[] = {"四"},week4[] = {"五"},week5[] = {"六"},week6[] = {"天"};                //星期几的字符集
  33. u8 code num2char[] = {"0123456789"};                //数字转化为ASCII字符
  34. u8 Time_num[] = {"00-00-00"};                                                //时分秒的数字形式
  35. u8 YMD_num[] = {"00-00-00"};                                                //year,month,day的数字形式

  36. u16 msecond;                                                                                                                //毫秒计数
  37. bit B_1ms;                                                                                                                        //1ms标志位

  38. struct POINT_CLOCK                                        //结构体   RTC变量时分秒
  39. {
  40.         u8 hour;
  41.         u8 minute;
  42.         u8 second;
  43. }RTC_Time,RTC_Time_Now;

  44. struct NUM_CLOCK                                        //结构体   RTC变量year,month,day的扩充
  45. {
  46.         u8 year;
  47.         u8 month;
  48.         u8 week;
  49.         u8 day;
  50. }More_Time;

  51. void  DisableHC595(void);                                                 //关闭595显示
  52. void  ReadRTC();                                                                                //读取PCF8563的时间
  53. void  WriteRTC();                                                                                //更改PCF8563的时间
  54. void  init_ClockCirle();                                                 //初始化表盘和刻度
  55. void  Display_Pointer(struct POINT_CLOCK AA);        //指针显示
  56. void  Display_ThreePointer();       //指针式时钟显示
  57. void  Display_Number(struct POINT_CLOCK AA,struct NUM_CLOCK BB);        //右侧LCD数字显示
  58.         
  59. void DisableHC595(void) //关闭595显示
  60. {               
  61.         u8        i;
  62.         HC595_SER   = 1;
  63.         for(i=0; i<20; i++)
  64.         {
  65.                 HC595_SCLK = 1;
  66.                 HC595_SCLK = 0;
  67.         }
  68.         HC595_LCLK = 1;
  69.         HC595_LCLK = 0;                                                        //锁存输出数据
  70.         HC595_LCLK = 1;
  71.         HC595_LCLK = 0;                                                        //锁存输出数据
  72. }


  73. /********************** 读RTC函数 ************************/
  74. void    ReadRTC(void)
  75. {
  76.         u8  tmp[7];
  77.         ReadNbyte(2, tmp, 7);
  78.         RTC_Time_Now.second = ((tmp[0] >> 4) & 0x07) * 10 + (tmp[0] & 0x0f);
  79.         RTC_Time_Now.minute = ((tmp[1] >> 4) & 0x07) * 10 + (tmp[1] & 0x0f);
  80.         RTC_Time_Now.hour   = ((tmp[2] >> 4) & 0x03) * 10 + (tmp[2] & 0x0f);
  81.         More_Time.day       = ((tmp[3] >> 4) & 0x03) * 10 + (tmp[3] & 0x0f);
  82.         More_Time.week      = ((tmp[4] >> 4) & 0x00) * 10 + (tmp[4] & 0x07);
  83.         More_Time.month     = ((tmp[5] >> 4) & 0x01) * 10 + (tmp[5] & 0x0f);
  84.         More_Time.year      = ((tmp[6] >> 4) & 0x0f) * 10 + (tmp[6] & 0x0f);
  85. }

  86. /********************** 写RTC函数 ************************/
  87. void    WriteRTC()
  88. {
  89.         u8  tmp[7];
  90.         tmp[0] = ((RTC_Time_Now.second / 10) << 4) + (RTC_Time_Now.second % 10);
  91.         tmp[1] = ((RTC_Time_Now.minute / 10) << 4) + (RTC_Time_Now.minute % 10);
  92.         tmp[2] = ((RTC_Time_Now.hour / 10) << 4) + (RTC_Time_Now.hour % 10);
  93.         tmp[3] = ((More_Time.day / 10) << 4) + (More_Time.day % 10);
  94.         tmp[4] = ((More_Time.week / 10) << 4) + (More_Time.week % 10);
  95.         tmp[5] = ((More_Time.month / 10) << 4) + (More_Time.month % 10);
  96.         tmp[6] = ((More_Time.year / 10) << 4) + (More_Time.year % 10);
  97.         WriteNbyte(2, tmp, 7);
  98. }

  99. void init_ClockCirle()                         //初始化表盘
  100. {
  101.         u8 i;
  102.         draw_Circle(32,32,31,0);//画圆  圆心坐标(32,32) 半径31,空心圆
  103.         for(i=0;i<60;i++)
  104.         {
  105.                 if((i%5)==0)      //画刻度
  106.                 {
  107.                         draw_Line(RTC_X(32,28,i),RTC_Y(32,28,i),RTC_X(32,30,i),RTC_Y(32,30,i));                                       
  108.                 }
  109.         }
  110. }
  111. /*========================================================================
  112. *name:Display_Pointer(struct POINT_CLOCK AA)
  113. *function:显示时、分、秒指针
  114. *参    数:结构体: 时分秒   
  115. *注:                秒针长24                        分针长17                        秒针长12
  116. =========================================================================*/
  117. void Display_Pointer(struct POINT_CLOCK AA)        //指针显示 ,作为Display_ThreePointer()的子函数
  118. {
  119.         draw_Line(RTC_X(32,24,AA.second),RTC_Y(32,24,AA.second),32,32);         //秒针
  120.         draw_Line(RTC_X(32,17,AA.minute),RTC_Y(32,17,AA.minute),32,32);                //分针
  121.         draw_Line(RTC_X(32,12,AA.minute/12+5*(AA.hour%12)),RTC_Y(32,12,AA.minute/12+5*(AA.hour%12)),32,32);  //时针        
  122. }

  123. /*========================================================================
  124. *name:Display_ThreePointer(struct POINT_CLOCK AA,unsigned char color)
  125. *function:显示时、分、秒指针
  126. *参    数:        结构体0:存放上一个时分秒   两者不同时,刷新显示
  127.                                                 结构体1:存放这一个时分秒   
  128. =========================================================================*/
  129. void Display_ThreePointer()        //左侧LCD指针式时钟显示
  130. {
  131.         if(RTC_Time.second!=RTC_Time_Now.second)      //秒刷新
  132.         {
  133.                 dele_Line(RTC_X(32,24,RTC_Time.second),RTC_Y(32,24,RTC_Time.second),32,32);
  134.         }
  135.         if(RTC_Time.minute!=RTC_Time_Now.minute)    //分刷新
  136.         {
  137.                 dele_Line(RTC_X(32,17,RTC_Time.minute),RTC_Y(32,17,RTC_Time.minute),32,32);        
  138.         }
  139.         if((RTC_Time.minute/12+5*(RTC_Time.hour%12))!=(RTC_Time_Now.minute/12+5*(RTC_Time_Now.hour%12)))   //时刷新显示
  140.         {
  141.                 dele_Line(RTC_X(32,12,RTC_Time.minute/12+5*(RTC_Time.hour%12)),RTC_Y(32,12,RTC_Time.minute/12+5*(RTC_Time.hour%12)),32,32);        
  142.         }
  143.         Display_Pointer(RTC_Time_Now);        //现在的指针式时钟显示
  144.         RTC_Time=RTC_Time_Now;
  145. }

  146. void Display_Number(struct POINT_CLOCK AA,struct NUM_CLOCK BB)        //右侧LCD数字显示
  147. {
  148.         lcdwritecmd(0x30);                                                //普通文本模式
  149.         ReadRTC();
  150.         Time_num[0]=num2char[AA.hour/10],Time_num[1]=num2char[AA.hour%10];
  151.         Time_num[3]=num2char[AA.minute/10],Time_num[4]=num2char[AA.minute%10];        
  152.         Time_num[6]=num2char[AA.second/10],Time_num[7]=num2char[AA.second%10];
  153.         lcdshowstr(4,2,Time_num);                                                //时分秒的数字显示
  154.         YMD_num[0]=num2char[BB.year/10],YMD_num[1]=num2char[BB.year%10];
  155.         YMD_num[3]=num2char[BB.month/10],YMD_num[4]=num2char[BB.month%10];
  156.         YMD_num[6]=num2char[BB.day/10],YMD_num[7]=num2char[BB.day%10];
  157.         lcdshowstr(4,1,YMD_num);                                                //年月日的数字显示
  158.         lcdshowstr(4,3,"星期");                                                //星期几的显示
  159.         switch (BB.week)
  160.         {
  161.                 case 0:lcdshowstr(6,3,week0);break;                case 1:lcdshowstr(6,3,week1);break;                case 2:lcdshowstr(6,3,week2);break;
  162.                 case 3:lcdshowstr(6,3,week3);break;                case 4:lcdshowstr(6,3,week4);break;                case 5:lcdshowstr(6,3,week5);break;
  163.                 case 6:lcdshowstr(6,3,week6);break;                default:lcdshowstr(6,3,"几");break;
  164.         }
  165. }
  166. void        AutoTime()                                                        //时间自动调整,分针时针的加减调整和进位
  167. {
  168.         if (IR_code == 7||IR_code == 21||IR_code == 64||IR_code == 68)                                
  169.                 {
  170.                         if(IR_code == 7)
  171.                         {
  172.                                 if(RTC_Time_Now.minute == 0)
  173.                                 {
  174.                                         RTC_Time_Now.minute = 59;
  175.                                         if(RTC_Time_Now.hour == 0)
  176.                                         {
  177.                                                 RTC_Time_Now.hour = 23;
  178.                                         }else RTC_Time_Now.hour--;
  179.                                 }else RTC_Time_Now.minute--;
  180.                                 WriteRTC();IR_code=0;
  181.                         }
  182.                         if(IR_code == 21)
  183.                         {
  184.                                 if(++RTC_Time_Now.minute >= 60)
  185.                                 {
  186.                                         RTC_Time_Now.minute = 0;
  187.                                         if(++RTC_Time_Now.hour >= 24)        RTC_Time_Now.hour = 0;
  188.                                 }
  189.                                 WriteRTC();IR_code=0;
  190.                         }
  191.                         if(IR_code == 64)
  192.                         {
  193.                                 if(++RTC_Time_Now.hour >= 24)
  194.                                 {
  195.                                         RTC_Time_Now.hour = 0;
  196.                                 }
  197.                                 WriteRTC();IR_code=0;
  198.                         }
  199.                         if(IR_code == 68)
  200.                         {
  201.                                 if(RTC_Time_Now.hour == 0)
  202.                                 {
  203.                                         RTC_Time_Now.hour = 23;
  204.                                 }else RTC_Time_Now.hour--;
  205.                                 WriteRTC();IR_code=0;
  206.                         }
  207.                 }
  208. }
  209.         void Timer0Init(void)                //1毫秒@11.0592MHz
  210. {
  211.         AUXR |= 0x80;                //定时器时钟1T模式
  212.         TMOD &= 0xF0;                //设置定时器模式
  213.         TH0 = 0xFC;
  214.         TL0 = 0xF6;
  215.         ET0 = 1;    //Timer0 interrupt enable
  216.         TR0 = 1;                //定时器0开始计时
  217. }

  218. void Interrupt_Timer0() interrupt 1
  219. {        
  220.         B_1ms = 1;                                        //1ms扫描显示一位
  221.         IR_RX_NEC();                                //扫描红外遥控
  222. }

  223. void main()
  224. {
  225.         bit error;
  226.         GPIO();
  227.         DisableHC595();                //禁止掉学习板上的HC595显示,省电
  228.         Timer0Init();EA=1;
  229.   lcdinit();                                //初始化
  230.         lcd_cls();                                                        //清屏
  231.         init_ClockCirle();                        //画出表盘
  232.         ReadRTC();
  233.         error = 1;                                                        //初始化默认更改时间
  234.         if(RTC_Time_Now.second >= 60)    error = 1; //错误
  235.         if(RTC_Time_Now.minute >= 60)    error = 1; //错误
  236.         if(RTC_Time_Now.hour   >= 24)    error = 1; //错误
  237.         if(error)  //有错误, 默认12:00:00
  238.         {
  239.                         RTC_Time_Now.second = 58;RTC_Time_Now.minute = 59;RTC_Time_Now.hour  = 22;                                //更改为2016-5-18
  240.                         More_Time.day = 18;More_Time.week = 2;More_Time.month = 5 ;More_Time.year =  16;        //        22:59:58
  241.                         WriteRTC();                                                                //写入时间到PCF8563
  242.         }
  243.         while(1)
  244.         {        //根据接收到的键值 对时间进行改变
  245.                 AutoTime();
  246.                 if(B_1ms)   //1ms到
  247.                 {
  248.                         B_1ms = 0;
  249.                         if(B_IR_Press)                      //检测到收到红外键码
  250.                         {
  251.                                 B_IR_Press = 0;
  252. ……………………

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

所有资料51hei提供下载:
IIC以及万年历.zip (106.44 KB, 下载次数: 123)




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

使用道具 举报

沙发
ID:198286 发表于 2020-3-1 12:35 | 只看该作者
PCF8563就是595的程序吧,我一直在找这个
回复

使用道具 举报

板凳
ID:214276 发表于 2020-3-28 16:44 | 只看该作者
刚好有个8583的时钟芯片,下载来试试看学习下。
回复

使用道具 举报

地板
ID:398094 发表于 2020-3-28 22:18 | 只看该作者
刚好有个8583的时钟芯片,学习下。
回复

使用道具 举报

5#
ID:852976 发表于 2020-12-7 16:06 | 只看该作者
刚好用到,感谢大佬
回复

使用道具 举报

6#
ID:170645 发表于 2022-2-18 03:39 来自手机 | 只看该作者
硬件i2c oled pcf 8563
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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