STM32F407VE OV2640 DMA进入HardFault_Handler

2019-07-20 23:58发布

        公司要做摄像头视频采集,恰好看到正点原子的探索者开发有这么个例子。就没了探索者开发板,然后照着例子完成了初步试验。
        完全正点原子的硬件平台,STM32F4采集OV2640摄像头的数据后通过UDP发送给PC端,PC端显示出来,效果大概是每秒10帧图片。DCMI的配置完全就是例子,连续采样模式,DMA的配置也是例子。
        但公司其他项目有用到STM32F4,但用的是STM32F407VET6,网卡是DP83848.然后我就重新改版做测试,然后就遇到了如题的问题。贴几个关键代码和思路。
[mw_shl_code=c,true]void OV2640_JPEG_Init(void) { u8 size = 4; while(OV2640_Init()) { delay_ms(200); } OV2640_JPEG_Mode(); My_DCMI_Init(); DCMI_DMA_Init((u32)jpeg_buf,JPEG_BUF_SIZE,DMA_MemoryDataSize_Word,DMA_MemoryInc_Enable); OV2640_OutSize_Set(jpeg_img_size_tbl[size][0],jpeg_img_size_tbl[size][1]); DMA2_Stream1->CR |= 0x00000001; DCMI->CR |= (uint32_t)DCMI_CR_CAPTURE; }[/mw_shl_code]       一看就知道这个原子哥得代码,也没得什么说的。就是我把图片大小设置为了640*480.
[mw_shl_code=c,true] DCMI_InitStructure.DCMI_CaptureMode = DCMI_CaptureMode_SnapShot; DCMI_InitStructure.DCMI_CaptureRate=DCMI_CaptureRate_All_Frame; DCMI_InitStructure.DCMI_ExtendedDataMode= DCMI_ExtendedDataMode_8b; DCMI_InitStructure.DCMI_HSPolarity= DCMI_HSPolarity_Low; DCMI_InitStructure.DCMI_PCKPolarity= DCMI_PCKPolarity_Rising; DCMI_InitStructure.DCMI_SynchroMode= DCMI_SynchroMode_Hardware; DCMI_InitStructure.DCMI_VSPolarity=DCMI_VSPolarity_Low; DCMI_Init(&DCMI_InitStructure);[/mw_shl_code]     我将DCMI连续输出模式改成了快照模式。
[mw_shl_code=c,true]void jpeg_data_process(void) { u8 *p; unsigned int cnt=0; unsigned int sum = 0;     p=(u8*)jpeg_buf; DMA2_Stream1->CR &= ~(1<<0); while(DMA2_Stream1->CR &(1<<0)); jpeg_data_len=JPEG_BUF_SIZE - DMA2_Stream1->NDTR;     sprintf((char*)tmpBuf,"%ld",4*jpeg_data_len);     udp_demo_senddata(tmpBuf,6); delay_ms(1);     p=(u8*)jpeg_buf;     cnt = 0;     sum = 4*jpeg_data_len;     while(cnt < sum)     { if(cnt + SEND_SIZE <= sum) { udp_demo_senddata((p+cnt),SEND_SIZE); cnt += SEND_SIZE; } else { udp_demo_senddata((p+cnt),sum - cnt); break; } while(d_cnt < 100) { d_cnt ++; LwIP_Periodic_Handle(LocalTime); } d_cnt = 0; } while(DMA2_Stream1->CR&0X01); DMA2_Stream1->AR=(u32)&DCMI->DR; DMA2_Stream1->M0AR=(u32)jpeg_buf; DMA2_Stream1->NDTR=JPEG_BUF_SIZE; DMA2_Stream1->CR |= 0x00000001; DCMI->CR |= (uint32_t)DCMI_CR_CAPTURE; }[/mw_shl_code]       因为是快照模式,所以进入这个函数以后DCMI->CR中的DCMI_CR_CAPTURE已经被清零了,然后就是暂停DMA传输,获取一帧图片的大小,UDP先传输这帧图片大小,再传输这帧图片的数据。再调整DMA的计数值,开DMA,开DCMI捕获。

     试验现象:在原子哥的平台上完全通过,在自己的平台STM32F407VET6上,能够获得图片,有时程序跑了十几秒(采集了几十帧图片,图片在PC上显示正常),有时程序只跑了一秒(采集了几帧图片,图片显示正常),然后程序就跑到了HardFault_Handler里面去了。


     然后自己测试了下,想找到怎么进入到HardFault里去的。
    1、屏蔽了OV2640的初始化代码,只运行LWIP内核,程序不出错。
   2、开OV2640的初始化代码,但关掉DMA2_Stream1->CR |= 0x00000001;这句话,就是不使能DMA功能,程序也不会出错。
   3、开OV2640,也打开DMA功能(也就是上面描述的),程序就会进入到HardFault_Handler里去。

[mw_shl_code=c,true] 尝试着去更改DMA里面的配置,都没什么效果。求指导,给个思路。论坛里有人可出在进HardFault_Handler时,看sp的值然后加20就是出错点的位置,但我还不知道怎么操作。[/mw_shl_code]
[mw_shl_code=c,true]   [/mw_shl_code]


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
12条回答
xijiele
1楼-- · 2019-07-21 03:20
 精彩回答 2  元偷偷看……
kanite
2楼-- · 2019-07-21 04:46
自己先定一个,下午来了继续干~
xijiele
3楼-- · 2019-07-21 08:27
默认的HardFault_Handler处理方法不是B .这样的死循环么?楼主将它改成BX LR直接返回的形式。然后在这条语句打个断点,一旦在断点中停下来,说明出错了,然后再返回,就可以返回到出错的位置的下一条语句那儿

__asm void wait()
{
      BX lr
}

void HardFault_Handler(void)
{
    /* Go to infinite loop when Hard Fault exception occurs */
       wait();
}

参考至http://blog.csdn.net/zyboy2000/article/details/7668331,可以作为一种调试方法
alone-耳温
4楼-- · 2019-07-21 09:31
 精彩回答 2  元偷偷看……
kanite
5楼-- · 2019-07-21 15:20
      谢谢2楼的提醒。我试了下,结果是这样的。
     



      它停在了stm32f4x7_eth.c中的这一行上面。进了一步~~
kanite
6楼-- · 2019-07-21 16:06
 精彩回答 2  元偷偷看……

一周热门 更多>