[51单片机] 51单片机驱动PCF8563

[复制链接]
 楼主| 比神乐 发表于 2024-10-13 15:26 | 显示全部楼层 |阅读模式
代码:
pcf8563.c
  1. #include <reg51.h>
  2. #include <absacc.h>
  3. #include <intrins.h>

  4. #define uchar unsigned char

  5. sbit SDA=P1^4;
  6. sbit SCL=P1^5;

  7. uchar g8563_Store[6]={0x23,0x12,0x31,0x23,0x59,0x40}; /*时间交换区,全局变量声明*/
  8. uchar code c8563_Store[6]={0x13,0x09,0x22,0x10,0x40,0x00}; /*写入时间初值:星期一 07:59:00*/

  9. /********************************************
  10. 内部函数,延时1
  11. ********************************************/
  12. void Delay()
  13. {
  14.                 _nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();/*根据晶振频率制定延时时间*/
  15. }
  16. /********************************************
  17. 内部函数,I2C开始
  18. ********************************************/
  19. void Start()
  20. {
  21.                 SDA=1;
  22.                    SCL=1;
  23.                    Delay();
  24.                    SDA=0;
  25.                    Delay();
  26.                    SCL=0;
  27. }
  28. /********************************************
  29. 内部函数,I2C结束
  30. ********************************************/
  31. void Stop()
  32. {
  33.                 SDA=0;
  34.                    SCL=0;
  35.             Delay();
  36.                    SCL=1;
  37.                    Delay();
  38.                    SDA=1;
  39.                    Delay();
  40. }
  41. /********************************************
  42. 内部函数,输出ACK ,每个字节传输完成,输出ack=0,结束读书据,ack=1;
  43. ********************************************/
  44. void WriteACK(uchar ack)
  45. {
  46.                 SDA=ack;
  47.                    Delay();
  48.                    SCL=1;
  49.                    Delay();
  50.                    SCL=0;
  51. }
  52. /********************************************
  53. 内部函数,等待ACK
  54. ********************************************/
  55. void WaitACK()
  56. {  
  57.                 uchar errtime=20;
  58.                    SDA=1;
  59.                    Delay(); /*读ACK*/
  60.                    SCL=1;
  61.                    Delay();
  62.                    while(SDA)
  63.                    {  
  64.                                 errtime--;
  65.                               if(!errtime)
  66.                                                 Stop();
  67.                    }
  68.                    SCL=0;
  69.                    Delay();
  70. }
  71. /********************************************
  72. 内部函数.输出数据字节
  73. 入口:B=数据
  74. ********************************************/
  75. void writebyte(uchar wdata)
  76. {
  77.                 uchar i;
  78.                    for(i=0;i<8;i++)
  79.                    {
  80.                         if(wdata&0x80)
  81.                                                 SDA=1;
  82.                                else
  83.                                                 SDA=0;
  84.                                wdata<<=1;
  85.                                SCL=1;
  86.                                Delay();
  87.                                SCL=0;
  88.                    }
  89.                    WaitACK();     //I2C器件或通讯出错,将会退出I2C通讯
  90. }
  91. /********************************************
  92. 内部函数.输入数据
  93. 出口:B
  94. ********************************************/
  95. uchar Readbyte()
  96. {
  97.                 uchar i,bytedata;
  98.                    SDA=1;
  99.                    for(i=0;i<8;i++)
  100.                    {
  101.                               SCL=1;
  102.                               bytedata<<=1;
  103.                               bytedata|=SDA;
  104.                               SCL=0;
  105.                               Delay();
  106.                    }
  107.                    return(bytedata);
  108. }
  109. /********************************************
  110. 输出数据->pcf8563
  111. ********************************************/
  112. void writeData(uchar address,uchar mdata)
  113. {
  114.                 Start();
  115.                    writebyte(0xa2); /*写命令*/
  116.                 writebyte(address); /*写地址*/
  117.             writebyte(mdata); /*写数据*/
  118.                 Stop();
  119. }
  120. /********************************************
  121. 输入数据<-pcf8563
  122. ********************************************/
  123. /*uchar ReadData(uchar address) //单字节
  124. {  
  125.                 uchar rdata;
  126.                    Start();
  127.             writebyte(0xa2); //写命令
  128.             writebyte(address); //写地址
  129.             Start();
  130.             writebyte(0xa3); //读命令
  131.             rdata=Readbyte();
  132.             WriteACK(1);
  133.             Stop();
  134.             return(rdata);
  135. }        */
  136. void ReadData1(uchar address,uchar count,uchar * buff) /*多字节*/
  137. {  
  138.                 uchar i;
  139.                    Start();
  140.                    writebyte(0xa2); /*写命令*/
  141.             writebyte(address); /*写地址*/
  142.             Start();
  143.             writebyte(0xa3); /*读命令*/
  144.             for(i=0;i<count;i++)
  145.             {
  146.                             buff[i]=Readbyte();
  147.                                if(i<count-1)
  148.                                                 WriteACK(0);
  149.             }
  150.             WriteACK(1);
  151.         Stop();
  152. }  
  153. /********************************************
  154. 内部函数,读入时间到内部缓冲区
  155. ********************************************/
  156. void P8563_Read()
  157. {   
  158.                 uchar time[7];
  159.             ReadData1(0x02,0x07,time);
  160.             g8563_Store[0]=time[0]&0x7f; /*秒 */
  161.             g8563_Store[1]=time[1]&0x7f; /*分 */
  162.             g8563_Store[2]=time[2]&0x3f; /*小时 */
  163.                 g8563_Store[3]=time[3]&0x3f; /*日 */
  164.             g8563_Store[4]=time[5]&0x1f; /*月 */
  165.                 g8563_Store[5]=time[6]; /*年  */

  166.                     
  167. }
  168. /********************************************
  169. 读入时间到内部缓冲区----外部调用
  170. ********************************************/
  171. void P8563_gettime()
  172. {
  173.             P8563_Read();
  174.             if(g8563_Store[0]==0)
  175.                               P8563_Read(); /*如果为秒=0,为防止时间变化,再读一次*/
  176. }       
  177. /********************************************
  178. 写时间修改值
  179. ********************************************/
  180. void P8563_settime()
  181. {
  182.             //uchar i;
  183.             writeData(8,g8563_Store[0]); //年
  184.                  writeData(7,g8563_Store[1]); //月
  185.                 writeData(5,g8563_Store[2]); //日
  186.                 writeData(4,g8563_Store[3]); //时
  187.                    writeData(3,g8563_Store[4]); //分  
  188.                 writeData(2,g8563_Store[5]); //秒
  189. }
  190. /********************************************
  191. P8563的初始化-----外部调用
  192. ********************************************/
  193. void P8563_init()
  194. {
  195.     uchar i;
  196.           // P8563_settime();
  197. //for(i=0;i<=5;i++) g8563_Store[i]=c8563_Store[i]; /*初始化时间*/
  198.         P8563_settime();  
  199.    // if((ReadData(0x0a)&0x3f)!=0x08) /*检查是否第一次启动,是则初始化时间*/
  200.    // {
  201. //            P3_4 = 0;
  202. //       for(i=0;i<=3;i++) g8563_Store[i]=c8563_Store[i]; /*初始化时间*/
  203. //       P8563_settime();
  204. //       writeData(0x0,0x00);
  205. //       writeData(0xa,0x8); /*8:00报警*/
  206. //       writeData(0x1,0x12); /*报警有效*/
  207.   //      writeData(0xd,0xf0);  //编程输出32.768K的频率
  208.   //  }
  209. }

主程序
  1. #include<reg51.h >
  2. #include"OLED.H"

  3. extern unsigned char g8563_Store[6];
  4. extern void P8563_init();
  5. extern void P8563_gettime();
  6. void main(void)
  7. {
  8.         int i;
  9.         unsigned char shi,ge;
  10.         LCD_Init();
  11.     LCD_CLS();
  12.         LCD_P8x16Str(20,4,(u8*)"20  -  -  ");
  13.         LCD_P6x8Str(20,6,(u8*)"  :  :  ");
  14.         P8563_init();
  15.         //Draw_BMP(0,0,100,3,(u8*)Dot);
  16.         while(1)
  17.         {
  18.                 P8563_gettime();
  19.                 shi=(g8563_Store[0]>>4)+0x30;
  20.                 ge=(g8563_Store[0]&0x0f)+0x30;
  21.                 LCD_P8x16Char(68,6,shi);
  22.                 LCD_P8x16Char(76,6,ge);
  23.                 shi=(g8563_Store[1]>>4)+0x30;
  24.                 ge=(g8563_Store[1]&0x0f)+0x30;
  25.                 LCD_P8x16Char(44,6,shi);
  26.                 LCD_P8x16Char(52,6,ge);
  27.                 shi=(g8563_Store[2]>>4)+0x30;
  28.                 ge=(g8563_Store[2]&0x0f)+0x30;
  29.                 LCD_P8x16Char(20,6,shi);
  30.                 LCD_P8x16Char(28,6,ge);

  31.                 shi=(g8563_Store[3]>>4)+0x30;
  32.                 ge=(g8563_Store[3]&0x0f)+0x30;
  33.                 LCD_P8x16Char(68,4,shi);
  34.                 LCD_P8x16Char(76,4,ge);
  35.                 shi=(g8563_Store[4]>>4)+0x30;
  36.                 ge=(g8563_Store[4]&0x0f)+0x30;
  37.                 LCD_P8x16Char(44,4,shi);
  38.                 LCD_P8x16Char(52,4,ge);
  39.                 shi=(g8563_Store[5]>>4)+0x30;
  40.                 ge=(g8563_Store[5]&0x0f)+0x30;
  41.                 LCD_P8x16Char(20,4,shi);
  42.                 LCD_P8x16Char(28,4,ge);
  43.                 for(i=0;i<20000;i++);
  44.         }
  45. }
效果图:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

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

本版积分规则

470

主题

3535

帖子

7

粉丝
快速回复 在线客服 返回列表 返回顶部