数码之家

 找回密码
 立即注册
搜索
查看: 5704|回复: 23

STM32 利用i2c驱动rx8025sa芯片 时间不更新

[复制链接]
发表于 2021-9-24 11:32:52 | 显示全部楼层 |阅读模式
STM32 利用i2c驱动rx8025sa芯片 时间不更新
调试后发现往rx8025sa寄存器写数据写不进去


读出的时间只是设置的初始时间,将rx8025sa移除,还能够输出时间 ,I2c未驱动成功rx8025sa是怎么回事,求大佬帮助

本帖子中包含更多资源

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

x
 楼主| 发表于 2021-9-24 11:35:16 | 显示全部楼层
如下rx025两个驱动函数

unsigned char RX8025_Read(unsigned char addr)
{
        u8 date;
                                IIC_Start();
                                IIC_Send_Byte(0x64);        
                                IIC_Ack();
                                IIC_Send_Byte(addr<<4);
                                IIC_Ack();
                                IIC_Start();
                                IIC_Send_Byte(0x65);        
                                IIC_Ack();
                                date=IIC_Read_Byte();                        
                                IIC_NAck();
                                IIC_Stop();
                                return date;
}

void RX8025_Write(u8 addr,u8 date)
{
        IIC_Start();
                                IIC_Send_Byte(0x64);        
                                IIC_Ack();
                                IIC_Send_Byte(addr<<4);                        
回复 支持 反对

使用道具 举报

发表于 2021-9-24 11:54:10 来自手机浏览器 | 显示全部楼层
看一下写数据的时序对不对?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-9-24 11:56:11 | 显示全部楼层
触景情伤 发表于 2021-9-24 11:54
看一下写数据的时序对不对?

老哥帮忙看一下 困扰一个礼拜了
void RX8025_Write(u8 addr,u8 date)
{
        IIC_Start();
                                IIC_Send_Byte(0x64);        
                                IIC_Ack();
                                IIC_Send_Byte(addr<<4);                        
                                IIC_Ack();
                                IIC_Send_Byte(date);                       
                                IIC_Ack();
                                IIC_Stop();
}
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-9-24 12:01:18 | 显示全部楼层
本帖最后由 dddz 于 2021-9-24 12:20 编辑
触景情伤 发表于 2021-9-24 11:54
看一下写数据的时序对不对?

老哥帮忙看一下 去除Rx8025sa 也能输出设置的时间

回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-9-24 12:10:42 | 显示全部楼层
void RX8025_Write(u8 addr,u8 date)
{
                                IIC_Start();
                                IIC_Send_Byte(0x64);      
                                IIC_Ack();
                                IIC_Send_Byte(addr<<4);                        
                                IIC_Ack();
                                IIC_Send_Byte(date);                        
                                IIC_Ack();
                                IIC_Stop();
}
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-9-24 12:17:24 | 显示全部楼层
void Rx8025_Init(void)
{
        RX8025_Write(RX8025_ADDR_CONTROL2,0x00);//清除所有标志       
        RX8025_Write(RX8025_ADDR_CONTROL1,0x20);
                        printf("%x\r\n",RX8025_Read(RX8025_ADDR_CONTROL1));

}

void SetTimeToRX8025(u8 *TimeBuf)
{//year,week,month,day,hour,minute,second
        u8 Count;
  for(Count=0;Count<7;Count++){
    EEbuf[Count]=*(TimeBuf+6-Count);
                RX8025_Write(Count,EEbuf[Count]);
  }
}

u8 Set_Time(u16 year,u8 month,u8 day,u8 hour,u8 minute,u8 second)
{
         u8 tmpBuf[7],i;
         tmpBuf[0]=year%0x07D%100;
         tmpBuf[1]=month;
         tmpBuf[2]=day;
         tmpBuf[3]=RTC_Get_Week(year,month,day);        //自动计算星期几
         if(tmpBuf[3]==7) tmpBuf[3]=0;
         tmpBuf[4]=hour;
         tmpBuf[5]=minute;
         tmpBuf[6]=second;
         for(i=0;i<7;i++){
                tmpBuf[i]=HEX_To_BCD(tmpBuf[i]);
         }

         SetTimeToRX8025(tmpBuf);
         return 0;
}
回复 支持 反对

使用道具 举报

发表于 2021-9-24 15:36:55 来自手机浏览器 | 显示全部楼层
dddz 发表于 2021-9-24 11:56
老哥帮忙看一下 困扰一个礼拜了
void RX8025_Write(u8 addr,u8 date)
{

找个能正确读时间的程序用逻辑分析仪看一下时序对不对,代码的话我不懂,大部分都是粘贴复制…
回复 支持 反对

使用道具 举报

发表于 2021-9-24 19:24:26 | 显示全部楼层
建议在网上找一个STM32的I2C驱动RX8025AC的代码试试看,因为STM32与C51的I2C速度或许不同。
回复 支持 反对

使用道具 举报

发表于 2021-9-24 20:03:09 | 显示全部楼层
本帖最后由 inthsunshine 于 2021-9-24 20:37 编辑

寄存器地址错了吧

比如小时寄存器,实际地址不是02h, 而是20h
回复 支持 反对

使用道具 举报

发表于 2021-9-24 22:48:08 | 显示全部楼层
inthsunshine 发表于 2021-9-24 20:03
寄存器地址错了吧

比如小时寄存器,实际地址不是02h, 而是20h

RX8025T 小时寄存器就是02H, 没有错。
回复 支持 反对

使用道具 举报

发表于 2021-9-25 00:04:50 | 显示全部楼层



/**************************************************************************
* 函数名: void I2C_delay(void)
* 描述  : 短暂延时
* 输入  : 无
* 输出  : 无
* 说明  : 内部定义的i可以优化速度,经测试最低到5还能写入
*****************************************unsigned char********************************/
static void I2C_delay(void)
{
    unsigned char i = 5;
    while(i)
    {
        i--;
    }
}


/**************************************************************************
* 函数名: void I2C_Start(void)
* 描述  : 起始信号
* 输入  : 无
* 输出  : 无
* 说明  :
***************************************************************************/
void I2C_Start(void)
{
    SCL_H;
    I2C_delay();
    SDA_H;
    I2C_delay();
    SDA_L;
    I2C_delay();
    SCL_L;
    I2C_delay();
}


/**************************************************************************
* 函数名: I2C_Stop(void)
* 描述  : 终止信号
* 输入  : 无
* 输出  : 无
* 说明  :
***************************************************************************/
void I2C_Stop(void)
{
    SDA_L;
    I2C_delay();
    SCL_H;
    I2C_delay();
    SDA_H;
    I2C_delay();
}





/**************************************************************************
* 函数名: void I2C_Ack(void)
* 描述  : 应答信号
* 输入  : 无
* 输出  : 无
* 说明  :
***************************************************************************/
/*

void I2C_Ack(void)
{
   SCL_L;  I2C_delay();
   SDA_L;  I2C_delay();
   SCL_H;  I2C_delay();
   SCL_L;  I2C_delay();
}

*/
/**************************************************************************
* 函数名: void I2C_NoAck(void)
* 描述  : 无应答信号
* 输入  : 无
* 输出  : 无
* 说明  :
***************************************************************************/

/*
void I2C_NoAck(void)
{
   SCL_L;  I2C_delay();
   SDA_H;  I2C_delay();
   SCL_H;  I2C_delay();
   SCL_L;  I2C_delay();
}
*/

/***************unsigned char*********************************************************
* 函数胾nsigned char unsigned char I2C_WaitAck(void)
* 描述  : 等待应答信号
* 输入  : 无
* 输出  : TRUE : 有应答
           FALSE : 无应答
* 说明  :
*********************************************************unsigned char****************/



unsigned char I2C_WaitAck(void)
{
    unsigned char ucErrTime = 0;
    SCL_L;
    I2C_delay();
    SDA_H;
    I2C_delay();
    SCL_H;
    I2C_delay();
    while(SDA_RX8025T == 1)
    {
        ucErrTime++;
        if(ucErrTime > 250)
        {
            I2C_Stop();
            return 0;
        }
    }
    SCL_L;
    return 1;
}


/**************************************************************************
* 函数名: void I2C_SendByunsigned char(unsigned char SendByte)
* 描述  : 发送一个字节
* 输入  : SendByte : 字节数据
* 输出  : 无
* 说明  : 数据从高位到低位
*********************************************************************unsigned char****/
void I2C_SendByte(unsigned char SendByte)
{
    unsigned char i = 8;
    while(i--)
    {
        SCL_L;
        I2C_delay();

        if(SendByte & 0x80)

            SDA_RX8025T = 1;
        else
            SDA_RX8025T = 0                                                                                                                                                                                                                                                                                                              ;

        SendByte <<= 1;

        I2C_delay();

        SCL_H;

        I2C_delay();
    }
    SCL_L;
}


/**************************************************************************
* 函数胾nsigned char unsigned char I2C_ReceiveByte(void)
* 描述  : 读取一个字节
* 输入  : 无
* 输出  : 字节数据
* 说明  : ReceiveByte : 数据从高位到低位
****************************************************unsigned char*********************/
unsigned char I2C_ReceiveByte(void)
{
    unsigned char i = 8;
    unsigned char ReceiveByte = 0;

    SDA_H;
    while(i--)
    {
        ReceiveByte <<= 1;
        SCL_L;
        I2C_delay();
        SCL_H;
        I2C_delay();
        if(SDA_RX8025T == 1)
        {
            ReceiveByte |= 0x01;
        }
    }
    SCL_L;
    return ReceiveByte;
}




#include "RX8025T.h"
#include "i2c_soft.h"
//#include "delay.h"

Calendar_OBJ calendar;

#define RX8025T_WriteAddress        0x64
#define RX8025T_ReadAddress         0x65

unsigned char BCD2HEX(unsigned char val)
{
    unsigned char i;
    i = val & 0x0f;
    val >>= 4;
    val &= 0x0f;
    val *= 10;
    i += val;

    return i;
}


unsigned int B_BCD(unsigned char val)
{
   unsigned char i,j,k;
   i=val/10;
   j=val%10;
   k=j+(i<<4);
   return k;
}


void RX8025T_WR_Byte(unsigned char addr, unsigned char bytedata)
{
    I2C_Start();
    I2C_SendByte(RX8025T_WriteAddress);
    I2C_WaitAck();
    I2C_SendByte(addr);
    I2C_WaitAck();
    I2C_SendByte(bytedata);
    I2C_WaitAck();
    I2C_Stop();
}


unsigned char RX8025T_RD_Byte(unsigned char addr)
{
    unsigned char Dat = 0;

    I2C_Start();
    I2C_SendByte(RX8025T_WriteAddress);
    I2C_WaitAck();
    I2C_SendByte(addr);
    I2C_WaitAck();
    I2C_Start();
    I2C_SendByte(RX8025T_ReadAddress);
    I2C_WaitAck();
    Dat = I2C_ReceiveByte();
    I2C_Stop();

    return Dat;
}


void RX8025T_Init(void)
{
    // I2C_GPIO_Config();
    RX8025T_WR_Byte(0x0e, 0);
    //    delay_ms(2);
    RX8025T_WR_Byte(0x0f, 0x0);
    // delay_ms(2);

  //         Set_RX8025T_Time(21,4,25,18,9,00,7);

}

  /*
void Set_RX8025T_Time(unsigned char yea,unsigned char mon,unsigned char da,unsigned char hou,unsigned char min,unsigned char sec,unsigned char week)
{
   unsigned char temp=0;

   temp=B_BCD(yea);
   RX8025T_WR_Byte(0x06,temp);

   temp=B_BCD(mon);
   RX8025T_WR_Byte(0x05,temp);

   temp=B_BCD(da);
   RX8025T_WR_Byte(0x04,temp);

   temp=B_BCD(hou);
   RX8025T_WR_Byte(0x02,temp);

   temp=B_BCD(min);
   RX8025T_WR_Byte(0x01,temp);

   temp=B_BCD(sec);
   RX8025T_WR_Byte(0x00,temp);

   temp=B_BCD(week);
   RX8025T_WR_Byte(0x03,temp);
}
  */



void Get_RX8025T_Time(void)
{
    calendar.w_year = RX8025T_RD_Byte(0x06);
    calendar.w_year = BCD2HEX(calendar.w_year);

    calendar.w_month = RX8025T_RD_Byte(0x05);
    calendar.w_month = BCD2HEX(calendar.w_month);

    calendar.w_date = RX8025T_RD_Byte(0x04);
    calendar.w_date = BCD2HEX(calendar.w_date);

    calendar.hour = RX8025T_RD_Byte(0x02);
    calendar.hour &= 0x3f;
    calendar.hour = BCD2HEX(calendar.hour);

    calendar.min = RX8025T_RD_Byte(0x01);
    calendar.min = BCD2HEX(calendar.min);

    calendar.sec = RX8025T_RD_Byte(0x00);
    calendar.sec = BCD2HEX(calendar.sec);

    calendar.week = RX8025T_RD_Byte(0x03);
    calendar.week = BCD2HEX(calendar.week);

    RX8025T_WR_Byte(0x0e, 0x20);

    calendar.temper_H = RX8025T_RD_Byte(0x11);
    calendar.temper_L = (RX8025T_RD_Byte(0x12) >> 6) * 25;



}



回复 支持 反对

使用道具 举报

发表于 2021-9-25 06:53:11 | 显示全部楼层
本帖最后由 inthsunshine 于 2021-9-25 07:08 编辑
广东梁百万 发表于 2021-9-24 22:48
RX8025T 小时寄存器就是02H, 没有错。

lz用的是SA, 所以地址要留意一下,T的没这问题
回复 支持 反对

使用道具 举报

发表于 2021-9-25 11:39:37 | 显示全部楼层
dddz 发表于 2021-9-24 11:35
如下rx025两个驱动函数

unsigned char RX8025_Read(unsigned char addr)

IIC_Ack(); 应该用等待应答的函数吧?
回复 支持 反对

使用道具 举报

发表于 2021-9-25 12:45:15 | 显示全部楼层
inthsunshine 发表于 2021-9-25 06:53
lz用的是SA, 所以地址要留意一下,T的没这问题

SA的需要address<<4来解决这个问题,我在C51单片机驱动RX8025AC时已经验证了的,楼主的代码也体现了这个操作,但我不知道STM32的I2C与C51的I2C是否有不同之处致使操作不正常。
回复 支持 反对

使用道具 举报

发表于 2021-9-25 13:03:37 | 显示全部楼层

stm32驱动8025AC我试过,没问题,不过用的IO模拟,不是硬件I2C
回复 支持 反对

使用道具 举报

发表于 2021-9-25 13:17:54 | 显示全部楼层
inthsunshine 发表于 2021-9-25 13:03
stm32驱动8025AC我试过,没问题,不过用的IO模拟,不是硬件I2C

就我的经验而言,同一段模拟I2C用于普通C51是好用的而用于STC的1T单片机时底层的读写代码就要加就几条延时,虽然我现在使用STC单片机时但凡有片内I2C总线的我都是用硬件I2C,而几种时间芯片驱动的模拟I2C也没问题的,RX8025T和RX8025AC我前些时都玩过的,而且也有在这里发帖分享,但玩的都不深入出现问题也弄不太明白的。
回复 支持 反对

使用道具 举报

发表于 2021-9-25 15:12:23 | 显示全部楼层
慕名而来 发表于 2021-9-25 13:17
就我的经验而言,同一段模拟I2C用于普通C51是好用的而用于STC的1T单片机时底层的读写代码就要加就几条延 ...

网传stm32的硬件I2C有bug,  我没试过, 低速串口模拟一下也很方便

SPI一定要用硬件了,模拟不过来, 我现在对SPI比较兴趣,I2C自带底层协议,罗里罗嗦,而应用芯片的SPI口设置就比较简单,直接把寄存器地址和参数放一起凑成8位或者16位发出去,不需要I2C那样的固定格式
回复 支持 反对

使用道具 举报

发表于 2021-9-25 19:45:08 | 显示全部楼层
inthsunshine 发表于 2021-9-25 15:12
网传stm32的硬件I2C有bug,  我没试过, 低速串口模拟一下也很方便

SPI一定要用硬件了,模拟不过来, 我 ...

STM32只是跑了几个例程实验了一下,没有深入学习,我只是做时钟或简单的控制也用不到太复杂的东西,所以我一般只玩STC,感觉这货简单好弄例程丰富,焊板子的时候只要预留一个4针插脚而后供电、调试代码、后期升级控制等等就全简单了,而STM32要麻烦许多(或许是我不熟悉)至今没有焊过STM32的最小系统板子,而STC15系的单片机焊板子的时候只要连接正负电源+两个串口引脚+用到的I/O即可,至于晶振、电容、复位、下载等等都不用理会了真心省事,感觉如果未来在单片机一途中有目标的话STM32或许是绕不开的知识,而只是业余爱好玩玩而已的话也就没必要追求高远了,至少我的做法是弄几个熟悉的芯片玩一些简单的控制足矣,当遇到必须用STM32控制的东西时利用例程照葫芦画瓢的也过得去就可以了。
回复 支持 反对

使用道具 举报

发表于 2021-9-25 20:18:26 | 显示全部楼层
慕名而来 发表于 2021-9-25 19:45
STM32只是跑了几个例程实验了一下,没有深入学习,我只是做时钟或简单的控制也用不到太复杂的东西,所以 ...

是的,stm32和stc51适合不同的场景,如果说复杂,stm32也不复杂,只是操作的规矩不同而已,适应了也就那样,stm32也可以使用片内时钟无需晶振电容什么的,一般还是会外接晶振,调试的话用专用的SWD接口(占用2根IO)也很方便速度快

stm32最小系统,我自己曾经画了一块板,开始用不同cpu焊了几块,因为杜邦头接触不好,现在也不怎么用最小系统,直接把板子做好,留个调试口直接玩,更简单些
回复 支持 反对

使用道具 举报

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

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-5-6 11:02 , Processed in 0.280800 second(s), 10 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

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