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条回答
kanite
2019-07-22 01:40
回复【7楼】xijiele:
---------------------------------
是的哦。

下午又试了下,不用网络发送数据,把lwip的所有代码全部屏蔽掉,使用串口发送代替网络发送,使用原子哥得串口摄像头软件,显示0.6帧每秒数据。也就是不出任何错。

问题就在网络和摄像头同时存在时,网卡是DP83848,LWIP基本上用的ST官方例子。我得好好看看官方例子和原子哥得LWIP有什么不同了。

一周热门 更多>