STM32 I2C 数据传输函数 I2CTransfer 实现 - 使用 STM32LL 库
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 );
}
解释:
- 函数参数:
deviceAddr表示目标设备地址,cmdArray表示发送的命令数组,dataArray表示发送或接收的数据数组,cmdLen表示命令数组长度,dataLen表示数据数组长度,flag表示操作类型,可以是I2C_FLAG_WRITE_READ或I2C_FLAG_WRITE_WRITE。 - 发送起始信号:
LL_I2C_GenerateStartCondition(I2C1)用于发送 I2C 起始信号。 - 发送设备地址:
LL_I2C_TransmitData8(I2C1, deviceAddr << 1)发送目标设备地址,左移一位表示写入操作。 - 发送命令数组: 循环发送命令数组中的每个字节。
- 处理读写操作: 根据
flag参数决定是发送数据还是接收数据。 - 发送停止信号:
LL_I2C_GenerateStopCondition(I2C1)发送 I2C 停止信号。
使用示例:
// 读取设备寄存器 0x10 的值
uint16_t value = i2cReadRegister(0x48, 0x10);
// 写入设备寄存器 0x20 的值 0x55
i2cWriteRegister(0x48, 0x20, 0x55);
注意:
- 此代码仅供参考,具体的实现可能需要根据实际情况进行调整。
- 确保 STM32 芯片的 I2C 外设已经配置完成。
- 使用前请参考 STM32LL 库的官方文档,了解相关 API 的详细用法。
原文地址: https://www.cveoy.top/t/topic/nf3U 著作权归作者所有。请勿转载和采集!