最近公司需要用到IIC协议通讯,我在验证IIC通讯时一直碰到验证不成功的问题,具体的信息如下:
所用主芯片是STM32H745XIH6U,FRAM设备用的FM24CL64B(从机)
协议代码使用cubemx生成,具体的软硬件配置如下图所示:
这里配置圆圈内内容后,波浪线的数值变为红色提示错误,然后cubemx自动纠正了:
根据H745电路图中如下两图所示,得知CN7引出的5和6针脚就是IIC协议的PD13,PD12:
下图为FM24CL的接线图,可知3 5是I2C协议所用针脚
于是开始配置I2C4:
软件的配置我是参考了https://jeckxu666.blog.csdn.net/article/details/117253441做的,最后按配置生成代码
然后是物理连线,根据上图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这三个变量中的哪一个不对么?或者说不是软件的问题,是硬件上我哪里搞错了?
现在就想让H745和FM24成功用I2C协议通讯上,达成H745对FM24进行读和写的操作