公司要做摄像头视频采集,恰好看到正点原子的探索者开发有这么个例子。就没了探索者开发板,然后照着例子完成了初步试验。
完全正点原子的硬件平台,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]
一周热门 更多>