void I2CTransfer(uint16_t deviceAddr, uint8_t cmdArray[], uint8_t dataArray[], uint16_t cmdLen, uint16_t dataLen, uint16_t flag)
{
    // 利用STM32LL库的I2C外设完成数据传输

    // 发送I2C起始信号
    LL_I2C_GenerateStartCondition(I2C1);

    // 等待I2C起始信号发送完成
    while(!LL_I2C_IsActiveFlag_SB(I2C1));

    // 发送设备地址和写入标志
    LL_I2C_TransmitData8(I2C1, deviceAddr << 1);

    // 等待设备地址发送完成
    while(!LL_I2C_IsActiveFlag_ADDR(I2C1));

    // 清除ADDR标志
    LL_I2C_ClearFlag_ADDR(I2C1);

    // 发送命令数组
    for(uint16_t i=0; i<cmdLen; i++)
    {
        LL_I2C_TransmitData8(I2C1, cmdArray[i]);

        // 等待数据发送完成
        while(!LL_I2C_IsActiveFlag_TXE(I2C1));
    }

    if(flag == I2C_FLAG_WRITE_READ)
    {
        // 发送I2C重复起始信号
        LL_I2C_GenerateStartCondition(I2C1);

        // 等待I2C重复起始信号发送完成
        while(!LL_I2C_IsActiveFlag_SB(I2C1));

        // 发送设备地址和读取标志
        LL_I2C_TransmitData8(I2C1, (deviceAddr << 1) | 0x01);

        // 等待设备地址发送完成
        while(!LL_I2C_IsActiveFlag_ADDR(I2C1));

        // 清除ADDR标志
        LL_I2C_ClearFlag_ADDR(I2C1);

        // 接收数据数组
        for(uint16_t i=0; i<dataLen; i++)
        {
            // 最后一位数据需要发送NACK
            if(i == dataLen-1)
            {
                LL_I2C_AcknowledgeNextData(I2C1, LL_I2C_NACK);
            }

            // 等待接收数据
            while(!LL_I2C_IsActiveFlag_RXNE(I2C1));

            // 读取接收到的数据
            dataArray[i] = LL_I2C_ReceiveData8(I2C1);
        }
    }
    else if(flag == I2C_FLAG_WRITE_WRITE)
    {
        // 发送数据数组
        for(uint16_t i=0; i<dataLen; i++)
        {
            LL_I2C_TransmitData8(I2C1, dataArray[i]);

            // 等待数据发送完成
            while(!LL_I2C_IsActiveFlag_TXE(I2C1));
        }
    }

    // 发送I2C停止信号
    LL_I2C_GenerateStopCondition(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 );
}

解释:

  1. 函数参数: deviceAddr 表示目标设备地址,cmdArray 表示发送的命令数组,dataArray 表示发送或接收的数据数组,cmdLen 表示命令数组长度,dataLen 表示数据数组长度,flag 表示操作类型,可以是 I2C_FLAG_WRITE_READI2C_FLAG_WRITE_WRITE
  2. 发送起始信号: LL_I2C_GenerateStartCondition(I2C1) 用于发送 I2C 起始信号。
  3. 发送设备地址: LL_I2C_TransmitData8(I2C1, deviceAddr << 1) 发送目标设备地址,左移一位表示写入操作。
  4. 发送命令数组: 循环发送命令数组中的每个字节。
  5. 处理读写操作: 根据 flag 参数决定是发送数据还是接收数据。
  6. 发送停止信号: LL_I2C_GenerateStopCondition(I2C1) 发送 I2C 停止信号。

使用示例:

// 读取设备寄存器 0x10 的值
uint16_t value = i2cReadRegister(0x48, 0x10);

// 写入设备寄存器 0x20 的值 0x55
i2cWriteRegister(0x48, 0x20, 0x55);

注意:

  • 此代码仅供参考,具体的实现可能需要根据实际情况进行调整。
  • 确保 STM32 芯片的 I2C 外设已经配置完成。
  • 使用前请参考 STM32LL 库的官方文档,了解相关 API 的详细用法。
STM32 I2C 数据传输函数 I2CTransfer 实现 - 使用 STM32LL 库

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

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