找回密码
 立即注册

QQ登录

只需一步,快速开始

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

PCF8563测试程序的51单片机版本

[复制链接]
跳转到指定楼层
楼主
ID:110734 发表于 2016-4-19 08:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. #include <reg51.h>
  2. #include <intrins.h>
  3. sbit SDA=P1^0;                          // 将p1.0口模拟数据口
  4. sbit SCL=P1^1;                          // 将p1.1口模拟时钟口
  5. #define MIN    0x02 //秒寄存器
  6. #define SEC   0x03 //分寄存器
  7. #define HOUR   0x04 //时寄存器
  8. #define DAY    0x05 //日寄存器
  9. #define WEEK   0x06 //周寄存器
  10. #define MONTH 0x07 //月寄存器
  11. #define YEAR   0x08 //年寄存器
  12. #define read_ADD 0xA3 //写器件地址
  13. #define write_ADD 0xA2 //读器件地址
  14. #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};               
  15. unsigned char g8563_Store[4]; /*时间交换区,全局变量声明*/  
  16. unsigned char code c8563_Store[4]={0x00,0x59,0x07,0x01}; /*写入时间初值:星期一 07:59:00*/
  17. bit   bdata SystemError;                // 从机错误标志位
  18. //--------------------------------------------------------------------------------------------------
  19. // 函数名称: iic_start()
  20. // 函数功能: 启动I2C总线子程序
  21. //--------------------------------------------------------------------------------------------------
  22. void iic_start(void)
  23. { EA=0;            //时钟保持高,数据线从高到低一次跳变,I2C通信开始
  24.           SDA = 1;         
  25.           SCL = 1;  
  26.           delayNOP();      // 延时5us
  27.           SDA = 0;
  28.           delayNOP();
  29.           SCL = 0;
  30.          }
  31. //--------------------------------------------------------------------------------------------------         
  32. // 函数名称: iic_stop()
  33. // 函数功能: 停止I2C总线数据传送子程序
  34. //--------------------------------------------------------------------------------------------------
  35. void iic_stop(void)
  36.   {  
  37.            SDA = 0;       //时钟保持高,数据线从低到高一次跳变,I2C通信停止
  38.            SCL = 1;
  39.            delayNOP();
  40.            SDA = 1;
  41.            delayNOP();
  42.            SCL = 0;
  43.   }
  44.   //--------------------------------------------------------------------------------------------------
  45.   // 函数名称: slave_ACK  // 函数功能: 从机发送应答位子程序  
  46.   //--------------------------------------------------------------------------------------------------
  47.    void slave_ACK(void)
  48.     {
  49.              SDA = 0;   
  50.              SCL = 1;
  51.              delayNOP();   
  52.              SDA = 1;
  53.              SCL = 0;
  54.               }
  55. //--------------------------------------------------------------------------------------------------
  56. // 函数名称: slave_NOACK  // 函数功能: 从机发送非应答位子程序,迫使数据传输过程结束  
  57. //--------------------------------------------------------------------------------------------------
  58. void slave_NOACK(void)
  59.   {  
  60.            SDA = 1;   
  61.            SCL = 1;
  62.            delayNOP();
  63.            SDA = 0;
  64.            SCL = 0;
  65.            }  
  66. //-------------------------------------------------------------------------------------------------
  67. // 函数名称: check_ACK  // 函数功能: 主机应答位检查子程序,迫使数据传输过程结束  
  68. //--------------------------------------------------------------------------------------------------
  69.   void check_ACK(void)
  70.      {   SDA = 1;      // 将p1.0设置成输入,必须先向端口写1
  71.                 SCL = 1;
  72.                 F0 = 0;  
  73.                 if(SDA == 1)    // 若SDA=1表明非应答,置位非应答标志F0   
  74.                 F0 = 1;
  75.                 SCL = 0;
  76.              }
  77. //--------------------------------------------------------------------------------------------------
  78. // 函数名称: IICSendByte
  79. // 入口参数: ch
  80. // 函数功能: 发送一个字节
  81. //--------------------------------------------------------------------------------------------------
  82. void IICSendByte(unsigned char ch)
  83. {   
  84.         unsigned char idata n=8;     // 向SDA上发送一位数据字节,共八位
  85.            while(n--)
  86.            {      
  87.                    if((ch&0x80) == 0x80)    // 若要发送的数据最高位为1则发送位1   
  88.                            {      
  89.                                    SDA = 1;    // 传送位1     
  90.                                    SCL = 1;     
  91.                                    delayNOP();     
  92.                                    SDA = 0;     
  93.                                    SCL = 0;        
  94.                            }   
  95.                                    else   
  96.                                            {      
  97.                                                     SDA = 0;    // 否则传送位0     
  98.                                                     SCL = 1;     
  99.                                                     delayNOP();
  100.                SCL = 0;     
  101.             }   
  102.                ch = ch<<1;    // 数据左移一位
  103.      }
  104. }
  105. //--------------------------------------------------------------------------------------------------
  106. // 函数名称: IICreceiveByte // 返回接收的数据  // 函数功能: 接收一字节子程序  
  107. //--------------------------------------------------------------------------------------------------
  108. unsigned char IICreceiveByte(void)
  109. {  unsigned char idata n=8;    // 从SDA线上读取一上数据字节,共八位
  110.          unsigned char tdata;
  111.          while(n--)
  112.          {     
  113.                  SDA = 1;   
  114.                  SCL = 1;     
  115.                  tdata = tdata<<1;    // 左移一位,或_crol_(temp,1)   
  116.                  if(SDA == 1)      
  117.                          tdata = tdata|0x01;    // 若接收到的位为1,则数据的最后一位置1   
  118.                          else      
  119.                     tdata = tdata&0xfe;    // 否则数据的最后一位置0   
  120.                     SCL=0;
  121.          }  
  122.   return(tdata);
  123.   }
  124. //--------------------------------------------------------------------------------------------------
  125. // 用户调用子程序  
  126. // 函数名称: write_CFGbyte  
  127. // 入口参数: CFG_add寄存器地址,CFG_data要写入寄存器的数值
  128. // 函数功能: 发送n位数据子程序  
  129. //--------------------------------------------------------------------------------------------------  
  130. void write_CFGbyte(unsigned char CFG_add,unsigned char CFG_data)
  131. {           
  132.     //unsigned char idata send_da,i=0;
  133.      iic_start();                // 启动I2C  
  134.      IICSendByte(write_ADD);     // 发送器件写地址
  135.      check_ACK();                // 检查应答位     
  136.      if(F0 == 1)
  137.              {      
  138.                      SystemError = 1;   
  139.                       return;    // 若非应答表明器件错误或已坏,置错误标志位SystemError
  140.                       }  
  141.                       IICSendByte(CFG_add);       // 发送寄存器地址
  142.                       check_ACK();                // 检查应答位     
  143.                       if(F0 == 1)
  144.                               {      
  145.                                       SystemError = 1;     
  146.                                       return;    // 若非应答表明器件错误或已坏,置错误标志位SystemError
  147.                                }      
  148.                                       IICSendByte(CFG_data);       // 发送寄存器数据
  149.                                       check_ACK();                // 检查应答位     
  150.                                       if(F0 == 1)
  151.                                               {      
  152.                                                       SystemError = 1;     
  153.                                                       return;    // 若非应答表明器件错误或已坏,置错误标志位SystemError
  154.                                               }  
  155.                                                       iic_stop();         // 全部发完则停止
  156. }
  157. //--------------------------------------------------------------------------------------------------
  158. // 用户调用子程序  // 函数名称: receiveNbyte  
  159. // 入口参数: CFG_add寄存器地址地址
  160. // 出口参数: receive_da  
  161. // 函数功能: 接收某个寄存器数据子程序
  162. //--------------------------------------------------------------------------------------------------
  163. unsigned char receive_CFGbyte(unsigned char idata CFG_add)
  164. {   unsigned char idata receive_da;
  165.                     iic_start();     
  166.                     IICSendByte(write_ADD); //器件写地址
  167.                     check_ACK();
  168.                     if(F0 == 1)
  169.                             {   
  170.                                      SystemError = 1;   
  171.                                      return(0); }  
  172.                                      IICSendByte(CFG_add); //寄存器地址 check_ACK(); if(F0 == 1)
  173.                                      {     SystemError = 1;   
  174.                                                    return(0); }      
  175.                                                    iic_start();      
  176.                                                    IICSendByte(read_ADD); //器件读地址   
  177.                                                    if(F0 == 1)
  178.                                                            {     SystemError = 1;   
  179.                                                                     return(0);
  180.                                                            }      
  181.                                                            receive_da=IICreceiveByte();     
  182.                                                            slave_NOACK();       // 收到最后一个字节后发送一个非应答位
  183.                                                            iic_stop();  
  184.                                                            return(receive_da);
  185.                                                    }
  186. //--------------------------------------------------------------------------------------------------
  187. // 用户调用函数  // 函数名称: receive_CFGNbyte
  188.   // 入口参数: CFG_add寄存器地址地址,n连续读数位,* buff存储区地址
  189.    // 函数功能: 接收n个寄存器数据子程序  
  190.    //--------------------------------------------------------------------------------------------------  
  191.    void receive_CFGNbyte(unsigned char CFG_add, unsigned char n,unsigned char * buff)
  192.    { unsigned char receive_da,i=0;
  193.            iic_start();      
  194.            IICSendByte(write_ADD); //器件写地址
  195.            check_ACK();
  196.            if(F0 == 1)
  197.                    {     
  198.                            SystemError = 1;   
  199.                            return;
  200.                     }  
  201.                            IICSendByte(CFG_add); //寄存器地址
  202.                            check_ACK();
  203.                            if(F0 == 1)
  204.                                    {     
  205.                                            SystemError = 1;   
  206.                                             return;
  207.                                     }     
  208.                                     iic_start();      
  209.                                     IICSendByte(read_ADD); //器件读地址   
  210.                                            if(F0 == 1)
  211.                                                     {     
  212.                                                             SystemError = 1;   
  213.                                                             return;
  214.                                                             }
  215.                                                             while(n--)
  216.                                                             {      
  217.                                                                     receive_da=IICreceiveByte();   
  218.                                                                     buff[i++]=receive_da;   
  219.                                                                     slave_ACK();    // 收到一个字节后发送一个应答位
  220.                                                             }  
  221.                                                                     slave_NOACK();    // 收到最后一个字节后发送一个非应答位
  222.                                                               iic_stop();
  223.    }
  224. //--------------------------------------------------------------------------------------------------
  225. // 用户调用函数
  226. // 函数名称: P8563_Readtime  
  227. // 函数功能: 读出时间信息
  228. //--------------------------------------------------------------------------------------------------
  229. void P8563_Readtime()
  230. {   unsigned char time[7];      
  231.          receive_CFGNbyte(MIN,0x07,time);     
  232.          g8563_Store[0]=time[0]&0x7f; /*秒*/     
  233.          g8563_Store[1]=time[1]&0x7f; /*分*/     
  234.          g8563_Store[2]=time[2]&0x3f; /*小时*/     
  235.          g8563_Store[3]=time[4]&0x07; /*星期*/
  236.          }
  237. //--------------------------------------------------------------------------------------------------
  238. // 用户调用函数  // 函数名称: P8563_settime
  239. // 函数功能: 写时间修改值  
  240. //--------------------------------------------------------------------------------------------------         
  241. void P8563_settime()
  242. {      
  243. unsigned char i;      
  244.         for(i=2;i<=4;i++)
  245.         {
  246.                 write_CFGbyte(i,g8563_Store[i-2]);
  247.         }      
  248.                 write_CFGbyte(6,g8563_Store[3]);
  249.   }
  250. //--------------------------------------------------------------------------------------------------
  251. // 用户调用函数  // 函数名称: P8563_init // 函数功能: 初始设置  
  252. //--------------------------------------------------------------------------------------------------
  253. void P8563_init()
  254. {      
  255.          unsigned char i;      
  256.          if((receive_CFGbyte(0x0a))!=0x8) /*检查是否第一次启动,是则初始化时间*/     
  257.                  {         
  258.                          for(i=0;i<=3;i++)      
  259.                          g8563_Store[i]=c8563_Store[i]; /*初始化时间*/         
  260.                          P8563_settime();         
  261.                          write_CFGbyte(0x0,0x00);
  262.                          write_CFGbyte(0xa,0x8); /*8:00报警*/         
  263.                          write_CFGbyte(0x01,0x12); /*报警有效*/         
  264.                          write_CFGbyte(0xd,0xf0);     
  265.                          }
  266.          }
复制代码

评分

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

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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