wangxiangtan 发表于 2025-2-16 18:34:15

小白学单片机记录之软件模拟IIC读写PCF8563时钟RTC数据

对于面向复制粘贴编程的我来说可真不容易,折腾了整整一上午才搞定。
试了多家的代码才测试成功。MCU为STC8H3K32S2,PCF8563T为马宝2.11大洋买的:







13点设置好RTC数据时差不到一秒,17点再看时,已经差了2秒了,
这时钟模块也不靠谱啊:





寄存器里面是BCD码格式,往里面写、读出来显示的时候都要做转换,
一开始直接读、写十进制发现咋整都不对,后面才改正过来。
粘上代码备查备用:

#include "bsp_pcf8563.h"
unsigned char timeBuffer;
void IIC_Delay()
{
      _nop_(); _nop_();      _nop_();      _nop_();      _nop_();      _nop_();
      _nop_(); _nop_(); _nop_();      _nop_();      _nop_();      _nop_();
      _nop_(); _nop_(); _nop_();
}
void IIC_Start(void)
{
      IIC_SDA = 1;      //为SDA下降启动做准备
      IIC_SCL = 1;      //在SCL高电平时,SDA为下降沿时候总线启动
      IIC_Delay();
      IIC_SDA = 0;      //突变,总线启动
      IIC_Delay();
      IIC_SCL = 0;
      IIC_Delay();
}
void IIC_Stop(void)
{
      IIC_SDA = 0;      //为SDA上升做准备
      IIC_Delay();
      IIC_SCL = 1;      //在SCL高电平时,SDA为上升沿时候总线停止
      IIC_Delay();
      IIC_SDA = 1;      //突变,总线停止
      IIC_Delay();
}
void IIC_Ack(unsigned char a)
{
      if(a)      IIC_SDA = 1;      //放上应答信号电平
      else      IIC_SDA = 0;
      IIC_Delay();
      IIC_SCL = 1;      //为SCL下降做准备
      IIC_Delay();
      IIC_SCL = 0;      //突变,将应答信号发送过去
      IIC_Delay();
}unsigned char IIC_Write_Byte(unsigned char dat)
{
      unsigned char i;
      unsigned char iic_ack=0;      //iic应答标志
      for(i = 0;i < 8;i++)
      {
                if(dat & 0x80)      IIC_SDA = 1;      //判断发送位,先发送高位
                else      IIC_SDA = 0;
                IIC_Delay();
                IIC_SCL = 1;      //为SCL下降做准备
                IIC_Delay();
                IIC_SCL = 0;      //突变,将数据位发送过去
                dat<<=1;      //数据左移一位
      }      //字节发送完成,开始接收应答信号
      IIC_SDA = 1;      //释放数据线
      IIC_Delay();
      IIC_SCL = 1;      //为SCL下降做准备
      IIC_Delay();
      //字节发送完成,开始接收应答信号
      iic_ack |= IIC_SDA;      //读入应答位
      IIC_SCL = 0;
      return iic_ack;      //返回应答信号
}读到数据后串口发送出来即可:

void main(void)
{
      sTime timeNow;
      char timeString;
      EAXSFR();                /* 扩展寄存器访问使能 */
      //开启中断0:INT0
      IT0 = 1;//0为上升下降沿触发;1为低电平触发;
      EX0 = 1;
      GPIO_config();      
      Uart1Init();
      ES = 1;
      EA = 1;
      Timer0_Init();
      timeNow.year=25;
      timeNow.mon=2;
      timeNow.week = 0;
      timeNow.day=16;
      timeNow.hour=13;
      timeNow.min=0;
      timeNow.sec = 0;
Bsp_Pcf8563_Init();
      while(1)
      {
                KeyTask();
                if(test1000ms == 1000)
                {
                        P54 = !P54;
                        test1000ms = 0;
                        MyGetTime(&timeNow);
                        sprintf(timeString, "20%02d-%02d-%02d %02d:%02d:%02d",(int)timeNow.year,(int)timeNow.mon,(int)timeNow.day,(int)timeNow.hour,(int)timeNow.min,(int)timeNow.sec);
                        Uart1SendStr(timeString);
                }      
      }
}      完整工程“Clock-STC8H3K32S2点灯+串口+按键+定时器+iic读PCF8563.rar”:









wangcong 发表于 2025-2-17 07:48:32

{:qiang:}
页: [1]
查看完整版本: 小白学单片机记录之软件模拟IIC读写PCF8563时钟RTC数据