杨大侠 发表于 2014-2-17 21:11:46

stm32f4硬件i2c+DMA读mpu6050单步调试能过,运行卡住

stm32f4硬件i2c+DMA读mpu6050单步调试能过,运行卡住
以下是卡住代码部分,希望有经验的朋友指导指导!
u32 I2C_DMA_Read( u8 SlaveAddr, u8 ReadAddr, u8* NumByte ,u8* ReadBuf)
{
I2C_ReadPtr = NumByte;

I2C_TimeCnt = I2C_TIME;
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))
    if((I2C_TimeCnt--) == 0)        return I2C_TimeOut();

I2C_GenerateSTART(I2C1, ENABLE);

I2C_TimeCnt = I2C_TIME;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
    if((I2C_TimeCnt--) == 0)        return I2C_TimeOut();

I2C_Send7bitAddress(I2C1, SlaveAddr, I2C_Direction_Transmitter);

I2C_TimeCnt = I2C_TIME;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))//卡住在此处!单步进入函数又可以通过!
    if((I2C_TimeCnt--) == 0)        return I2C_TimeOut();

I2C_SendData(I2C1, ReadAddr);

I2C_TimeCnt = I2C_TIME;
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF) == RESET)
    if((I2C_TimeCnt--) == 0)        return I2C_TimeOut();

I2C_GenerateSTART(I2C1, ENABLE);

I2C_TimeCnt = I2C_TIME;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))
    if((I2C_TimeCnt--) == 0)        return I2C_TimeOut();

I2C_Send7bitAddress(I2C1, SlaveAddr, I2C_Direction_Receiver);

if((u16)(*NumByte) < 2) {
I2C_TimeCnt = I2C_TIME;
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR) == RESET)
    if((I2C_TimeCnt--) == 0)        return I2C_TimeOut();

I2C_AcknowledgeConfig(I2C1, DISABLE);
(void)I2C1->SR2;

I2C_GenerateSTOP(I2C1, ENABLE);

I2C_TimeCnt = I2C_TIME;
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET)
    if((I2C_TimeCnt--) == 0)        return I2C_TimeOut();

*ReadBuf = I2C_ReceiveData(I2C1);

(u16)(*NumByte)--;

I2C_TimeCnt = I2C_TIME;
while(I2C1->CR1 & I2C_CR1_STOP)
    if((I2C_TimeCnt--) == 0)        return I2C_TimeOut();

I2C_AcknowledgeConfig(I2C1, ENABLE);
}
else {
    I2C_TimeCnt = I2C_TIME;
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
      if((I2C_TimeCnt--) == 0)        return I2C_TimeOut();

    DMA_InitStruct.DMA_Channel = DMA_Channel_1;
    DMA_InitStruct.DMA_PeripheralBaseAddr = (u32)I2C1_DR_Address;
    DMA_InitStruct.DMA_Memory0BaseAddr = (u32)ReadBuf;
    DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralToMemory;
    DMA_InitStruct.DMA_BufferSize = (u32)(*NumByte);
    DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStruct.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Enable;
    DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
    DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
    DMA_Init(DMA1_Stream0, &DMA_InitStruct);

    I2C_DMALastTransferCmd(I2C1, ENABLE);

    DMA_Cmd(DMA1_Stream0, ENABLE);
}

I2C_TimeCnt = I2C_TIME;
while(*NumByte > 0)
if((I2C_TimeCnt--) == 0)        return I2C_TimeOut();

return SUCCESS;
}

卡住部分后面的各个while进入后单步都能过,一点run就会卡住,难道是硬件i2c+DMA太快?MPU6050响应不了这么快?

rainyuoko 发表于 2014-2-17 21:28:20

看看iic速率是不是太高了。high speed我记得是要先在低速模式初始化的

杨大侠 发表于 2014-2-17 22:44:40

rainyuoko 发表于 2014-2-17 21:28
看看iic速率是不是太高了。high speed我记得是要先在低速模式初始化的

你是说低速模式初始化6050?麻烦详解!

rainyuoko 发表于 2014-2-17 23:21:12

杨大侠 发表于 2014-2-17 22:44
你是说低速模式初始化6050?麻烦详解!

你仔细看看6050手册应该会有初始化说明的,还有iic协议手册。

wenzhouyxc 发表于 2014-2-27 13:45:13

楼主这个问题解决了吗?现在我在调试这个程序的时候也是卡在这里。

Mac_Alex 发表于 2014-3-11 10:43:08

同问这个问题,楼主你解决了吗?希望能得到你的指导。

杨大侠 发表于 2014-3-11 11:20:35

Mac_Alex 发表于 2014-3-11 10:43
同问这个问题,楼主你解决了吗?希望能得到你的指导。

办法就是不要使用DMA,在合适的时机打开和关短buf的中断,祝你好运。

IamPolaris 发表于 2014-3-12 11:32:16

杨大侠 发表于 2014-3-11 11:20
办法就是不要使用DMA,在合适的时机打开和关短buf的中断,祝你好运。

楼主行行好,我最近也在调这个,也是用i2c读取MPU6050的数据,老板非要用硬件接口。我这两天一直没调通。楼主给分驱动吧。

mute 发表于 2014-3-13 14:13:23

STM的I2C是狗屎。。。。

onev 发表于 2014-3-26 14:26:59

楼主这个问题有没有解决我的问题是 用硬件IIC能单字节写单字节读 就是不能多字节读          用模拟iic居然不能写不能读
页: [1]
查看完整版本: stm32f4硬件i2c+DMA读mpu6050单步调试能过,运行卡住