CH582 I2C读取卡死问题

尝试使用582的硬件I2C读取从机寄存器,但是发现会卡在mode_select,不知道该如何解决了

代码参考了:

http://www.wch.cn/index.php/bbs/thread-86122-1.html

http://bbs.eeworld.com.cn/thread-1196656-1-1.html

void?i2c_read_reg(uint8_t?addr,?uint8_t?reg,?uint8_t?data_len,?uint8_t?*data)
{
????uint8_t?i?=?0;
????printf("busy1\n");
????while?(I2C_GetFlagStatus(I2C_FLAG_BUSY)?!=?RESET)
????????;
????printf("busy2\n");
????I2C_GenerateSTART(ENABLE);
????printf("modeselect1\n");
????while?(!I2C_CheckEvent(I2C_EVENT_MASTER_MODE_SELECT))
????????;
????printf("modeselect2\n");
????I2C_Send7bitAddress(addr,?I2C_Direction_Receiver);
????printf("rmodeselect1\n");
????while?(!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
????????;
????printf("rmodeselect2\n");
????if?(I2C_GetFlagStatus(I2C_FLAG_TXE)?!=?RESET)
????{
????????printf("send?reg\n");
????????I2C_SendData(reg);
????}
????printf("rmodeselect1\n");
????while?(!I2C_CheckEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
????????;
????printf("rmodeselect2\n");
????if?(data_len?==?1)
????{
????????I2C_GenerateSTOP(ENABLE);
????????printf("I2C_FLAG_RXNE?1\n");
????????if?(I2C_GetFlagStatus(I2C_FLAG_RXNE)?!=?RESET)
????????{
????????????printf("I2C_FLAG_RXNE?2\n");
????????????*data?=?I2C_ReceiveData();
????????}
????}
????else
????{
????????while?(i?<?(data_len))
????????{
????????????if?(I2C_GetFlagStatus(I2C_FLAG_RXNE)?!=?RESET)
????????????{
????????????????data[i]?=?I2C_ReceiveData();
????????????????i++;
????????????????if?(i?==?(data_len?-?1))
????????????????{
????????????????????I2C_GenerateSTOP(ENABLE);
????????????????}
????????????}
????????}
????}
}

int?main()
{
????uint8_t?len?=?0;
????int?err?=?0;
????SetSysClock(CLK_SOURCE_PLL_32MHz);

????/*?配置串口1:先配置IO口模式,再配置串口?*/
????GPIOA_SetBits(GPIO_Pin_9);
????GPIOA_ModeCfg(GPIO_Pin_8,?GPIO_ModeIN_PU);??????//?RXD-配置上拉输入
????GPIOA_ModeCfg(GPIO_Pin_9,?GPIO_ModeOut_PP_5mA);?//?TXD-配置推挽输出,注意先让IO口输出高电平
????UART1_DefInit();

????printf("hello\n");

????GPIOB_ModeCfg(GPIO_Pin_13?|?GPIO_Pin_12,?GPIO_ModeIN_PU);

????I2C_SoftwareResetCmd(ENABLE);
????I2C_SoftwareResetCmd(DISABLE);

????I2C_Init(I2C_Mode_I2C,?100000,?I2C_DutyCycle_16_9,?I2C_Ack_Enable,?I2C_AckAddr_7bit,?0x01);
????I2C_StretchClockCmd(ENABLE);
????I2C_Cmd(ENABLE);

????uint8_t?*da;
????i2c_read_reg(0x12,?0x00,?1,?da);
????printf("data:%02x\n",?da);
}

icon_rar.gifmain.zip

根据串口打印信息,是卡在了I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED

QQ截图20220522100552.png


从机芯片使用的是qma7981

寄存器如下,代码是读chip-id,在esp32平台测过可以读取,硬件无问题。

1653184758554619.png

1653184758169902.png


根据v307的代码改了一下,但还是不能用

u8 MPU_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf)

{

    u8 i=0;


    I2C_AcknowledgeConfig(ENABLE );


    I2C_GenerateSTART( ENABLE );


    while( !I2C_CheckEvent(  I2C_EVENT_MASTER_MODE_SELECT ) ) ;

    I2C_Send7bitAddress((addr << 1) | 0X00,I2C_Direction_Transmitter); //发送器件地址+写命令


    while( !I2C_CheckEvent(  I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ) ); //等待应答


    I2C_SendData(reg);         //写寄存器地址



    I2C_GenerateSTART(  ENABLE );

    while( !I2C_CheckEvent( I2C_EVENT_MASTER_MODE_SELECT ) );


    I2C_Send7bitAddress(((addr << 1) | 0x01),I2C_Direction_Receiver);//发送器件地址+读命令

    while( !I2C_CheckEvent(  I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ) ); //等待应答


    while(i < len)

    {

        if( I2C_GetFlagStatus( I2C_FLAG_RXNE ) !=  RESET )

        {

            if(i == (len - 2))

            {

                I2C_AcknowledgeConfig(DISABLE );

                buf[i] = I2C_ReceiveData();     //读数据,发送nACK


            }

            else

            {

                buf[i] = I2C_ReceiveData();     //读数据,发送ACK

            }

            i++;

        }

    }


    I2C_GenerateSTOP( ENABLE ); //产生一个停止条件


    return 0;

}

现象:

1653208941770162.png

1653208941113318.png



已解决,谢谢


老哥,怎么解决的,我也遇到一样的问题了



可以参考以下博客

以EEPROM为例的硬件IIC的使用 - JayWell - 博客园 (cnblogs.com)

注意下图位置的相关代码

6fbf098978f80420bbc8e3d04b699f0.png


只有登录才能回复,可以选择微信账号登录