问答

汇集网友智慧,解决技术难题

21ic问答首页 - 关于GD32f103读取AT24C02总是读不准的疑问

关于GD32f103读取AT24C02总是读不准的疑问

zhczlzhang2022-07-26
        如题所示,我第一次使用GD32f103代替stm32,在IIC读取24C02这里出问题了,代码是在stm32上面验证过了,没有问题。为了可移植行,就没有使用GD32的固件库IIC,而是硬件模拟IIC。        但是在GD32上面时,就是存储进去是0x01,读出来是0xc0,写入时0x07,读出来是0x08,写入时0x55,读出来是0x56.
        调试了半天,延时之类的都试过了,感觉还是时序的问题,但是手上没有示波器,只能靠猜,请大家帮忙。
    IIC_Init();
    delay_1ms(1000);
    AT24C02_SaveROWSta(AT24C02_row1,0x01);
    delay_1ms(1000);
    // temp = AT24C02_ReadOneByte(AT24C02_row1);
    send_485(AT24C02_ReadOneByte(AT24C02_row1),1);
    //以上是在main中的代码

    void AT24C02_SaveROWSta(uint8_t row,uint8_t sta1)
{
    AT24C02_WriteOneByte(0,0x55);                //24C02 地址0 写入0x55
    AT24C02_WriteOneByte(row,sta1);              //24C02 地址 写入保存的行列的状态
}

void AT24C02_WriteOneByte(unsigned char WriteAddr,unsigned char DataToWrite)
{                                                                                            
    IIC_Start();                    //开始信号
    IIC_Send_Byte(AT24C02_WADDR);   //发送器件地址+写操作     
    IIC_Wait_Ack();                 //等待应答
    IIC_Send_Byte(WriteAddr);       //发送写入数据的目的地址
    IIC_Wait_Ack();                 //等待应答                                             
    IIC_Send_Byte(DataToWrite);     //发送要写入的数据                             
    IIC_Wait_Ack();                 //等待应答     
    IIC_Stop();                     //停止信号  
    Delay_Ms(5);                    //延迟
}

unsigned char AT24C02_ReadOneByte(unsigned char ReadAddr)
{                 
    unsigned char receive;         //定义一个变量用于保存接收到的数据

    receive = 0;                   //清除receive,准备接收数据
    IIC_Start();                   //IIC开始信号
    IIC_Send_Byte(AT24C02_WADDR);  //发送24c02器件地址+写操作        
    IIC_Wait_Ack();                //等待应答
    IIC_Send_Byte(ReadAddr);       //发送需要读数据的地址
    IIC_Wait_Ack();                //等待应答
    IIC_Start();                   //IIC开始信号
    IIC_Send_Byte(AT24C02_RADDR);  //发送24c02器件地址+读操作                  
    IIC_Wait_Ack();                //等待应答
    receive=IIC_Read_Byte(0);      //读一字节数据,保存在receive变量中   
    IIC_Stop();                    //停止信号
    Delay_Ms(5);                   //延迟
    return receive;                //返回读取的数据
}
//以上是24c02中的代码
void IIC_Send_Byte(unsigned char txd)
{                        
    unsigned char t;                   //定义一个变量用于for循环

    SDA_OUT();                         //SDA线输出模式
    IIC_SCL_L;                         //SCL拉低,开始数据传输
    for(t=0;t<8;t++){                  //for循环,一位一位的发送,从最高位 位7开始                 
        IIC_SDA_OUT(((txd&0x80)>>7));  //给SDA数据线
        txd<<=1;                       //左移一位,准备下一次发送
        Delay_Us(2);                   //延时
        IIC_SCL_H;                     //SCL拉高
        Delay_Us(2);                   //延时
        IIC_SCL_L;                     //SCL拉低
        Delay_Us(2);
    }   
}
unsigned char IIC_Read_Byte(unsigned char ack)
{
    unsigned char i;           //定义一个变量用于for循环
    unsigned char receive;     //定义一个变量用于保存接收到的数据

    SDA_IN();//SDA设置为输入
    for(i=0;i<8;i++ )
    {
        IIC_SCL_L;
        Delay_Us(2);
        IIC_SCL_H;
        receive<<=1;
        if(READ_SDA)receive++;   
        Delay_Us(1);
    }
        if (!ack)
    {
        SDA_OUT();   //SDA线输出模式
        IIC_SDA_H;   //时钟脉冲的高电平期间保持稳定的高电平
        IIC_SCL_H;   //SCL拉高
        Delay_Us(2); //延时
        IIC_SCL_L;   //SCL拉低
    }

    else
    {
        SDA_OUT();   //SDA线输出模式
        IIC_SDA_L;   //时钟脉冲的高电平期间保持稳定的低电平
        IIC_SCL_H;   //SCL拉高
        Delay_Us(2); //延时
        IIC_SCL_L;   //SCL拉低
        IIC_SDA_H;   //SDA拉高        
    }
    return receive;
}
//代码基本上就是这样,在stm32中测试没有这个现象,GD32f103中就有了,请大家指点一下。










       




回答 +关注 15
943人浏览 1人回答问题 分享 举报
1 个回答
  • 已经找到问题了,程序存储进去0X55,然后在程序内部运算,如果等于0x55,就发送01,否则就发送02,然后我就接收到01,看来应该是在转化读取24c02获得的数值转化为串口数据过程中出现了问题,暂时还没找到那里的问题。

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