有没有大师教教我PCA8565 RTC怎么使用的呐。调不出来了

2019-07-15 22:21发布

我用平时可以用的IIC总线进行操作,不是专门的IIC接口,一般的IIO进行操作,可是一直读取的是255,我现在怎么调都调不出来,不能在线仿真,只能烧写之后,观察现象。。
求指点
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
4条回答
怪兽跳跳糖
2019-07-16 09:14
zuohaiwen112 发表于 2013-9-26 19:34
把你的代码贴出来看看!不然怎么知道问题点在那?

我用的是STC15F2K32S单片机,IIC总线代码也是借鉴STC官网的模块进行改写的。现在出现的问题是一直读取的数据是0xff,不正常。
硬件我是用普通IO口做得SDA,SLK传输口。外部晶振是5.5296M。

请老师检查:
/**************************************
起始信号
**************************************/
void PCA8565_Start()
{
    SDA = 1;                    //拉高数据线
    SCL = 1;                    //拉高时钟线
    Delay5us();                 //延时
    SDA = 0;                    //产生下降沿
    Delay5us();                 //延时
    SCL = 0;                    //拉低时钟线
}

/**************************************
停止信号
**************************************/
void PCA8565_Stop()
{
    SDA = 0;                    //拉低数据线
    SCL = 1;                    //拉高时钟线
    Delay5us();                 //延时
    SDA = 1;                    //产生上升沿
    Delay5us();                 //延时
}

/**************************************
发送应答信号
入口参数:ack (0:ACK 1:NAK)
**************************************/
void PCA8565_SendACK(bit ack)
{
    SDA = ack;                  //写应答信号
    SCL = 1;                    //拉高时钟线
    Delay5us();                 //延时
    SCL = 0;                    //拉低时钟线
    Delay5us();                 //延时
}

/**************************************
接收应答信号
**************************************/
bit PCA8565_RecvACK()
{
    SCL = 1;                    //拉高时钟线
    Delay5us();                 //延时
    CY = SDA;                   //读应答信号
    SCL = 0;                    //拉低时钟线
    Delay5us();                 //延时
        LEDG ^= 1;
    return CY;
}

/**************************************
向IIC总线发送一个字节数据
**************************************/
void PCA8565_SendByte(unsigned char dat)
{
    unsigned char i;

    for (i=0; i<8; i++)         //8位计数器
    {
        dat <<= 1;              //移出数据的最高位
        SDA = CY;               //送数据口
        SCL = 1;                //拉高时钟线
        Delay5us();             //延时
        SCL = 0;                //拉低时钟线
        Delay5us();             //延时
    }
    PCA8565_RecvACK();
}

/**************************************
从IIC总线接收一个字节数据
**************************************/
unsigned char  PCA8565_RecvByte()
{
    unsigned char i;
    unsigned char dat = 0;

    SDA = 1;                    //使能内部上拉,准备读取数据
    for (i=0; i<8; i++)         //8位计数器
    {
        dat <<= 1;
        SCL = 1;                //拉高时钟线
        Delay5us();             //延时
        dat |= SDA;             //读数据
        SCL = 0;                //拉低时钟线
        Delay5us();             //延时
    }

    return dat;
}


/**************************************
向AT24C04写1页(16字节)数据
将TESTDATA开始的16个测试数据写如设备的00~0F地址中
**************************************/
void PCA8565_WritePage(unsigned char Addr,unsigned char date)
{
    unsigned char i;

    PCA8565_Start();            //起始信号
    PCA8565_SendByte(0xa2);     //发送设备地址+写信号
    PCA8565_SendByte(Addr);     //发送存储单元地址
    PCA8565_SendByte(date);
    PCA8565_Stop();             //停止信号
}


/**************************************
从AT24C04读取1页(16字节)数据
将设备的00~0F地址中的数据读出存放在DATA区的BUF中
**************************************/
unsigned char  PCA8565_ReadPage(unsigned char Addr)
{
        unsigned char tempA;

    PCA8565_Start();            //起始信号
    PCA8565_SendByte(0xa2);     //发送设备地址+写信号
    PCA8565_SendByte(Addr);     //发送存储单元地址
    PCA8565_Start();            //起始信号
    PCA8565_SendByte(0xa3);     //发送设备地址+读信号
    tempA = PCA8565_RecvByte();
        PCA8565_SendACK(1); //最后一个数据需要会NAK
    PCA8565_Stop();
        return tempA;             //停止信号
}


void TSetTime(void)//只初始化一次即可,是否初始化记录在eeprom中。上电读取,判断是否需要初始化
{
        PCA8565_WritePage(0x00,0x20);
        PCA8565_WritePage(0x08,1);Delay_ms(5);
        PCA8565_WritePage(0x07,2);        Delay_ms(5);
        PCA8565_WritePage(0x05,3);        Delay_ms(5);
        PCA8565_WritePage(0x04,4);        Delay_ms(5);
        PCA8565_WritePage(0x03,5);        Delay_ms(5);
        PCA8565_WritePage(0x02,6); //Second

        PCA8565_WritePage(0x00,0);//开始时间机器,这个寄存器可以不设置,直接默认即可               
}

void TGetTime(void)
{
        dateTime.year = PCA8565_ReadPage(0x08);  
        dateTime.month = PCA8565_ReadPage(0x07);
        dateTime.day = PCA8565_ReadPage(0x05);          
        dateTime.hour = PCA8565_ReadPage(0x04);   
        dateTime.minute = PCA8565_ReadPage(0x03);
        dateTime.second = PCA8565_ReadPage(0x02);

}

这是我按照数据手册写的读取时间模块:
        PCA8565_Start();
        PCA8565_SendByte(0xa2);
        //AT24C04_SendByte(0x02);
        PCA8565_Stop();
        PCA8565_SendByte(0xa3);
        dateTime.year = PCA8565_ReadPage(0x08);  
        dateTime.month = PCA8565_ReadPage(0x07);
        dateTime.day = PCA8565_ReadPage(0x05);          
        dateTime.hour = PCA8565_ReadPage(0x04);  
        AT24C04_Stop();





一周热门 更多>