我发现我的 STM32F4 和 IMU 设备之间的 I2C 通信随机挂起。 STM32F4 是主机,总线上唯一的其他设备是 IMU6050 6 轴加速度计/陀螺仪。该程序最终因陷入 I2C_CheckEvent() 函数内的循环而挂起。
初始化如下:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(DATAPORT, &GPIO_InitStructure);
GPIO_PinAFConfig(DATAPORT, GPIO_PinSource8, GPIO_AF_I2C1);
GPIO_PinAFConfig(DATAPORT, GPIO_PinSource9, GPIO_AF_I2C1);
/* Set the I2C parameters, pretty much default except ack */
I2C_InitStructure.I2C_ClockSpeed = 100000;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C1, &I2C_InitStructure);
/* Enable the I2C peripheral */
I2C_Cmd(I2C1, ENABLE);
/* Config the IMU with defult settings */
IMUConfig(DEFAULTACCELRANGE, DEFAULTGYRORANGE);
IMU 的初始化已完成,我确信在获得有效数据一段时间后一切正常。应用程序在运行几秒钟后随机崩溃。
读取函数:
void IMUReadBytes(uint8_t startAddress, uint8_t numOfBytes, uint8_t *location){
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, IMU_ADDRESS << 1, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, startAddress);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, IMU_ADDRESS << 1, I2C_Direction_Receiver);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
int num = 0;
for(num = 0; num <= numOfBytes; num++){
if(num == numOfBytes){
I2C_AcknowledgeConfig(I2C1, DISABLE);
I2C_GenerateSTOP(I2C1, ENABLE);
}
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
location[num] = I2C_ReceiveData(I2C1);
}
I2C_AcknowledgeConfig(I2C1, ENABLE);
}
每次,应用程序似乎都因其中一个 while 检查事件而崩溃,每次都不一样。
可能不相关,但在编译时,我收到警告:
source\application\source\imu.c:129:5: warning: passing argument 3 of 'IMUReadBytes' from incompatible pointer type [enabled by default]
source\application\source\imu.c:81:6: note: expected 'uint8_t *' but argument is of type 'uint8_t (*)[14]'
我不确定这是否与它有任何关系。
正如我所说,代码可以正常运行一段时间,有时甚至几分钟。我已经将陀螺仪和加速度值与某些电机相关联,并且在它工作期间,一切都运行得很好。不知道为什么会卡住
最佳答案
您没有包括如何调用 IMUReadBytes(...)
并且您有一个与此相关的编译器警告。此外,如果没有真正的代码,则无法看出您是否超出了 location
的范围。
然而,为了缩小问题的范围,我建议将整个代码分成几部分,并首先运行一些东西:
while(1)
{
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
unsigned char readbyte = I2C_ReceiveData(I2C1);
printf("%x ",readbyte);
}
这里的要点是有一个简单的稳健循环,它总是读取数据并将其输出给您。所以你可以运行它看看挂起是否发生。这样的循环不会影响其他内存,这可能会排除一些数据损坏问题和其他问题,或多或少与 I2C 无关。
你有没有可以从你的系统打印出来的串口?调试的最大 helper 。
另一种方法是在示波器上触发总线数据(如果有的话)。
否则,您将只需要通过查看代码和文档来分析您的程序。
关于c - STM32F4卡在I2C_CheckEvent(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24768383/