完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
STM32F103ZET6的开发板,MCU作为主I2C,用I2C硬件轮询的方式读写一个I2C从设备。板子启动后,通过一个按钮开关来打开或关闭I2C写数据和读数据,在开始的第一次写数据时会偶现出现BUSY超时错误,后面持续数百万次的写和读操作结果都是正常的,而且这个错误也不是必现,是随机出现的,大概有50%多的错误概率,完全发现不了规律。从调试跟踪的结果看,都是在主I2C给从I2C发送器件地址后,主I2C没有收到ACK,然后超时。看了网上以前的一些分析,提到的一些可能原因,对比分析了,都对应不上。这个是偶现的错误,而且后面的读写都正常,所以写的从I2C的地址肯定是没有问题的。主I2C读写测试是在MCU上电启动后通过按钮开关控制的,不是一上电就开始读写。IO的初始化顺序也试了,IO的端口速率400K和100K都试了,都不能解决这个问题。
通过在软件中判断写操作的结果,如果发现写错误就重复写几次,也解决不了第一次偶然写失败的问题。 另外用中断的方式读写I2C,也有一样的问题,偶现第一次写失败,中断方式中发现主I2C能收到I2C_IT_AF中断错误。从I2C设备暂时不太好分析,现在还不确定到底是STM32F103的I2C的问题还是从设备的I2C问题。 不知道有没有遇到类似的问题的?能不能解决? 下面是STM32F103的I2C的IO/I2C初始化代码和I2C读写单个字节的代码: void I2C_Config(void) { I2C_InitTypeDef I2C_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_ClocksTypeDef rcc_clocks; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE); GPIO_AFIODeInit(); RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1|RCC_APB1Periph_I2C2, ENABLE); RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1|RCC_APB1Periph_I2C2, DISABLE); GPIO_DeInit(GPIOB); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, GPIO_InitStructure); GPIO_SetBits(GPIOB, GPIO_InitStructure.GPIO_Pin); GPIO_PinLockConfig(GPIOB, GPIO_InitStructure.GPIO_Pin); I2C_DeInit(I2C2); I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = 0x23; //unuseful I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = 400000; I2C_Init(I2C2, I2C_InitStructure); I2C_Cmd(I2C2, ENABLE); I2C_AcknowledgeConfig(I2C2, ENABLE); RCC_GetClocksFreq( rcc_clocks); g_ultimeOut = (rcc_clocks.SYSCLK_Frequency /10000); } void I2C_WriteByte(u8 addr, u8 data) { u32 timeout = g_ulTimeOut; while((timeout--) (I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY))); I2C_GenerateSTART(I2C2, ENABLE); timeout = g_ulTimeOut; while((timeout--) (SUCCESS!=I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT))); I2C_Send7bitAddress(I2C2, IIC_DEVICE_ADDRESS, I2C_Direction_Transmitter); timeout = g_ulTimeOut; while((timeout--) (SUCCESS!=I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))); I2C_SendData(I2C2, addr); timeout = g_ulTimeOut; while((timeout--) (SUCCESS!=I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING))); I2C_SendData(I2C2, data); timeout = g_ulTimeOut; while((timeout--) (SUCCESS!=I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED))); I2C_GenerateSTOP(I2C2, ENABLE); } void I2C_ReadByte(u8 addr, u8 *pdata) { u32 timeout = g_ulTimeOut; while((timeout--) I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY)); I2C_GenerateSTART(I2C2, ENABLE); timeout = g_ulTimeOut; while((timeout--) (SUCCESS!=I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT))); I2C_Send7bitAddress(I2C2, IIC_DEVICE_ADDRESS, I2C_Direction_Transmitter); timeout = g_ulTimeOut; while((timeout--) (SUCCESS!=I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))); I2C_SendData(I2C2, addr); timeout = g_ulTimeOut; while((timeout--) (SUCCESS!=I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTING))); //restart I2C_GenerateSTART(I2C2, ENABLE); timeout = g_ulTimeOut; while((timeout--) (SUCCESS!=I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT))); // device address, read action I2C_Send7bitAddress(I2C2, IIC_DEVICE_ADDRESS, I2C_Direction_Receiver); timeout = g_ulTimeOut; while((timeout--) (SUCCESS!=I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))); // receive byte I2C_AcknowledgeConfig(I2C2, DISABLE); I2C_GenerateSTOP(I2C2, ENABLE); // read timeout = g_ulTimeOut; while((timeout--) (SUCCESS!=I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED))); *pdata = I2C_ReceiveData(I2C2); I2C_AcknowledgeConfig(I2C2, ENABLE); } |
|
相关推荐
2个回答
|
|
建议先抓一下波形,先保证I2C不是被锁死的状态。可以考虑初始化时增加一个I2C的结束操作,让I2C总线的设备进入正常状态。另外,I2C总线上上拉电阻是否焊接,上拉电阻的阻值是多少?
|
|
|
|
启动I2C通讯时加一个延时看看。
|
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1658 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1568 浏览 1 评论
996 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
695 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1616 浏览 2 评论
1876浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
660浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
528浏览 3评论
546浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
517浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-28 18:24 , Processed in 0.879028 second(s), Total 83, Slave 65 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号