打印
[牛人杂谈]

M031的I2C写函数学习思考

[复制链接]
311|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yiyigirl2014|  楼主 | 2024-1-9 16:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
uint8_t I2C_WriteByte(I2C_T *i2c, uint8_t u8SlaveAddr, uint8_t data)
{
    uint8_t u8Xfering = 1U, u8Err = 0U, u8Ctrl = 0U;
    uint32_t u32TimeOutCount;

    g_I2C_i32ErrCode = 0;

    I2C_START(i2c);

    while (u8Xfering && (u8Err == 0U))
    {
        u32TimeOutCount = SystemCoreClock;
        I2C_WAIT_READY(i2c)
        {
            u32TimeOutCount--;
            if(u32TimeOutCount == 0)
            {
                g_I2C_i32ErrCode = I2C_TIMEOUT_ERR;
                break;
            }
        }

        switch (I2C_GET_STATUS(i2c))
        {
        case 0x08:
            I2C_SET_DATA(i2c, (uint8_t)(u8SlaveAddr << 1U | 0x00U));  /* Write SLA+W to Register I2CDAT */
            u8Ctrl = I2C_CTL_SI;                           /* Clear SI */
            break;

        case 0x18:                                         /* Slave Address ACK */
            I2C_SET_DATA(i2c, data);                       /* Write data to I2CDAT */
            break;

        case 0x20:                                         /* Slave Address NACK */
        case 0x30:                                         /* Master transmit data NACK */
            u8Ctrl = I2C_CTL_STO_SI;                       /* Clear SI and send STOP */
            u8Err = 1U;
            break;

        case 0x28:
            u8Ctrl = I2C_CTL_STO_SI;                       /* Clear SI and send STOP */
            u8Xfering = 0U;
            break;

        case 0x38:                                         /* Arbitration Lost */
        default:                                           /* Unknow status */
            I2C_SET_CONTROL_REG(i2c, I2C_CTL_STO_SI);      /* Clear SI and send STOP */
            u8Ctrl = I2C_CTL_SI;
            u8Err = 1U;
            break;
        }

        I2C_SET_CONTROL_REG(i2c, u8Ctrl);                  /* Write controlbit to I2C_CTL register */
    }

    u32TimeOutCount = SystemCoreClock;
    while ((i2c)->CTL0 & I2C_CTL0_STO_Msk)
    {
        u32TimeOutCount--;
        if(u32TimeOutCount == 0)
        {
            g_I2C_i32ErrCode = I2C_TIMEOUT_ERR;
            break;
        }
    }

    return (u8Err | u8Xfering);                            /* return (Success)/(Fail) status */
}
该函数写的比较复杂,最后返回一个是否发送成功的标志。
最后是通过检测两个事件,I2C总线是否完成了发送,如果没有就检测第二个标志,是否发送超时了。超时后也会自动结束函数,防止阻塞卡死。

使用特权

评论回复
沙发
yiyigirl2014|  楼主 | 2024-1-9 16:41 | 只看该作者
这跟我想的方法是相似的,挺好的。

使用特权

评论回复
板凳
duo点| | 2024-1-9 16:44 | 只看该作者
挺好的

使用特权

评论回复
地板
AloneKaven| | 2024-1-10 08:05 | 只看该作者
写的听清楚的

使用特权

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

本版积分规则

213

主题

3538

帖子

10

粉丝