繁体   English   中英

STM32F4挂在I2C_CheckEvent()中

[英]STM32F4 Hanging in I2C_CheckEvent()

我发现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 check事件之一崩溃,每次都不同。

可能不相关,但是在编译时,我得到警告:

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无关。

您是否有一个可以从系统中打印出来的串行端口? 它是调试的最大帮手。

另一种方法是在示波器上触发总线数据。

否则,您只需要通过观看代码和文档来分析程序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM