本帖最后由 泡泡茶壶 于 2022-7-19 10:56 编辑
最近公司需要用到 IIC 协议通讯,我在验证 IIC 通讯时一直碰到验证不成功的问题,具体的信息如下:
所用主芯片是 STM32H745XIH6U,FRAM 设备用的 FM24CL64B(从机) 协议代码使用 cubemx 生成,具体的软硬件配置如下图所示:
这里配置圆圈内内容后,波浪线的数值变为红色提示错误,然后 cubemx 自动纠正了:
根据 H745 电路图中如下两图所示,得知 CN7 引出的 5 和 6 针脚就是 IIC 协议的 PD13,PD12:
下图为 FM24CL 的接线图,可知 3 5 是 I2C 协议所用针脚
于是开始配置 I2C4:
然后是物理连线,根据上图 H745 和 FM24 的电路图接线如下(棕色红色为地线和供电):
然后在 keil5 中打开上面生成的代码,main.c 中添加测试用例如下: 首先在 BEGIN PV 中定义传参
/* USER CODE BEGIN PV */#define Write_ADDR 0xAE
#define Read_ADDR 0xAF
unsigned char str1[]={"i2ctest1"};
unsigned char str2[]={"i2ctest2"};
unsigned char str3[]={"i2ctest3"};
uint8_t ReadBuffer[50];
然后在 main 函数中添加如下代码: /* USER CODE BEGIN 2 */
int i=5;int j =5;int k=5;
HAL_Delay(100);
//阻塞方式写入读取
if(HAL_I2C_Mem_Write(&hi2c4,Write——ADDR,0,I2C_MEMADD_SIZE_8BIT,str1,sizeof(str1),1000)==HAL_OK)
{i=6;}else{i=7;}
HAL_Delay(1000);
HAL_I2C_Mem_Read(&hi2c4,Read_ADDR,0,I2C_MEMADD_SIZE_8BIT,ReadBuffer,sizeof(str1),1000);
HAL_Delay(1000);
//中断方式写入读取
if(HAL_I2C_Mem_Write_IT(&hi2c4,Write_ADDR,0,I2C_MEMADD_SIZE_8BIT,str2,sizeof(str2))==HAL_OK)
{j=6;}else{j=7;}
HAL_Delay(1000);
HAL_I2C_Mem_Read_IT(&hi2c4,Read_ADDR,0,I2C_MEMADD_SIZE_8BIT,ReadBuffer,sizeof(str2));
HAL_Delay(1000);
//DMA中断方式写入读取
if(HAL_I2C_Mem_Write_DMA(&hi2c4,Write_ADDR,0,I2C_MEMADD_SIZE_8BIT,str3,sizeof(str3))==HAL_OK)
{k=6;}else{k=7;}
HAL_Delay(1000);
HAL_I2C_Mem_Read_DMA(&hi2c4,Read_ADDR,0,I2C_MEMADD_SIZE_8BIT,ReadBuffer,sizeof(str3));
HAL_Delay(1000);
/* USER CODE END 2 */
说明一下。读写地址为 AE 和 AF 是因为 FM24 的接线图如下图: 我的理解是用来决定从设备地址的那几根线全部接到供电线上了,所以全部是 1,也就是说地址是 0xAE 和 0xAF。
然后编译,下载到 H745 中都没问题,最后跑起来调试时,watch 窗口查看 ijk 三个变量的值,结果全都从 5 变成了 7,说明确实被执行了但全都失败了。
由于我本人之前是搞软件开发的没接触过嵌入式,所以偏向于从软件层面思考解决方案。我打断点调试,函数执行的路径如下:
HAL_I2C_Mem_Write→I2C_RequestMemoryWrite→I2C_WaitOnTXISFlagUntilTimeout→I2C_IsErrorOccurred
执行过程在 I2C_IsErrorOccurred 函数中的详细步骤如下:
1. 进入 6423 行 while (__HAL_I2C_GET_FLAG (hi2c, I2C_FLAG_TXIS) == RESET) 语句,然后进行到 6432 行 if (Timeout != HAL_MAX_DELAY) 判断语句
2. 循环至 6426 行 if (I2C_IsErrorOccurred (hi2c, Timeout, Tickstart) != HAL_OK) 语句并进入该函数
3. 到达 6575 行 if (HAL_IS_BIT_SET (itflag, I2C_FLAG_AF)) 进入该语句,该语句最终导致了 I2C_IsErrorOccurred 函数返回 HAL_ERROR 导致写函数执行失败。
失败的原因到底是什么?上面 define 的地址我不光试了 AE 和 AF,从 A0 到 A8 我也全部试了,全都不行。是因为 TXIS,itflag 或者 FALG_AF 这三个变量中的哪一个不对么?或者说不是软件的问题,是硬件上我哪里搞错了?也想过可能是时钟树配置的不对?或者是流传的 stm32 上的 I2C 不稳定的问题?第一次调试时地址没有写对,应该是 AE 和 AF 我写成了 A0 和 A1,我看别人说 stm32 上的 I2C 有个 bug 是只要你第一次输入的地址是错的那么后面就算输入对的地址,主机也无法识别,难道是因为这个? 现在就想让 H745 和 FM24 成功用 I2C 协议通讯上,达成 H745 对 FM24 进行读和写的操作,请大佬赐教,万分感谢!!
|