void I2CTransfer(uint16_t deviceAddr, uint8_t cmdArray[], uint8_t dataArray[], uint16_t cmdLen, uint16_t dataLen, uint16_t flag)
{
    // 根据flag确定读写方式
    if(flag == I2C_FLAG_WRITE_READ)
    {
        // 发送写命令
        LL_I2C_Enable(I2C1);
        LL_I2C_HandleTransfer(I2C1, deviceAddr, LL_I2C_ADDRSLAVE_7BIT, cmdArray, cmdLen, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);
        while (!LL_I2C_IsActiveFlag_TXE(I2C1));
        while (!LL_I2C_IsActiveFlag_STOP(I2C1));
        
        // 接收数据
        LL_I2C_HandleTransfer(I2C1, deviceAddr, LL_I2C_ADDRSLAVE_7BIT, dataArray, dataLen, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_READ);
        while (!LL_I2C_IsActiveFlag_TXE(I2C1));
        while (!LL_I2C_IsActiveFlag_STOP(I2C1));
    }
    else if (flag == I2C_FLAG_WRITE_WRITE)
    {
        // 发送写命令和数据
        uint8_t writeBuffer[cmdLen + dataLen];
        memcpy(writeBuffer, cmdArray, cmdLen);
        memcpy(writeBuffer + cmdLen, dataArray, dataLen);
        LL_I2C_Enable(I2C1);
        LL_I2C_HandleTransfer(I2C1, deviceAddr, LL_I2C_ADDRSLAVE_7BIT, writeBuffer, cmdLen + dataLen, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);
        while (!LL_I2C_IsActiveFlag_TXE(I2C1));
        while (!LL_I2C_IsActiveFlag_STOP(I2C1));
    }
}

static uint16_t i2cReadRegister(uint16_t addr,uint8_t regOffset)
{
    uint16_t result = 0x00;

    uint8_t cmdArray[1];
    uint8_t dataArray[2];

    cmdArray[0] = regOffset;
    I2CTransfer(addr << 1, cmdArray, dataArray, 1, 2, I2C_FLAG_WRITE_READ );

    result = (dataArray[1] << 8) | (dataArray[0]);
    return result;
    return dataArray[0];
}


static void i2cWriteRegister(uint16_t addr,uint8_t regOffset, uint8_t writeData)
{
    uint8_t cmdArray[1];
    uint8_t dataArray[2];

    cmdArray[0] = regOffset;
    dataArray[0] = writeData;
    I2CTransfer(addr << 1, cmdArray, dataArray, 1, 2, I2C_FLAG_WRITE_WRITE );
}

函数说明:

  • I2CTransfer: 该函数根据传入的 flag 参数,选择执行 I2C 写操作或者读写操作。
  • i2cReadRegister: 该函数用于从指定 I2C 设备的指定寄存器读取数据。
  • i2cWriteRegister: 该函数用于向指定 I2C 设备的指定寄存器写入数据。

代码示例:

// 初始化 I2C1
LL_I2C_InitTypeDef I2C_InitStruct = {0};
I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C;
I2C_InitStruct.ClockSpeed = 400000;
I2C_InitStruct.DutyCycle = LL_I2C_DUTYCYCLE_2;
I2C_InitStruct.OwnAddress1 = 0x00;
I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK;
I2C_InitStruct.OwnAddress2 = 0x00;
LL_I2C_Init(I2C1, &I2C_InitStruct);
LL_I2C_Enable(I2C1);

// 读取寄存器
uint16_t data = i2cReadRegister(0x48, 0x00);

// 写入寄存器
i2cWriteRegister(0x48, 0x01, 0x55);

注意事项:

  • 确保正确配置 I2C 模块和引脚。
  • 修改代码中的 I2C 设备地址和寄存器地址。
  • 使用前请参考 STM32 的官方文档以确保正确使用 LL 库。

优化建议:

  • 使用 LL_I2C_HandleTransfer 函数代替 LL_I2C_TransmitLL_I2C_Receive 函数,提高代码效率。
  • 使用循环语句来检查 I2C 传输状态,避免死锁。
  • 在代码中添加错误处理机制,例如检查 I2C 传输是否成功。
  • 使用更具体的函数名称,例如 I2c_ReadRegisterI2c_WriteRegister,以提高代码可读性。

总结:

本代码提供了一个简单而实用的 STM32 I2C 驱动程序,可用于与 I2C 设备进行通信。通过代码优化,可以提高代码效率和可读性。

STM32 I2C 驱动程序:利用 LL 库实现 I2C 读写操作

原文地址: https://www.cveoy.top/t/topic/nggU 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录