STM32
直播中

张华

7年用户 1335经验值
私信 关注
[问答]

IIC读数据,数据读出来是错误,为什么?

void BEKEN_I2C_Start(void)
{
        BK_SCL_H;
        BK_SDA_H;
        Delay1us;//(28us)
        BK_SDA_L;//START:when CLK is high,DATA change form high to low
        Delay1us;//延时要大于4.7us
        BK_SCL_L;//钳住I2C总线,准备发送或接收数据
        Delay1us;
}
void BEKEN_I2C_Stop(void)
{
        BK_SCL_L;//标记MPU_SCL_H
        BK_SDA_L;//STOP:when CLK is high DATA change form low to high
        Delay1us;
        BK_SCL_H;//标记MPU_SDA_H
        Delay1us;
        BK_SDA_H;//标记MPU_SCL_H
        Delay1us;
}
u8 BEKEN_I2C_ReceiveACK(void)
{
        /*u16 i,j;
        i=700;
        BK_SDA_H;
        //Delayus(4);
        BK_SCL_H;
        Delay1us;
        while(BK_SDA_read)//从机拉低数据线代表收到数据
        {
                i--;//延时等待一定的时间,例如可以等待0.5毫秒或者循环读2000次ACK,如果超过这个时间没有响应,就返回失败信息
                Delay1us;
        if(i<10)
        {
            BK_SCL_L;
            return TRUE;//1
        }
        }
        BK_SCL_L;
        Delay1us;
        return FALSE;//0*/
        
        BK_SCL_L;
        Delay1us;
        BK_SCL_H;
        Delay1us;
        if(BK_SDA_read)
        {
                BK_SCL_L;
                return TRUE;
        }
        BK_SCL_L;
    Delay1us;
        return FALSE;
}
void BEKEN_I2C_ack(void)
{
        BK_SCL_L;//标记,这里之前没有的
        BK_SDA_L;
    Delay1us;
    BK_SCL_H;
    Delay1us;
    BK_SCL_L;
    Delay1us;
}
void BEKEN_I2C_nack(void)
{
        BK_SCL_L;//标记,这里之前没有的
        BK_SDA_H;
    Delay1us;
    BK_SCL_H;
    Delay1us;
    BK_SCL_L;
    Delay1us;
}
void BEKEN_I2C_sendbyte(u8 val)
{
        u8 i;
        BK_SCL_L;//拉低时钟开始传输数据
        for(i=0;i<8;i++)
        {
                if(val 0x80)
                        BK_SDA_H;
                else
                        BK_SDA_L;
                val<<=1;
                BK_SCL_H;
                Delay1us;
                BK_SCL_L;
                Delay1us;
        }
}
u8 BEKEN_I2C_readbyte(void)
{
        u8 i,j,read_data=0;
        BK_SDA_H;
        for(i=0;i<8;i++)
        {
                read_data<<=1;
                BK_SCL_L;
                Delay1us;
                BK_SCL_H;
                Delay1us;
                if(BK_SDA_read)
                        read_data|=0x01;
        }
        BK_SCL_L;
    return read_data;
}



/*************************************************
  Function:       BEKEN_I2c_Write
  Description:    write a array
  Input:          reg: register number
                  pBuff: a buffer contain written data
                  len:the length of written data      
  Output:         None
  Return:         None
*************************************************/
void BEKEN_I2c_Write(u8 reg,u8 *pBuf,u8 len)
{
    u8 i;
    u8 Addr;
    Addr=dev_addr;//device address.

    if(reg <= 0x0b)       //Analog registers saved by analog_reg_val[][] for read operation
    {
        analog_reg_val[reg][0] = pBuf[0];
        analog_reg_val[reg][1] = pBuf[1];
        analog_reg_val[reg][2] = pBuf[2];
        analog_reg_val[reg][3] = pBuf[3];
    }

    BEKEN_I2C_Start();
    BEKEN_I2C_sendbyte(Addr);
    BEKEN_I2C_ReceiveACK();

    reg=reg<<1;
    BEKEN_I2C_sendbyte(reg);   
    BEKEN_I2C_ReceiveACK();
         
    for(i=0;i>8);
                pBuf[1] =(u8)(SW_VERSION_NO 0x00ff);
                #ifdef DEBUG_INFO
                pBuf[0] =(u8)((debug_info 0xff00)>>8);
                pBuf[1] =(u8)(debug_info 0x00ff);
                #endif
        }
}

回帖(1)

李平

2024-5-9 16:39:46
在I2C通信中,如果读取到的数据是错误的,可能有以下几个原因:

1. 起始条件不满足:在I2C通信中,起始条件是SCL为高电平,SDA从高电平跳变为低电平。在你的代码中,BK_SCL_H和BK_SDA_H将SCL和SDA都设置为高电平,然后BK_SDA_L将SDA设置为低电平。这个过程中,如果SCL没有保持高电平,那么起始条件就不满足。

2. 时钟同步问题:I2C通信需要严格的时钟同步。在你的代码中,Delay1us用于控制SCL和SDA的跳变时间。如果这个延时不准确,可能会导致通信错误。你需要确保这个延时足够长,以满足I2C协议的要求。

3. 地址或寄存器设置错误:在I2C通信中,你需要发送正确的设备地址和寄存器地址,才能读取到正确的数据。如果地址或寄存器设置错误,可能会导致读取到错误的数据。

4. 数据传输错误:在数据传输过程中,如果SCL或SDA的电平跳变不符合I2C协议的要求,可能会导致数据传输错误。

5. 硬件问题:如果I2C总线上的硬件设备存在问题,如线路干扰、设备损坏等,也可能导致读取到错误的数据。

为了解决这个问题,你可以尝试以下方法:

1. 确保起始条件满足:在设置SDA为低电平时,确保SCL保持高电平。

2. 调整延时:尝试调整Delay1us的值,以满足I2C协议的时钟要求。

3. 检查地址和寄存器设置:确保你发送的设备地址和寄存器地址是正确的。

4. 检查硬件连接:检查I2C总线上的硬件设备,确保没有线路干扰或设备损坏。

5. 使用示波器或逻辑分析仪:使用示波器或逻辑分析仪观察I2C总线上的信号,以便于发现问题所在。

6. 参考数据手册:仔细阅读I2C设备的数据手册,确保你的代码符合I2C协议的要求。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分