MCAL环境下I2C只能执行一次问题
-
样机上有一颗兴威帆的RTC芯片,采用的是I2C通讯,器件地址为单字节,访问地址为单字节;访问方式应该是跟官方开发板上的AT24C02类似。
先拿MCAL库里面的I2C例程作测试,里面有一个AT24C02的I2C驱动,IAR环境下跑了一下,正常。
之后在主循环中重复调用“写-读-比较”函数,发现只能成功一次;试着改变波特率,DMA改为中断等措施,但都是第一次成功,之后就不行了,例程中的中断函数也不知道是起什么作用的。
其它疑问包括:
1 - I2C的波特率一般会设置为100K-400K,取决于上拉电阻,但MCAL驱动里面附带了很多细化参数,不知道怎么调;2 - I2C同步方式会存在超时问题,云途MCAL的超时时间应该是循环次数而不是严格意义的时间,结合I2C具体要怎么设置?设置为多大为宜?因为I2C的超时不设置真不行;
3 - 有没有取消从器件锁死的函数?
附已有的I2C访问流程经验:
1 - I2C初始化;
2 - 访问I2C器件;
3 - 如果超时,注销I2C重启;
4 - 如果还不行,I2C引脚需要切换到GPIO口模式,执行取消挂死流程,之后再重新初始化。附测试工程
i2c测试.zip -
- 波特率 = 频率 / (((MCLKCFG[LOW] + MCLKCFG[High] + 2 + ROUNDDOWN((2 + MFLTCFG[FLTSCL] + SCL_RISETIME) / 2^DIV)) * 2^DIV)).
- 超时时间跟你的通信数据长度和主频都有关系。你可以根据你的实际应用通过调试的手段获取到正常通信完成时最大的计数值,然后给这个值加一个裕量就可以了。
- 驱动中没有解锁总线锁死的函数,你需要将clock管脚配置为gpio然后发送9个clock就可以实现。
Demo中的中断回调是工作在slave模式的instanse使用的。
关于你描述的只能读写一次的问题,怀疑是你写完后从设备没有把数据处理完成,然后再次发起通信时从设备没有响应导致的(用逻辑分析仪抓下波形看从设备是否没有发送ACK响应),你需要每次通信后加适量的延时来保证。
-
Frank 在 MCAL环境下I2C只能执行一次问题 中说:
关于你描述的只能读写一次的问题,怀疑是你写完后从设备没有把数据处理完成,然后再次发起通信时从设备没有响应导致的(用逻辑分析仪抓下波形看从设备是否没有发送ACK响应),你需要每次通信后加适量的延时来保证。
例程就是官方的mcal库自带的例程。都有延时
void Eeprom_Write_Read_Test(void) { // 1-发 ... Delay((uint32)1000000); // 收 ... // 比较 ... } main() { while (1) { TestCount++; if (TestCount % 2000000 == 0U) { Dio_FlipChannel(DioConf_DioChannel_DioChannel_0); if(tx_busy == 0){ tx_busy =1; i2c_count[0]++; WriteToEepromBuffer[7]++; Eeprom_Write_Read_Test(); } } } }
见了鬼了,第一次就可以,之后发收测试就不行。
发帖前请查看
帮助没办法联网的电脑使用YCT
帮助改进和优化YT CONFIG TOOL,有机会抽取YTM32B1ME0 EVB哦...