c - STM32F4卡在I2C_CheckEvent()

标签 c i2c stm32 stm32f4discovery

我发现我的 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/

相关文章:

c - 可变参数函数中的大小整数和提升

c - 如何在C中将rpm转换为rad/s?

c - 从 MMA7455L 传感器 i2c 获取数据

c++ - FatFS - 无法格式化驱动器,FR_MKFS_ABORTED

c++ - 为什么运算符不能放在括号中?

C - 抛出异常 : read access violation

c++ - i2c smbus* 函数在 centos 7 i2c-dev.h 上不存在

c - I2C 符号链接(symbolic link)

c - Discovery board STM32L0 (LoRaWAN) -> 如何正确配置停止模式?

stm32 - 如何调试定时器