[KungFu32位 MCU] 醉了,又卡I2C上了,有空帮忙看看,谢谢了...

[复制链接]
566|9
手机看帖
扫描二维码
随时随地手机跟帖
fydabcd|  楼主 | 2022-6-22 18:35 | 显示全部楼层 |阅读模式
本帖最后由 fydabcd 于 2022-6-22 18:38 编辑

        主机模式,从机为24C04,24C04的随机读写,需要发完器件地址和子地址后,重新发送起始位和器件地址才能读。
      调试调用函数I2c_Buffer_Read(I2C0_SFR, 0xA0, i2c_read_buffer, 10);
      另外比较疑惑的是官方的里程中,读和写的函数都没有子地址的参数,这个不应该是I2C的标配吗?
/*发送起始位*/void I2c_Buffer_Read(I2C_SFRmap* I2Cx, uint16_t Read_I2C_Addr, uint8_t *p_buffer, uint16_t number_of_byte)
{

        I2Cx->SR = 0;
        I2C_Cmd(I2Cx, TRUE);
        I2C_Clear_INTERRUPT_Flag(I2Cx);
        I2C_Generate_START(I2Cx, TRUE);
        while (!I2C_Get_INTERRUPT_Flag(I2Cx));
        /*发送器件地址*/
        I2C_SendData8(I2Cx, Read_I2C_Addr | 0x01);
        I2C_Clear_INTERRUPT_Flag(I2Cx);
        while (!I2C_Get_INTERRUPT_Flag(I2Cx));
        I2c_Wait_Ack_Flag(I2Cx);
        if(AckTimeoutFlag == 1)
        {
                return (void)0;
        }
        /*发送子地址*/
    I2C_SendData8(I2Cx, 0x0);/*此处调试中,子地址固定为0*/
    I2C_Clear_INTERRUPT_Flag(I2Cx);
    while (!I2C_Get_INTERRUPT_Flag(I2Cx));
    I2C_Clear_INTERRUPT_Flag(I2Cx);
        I2c_Wait_Ack_Flag(I2Cx);
        if(AckTimeoutFlag == 1)
        {
                return (void)0;
        }
        /*重发起始位*/
        I2C_Clear_Start_Flag(I2Cx);
        I2C_Clear_INTERRUPT_Flag(I2Cx);
        I2C_Generate_START(I2Cx, TRUE);
        while (!I2C_Get_INTERRUPT_Flag(I2Cx));
        /*重发器件地址*/
        I2C_SendData8(I2Cx, Read_I2C_Addr | 0x01);
        I2C_Clear_INTERRUPT_Flag(I2Cx);
        while (!I2C_Get_INTERRUPT_Flag(I2Cx));
        I2c_Wait_Ack_Flag(I2Cx);
        if(AckTimeoutFlag == 1)
        {
                return (void)0;
        }
        /*读取数据*/
         while (number_of_byte)
         {
                 while (!I2C_Get_INTERRUPT_Flag(I2Cx));
                 if (I2C_Get_Receive_Buff_Flag(I2Cx))
                 {
                         I2C_Ack_DATA_Config(I2Cx, I2C_ACKDATA_ACK);
                         *p_buffer = I2C_ReceiveData(I2Cx);
                         I2C_Clear_INTERRUPT_Flag(I2Cx);
                         p_buffer++;
                 }
                 number_of_byte--;
         }
        
         /* Stop bit */
         I2C_Generate_STOP(I2Cx, TRUE);
        
         /* Clear the ISIF bit of the I2C interrupt flag */
         I2C_Clear_INTERRUPT_Flag(I2Cx);
         /* Wait for the stop to complete */
         while (!I2C_Get_INTERRUPT_Flag(I2Cx));
        //           ;
        
         /* Clear the ISIF bit of the I2C interrupt flag */
         I2C_Clear_INTERRUPT_Flag(I2Cx);
         /* Clear the I2C stop flag PIF bit */
         I2C_Clear_Stop_Flag(I2Cx);
         /* Turn off the I2C module */
         I2C_Cmd(I2Cx, FALSE);
}


使用特权

评论回复
树上的小鸟| | 2022-6-23 07:57 | 显示全部楼层
这个没有针对特定外围器件去做例程,主要是体现操作方法和流程,可以根据实际的应用去修改嘛

使用特权

评论回复
树上的小鸟| | 2022-6-23 08:00 | 显示全部楼层
例程代码仅仅提供的这个外设模块的操作方法示例,没有针对特定的应用场景或者外围器件做应用,可以直接在代码上重构适合自己应用的代码。

使用特权

评论回复
lvben5d| | 2022-6-23 09:15 | 显示全部楼层
本帖最后由 lvben5d 于 2022-6-23 09:19 编辑

官网 KF32A得 I2C我没调试, 我调试KF8A  I2C OK。  你注意下I2C的基本规范,我有GD32的I2C,也是按照GD32官网,自己需要按照I2C 读写外部器件规范,整合了下。 要认真去看I2C 读写外部器件的特性,有一个需要注意的点: I2C 从机地址  可能需要 <<1 。 我的GD32E103 是需要<<1位才对。 从机地址 比如是 0xA0 ,我实际填写的从机地址是   (0xA0<<1)  ,卡了我1星期,我才发现是从机地址不对。     不管是哪家MCU,  I2C驱动时序中按照各家MCU的寄存器对照手册进行,前期如果会用示波器(让硬件协助),可以拉到SDA引脚,把I2C时钟控制在400KHZ + (慢一点便于抓波)

使用特权

评论回复
评论
qintian0303 2022-6-24 08:45 回复TA
@lvben5d :应该是没有应答,但是地址都对啊,查寄存器地址写到地址寄存器了,就是没有应答 
zhxzhxzzhhxx 2022-6-23 19:00 回复TA
IIC的地址,是 Bit7-Bit1,最后一位是读写标志,0xA1,0xA0分别是0X50地址的器件的读写 
lvben5d 2022-6-23 13:19 回复TA
@qintian0303 : 卡在哪里,就看是没发 还是没应答了。 
qintian0303 2022-6-23 11:54 回复TA
老哥,我用GD的硬件IIC,一直卡在一个while循环,我查看是一个标志位没有置位,就死在哪里了,试过改从机地址,可是从机就是不反应,模拟就没有问题 
ayb_ice| | 2022-6-23 13:08 | 显示全部楼层
GPIO模拟比这不知道好多少,我从不用硬件的IIC,SPI

使用特权

评论回复
nongshengjiang| | 2022-6-23 13:42 | 显示全部楼层
你们都什么专业的呵呵

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则