本帖最后由 colin2135 于 2015-10-10 09:32 编辑
感谢21给的板子。
这次分享用446的DCMI来捕捉OV2640的JPEG图像。
用到了的外设:
1.硬件的I2C
2.MCO1,输出16M XCLK给OV2640
3.DCMI 数字图像接口
4.UART 用来和上位机通信
实物连接与引脚图
硬件接完成后,首先应该通过I2C读取ID,看看OV2640能否工作。
uint8_t OV2640_ReadID(OV2640_IDTypeDef* OV2640ID)
{
i2c_sent(OV2640_DSP_RA_DLMT, 0x01);
OV2640ID->Manufacturer_ID1 =i2c_receive(OV2640_SENSOR_MIDH);
OV2640ID->Manufacturer_ID2 =i2c_receive(OV2640_SENSOR_MIDL);
OV2640ID->Version =i2c_receive(OV2640_SENSOR_PIDH);
OV2640ID->PID =i2c_receive(OV2640_SENSOR_PIDL);
return 0;
}
正常的话,可以在watch窗口看到如下:
上面一步正常后,就可以读取JPEG了。下面会贴上整个源代码,代码我加上了注释,下面讲讲使用HAL库要注意的地方。
在DCMI初始后面,HAL里面会默认打开FRAME中断,但捕捉到一帧后,会关闭这个中断,所以每次拍照都要打开FRAME中断。(是不是很多人发现只能拍一次?)
__HAL_DCMI_ENABLE_IT(&DCMI_hdcmi, DCMI_IT_FRAME);
HAL_DCMI_Start_DMA(&DCMI_hdcmi, DCMI_MODE_SNAPSHOT,(uint32_t)JpegBuffer, pictureBufferLength);
NDTR存放了DMA 传输次数,他是递减的,使用pictureBufferLength-NDTR就是传输次数。
pictureLength=pictureBufferLength-DCMI_hdcmi.DMA_Handle->Instance->NDTR;
DCMI的FIFO是32位的,所以传输次数*4才是JPEG长度。(注意这里,配合手册一起看。)
pictureLength*=4;
还有在FRAME的回调函数里面,注意看以下:
void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
{
while(HAL_DMA_Abort(hdcmi->DMA_Handle)!=HAL_OK);
getPicture=1;
}
这里使用了HAL_DMA_Abort(hdcmi->DMA_Handle),因为JPEG每次的传输长度都不是固定的,我们可以通过FRAME中断来判断已经完成了一帧图像,
所以在这个中断里面,就可以中断DMA的传输了。
比较重要的事情就是上面那些了,如果成功捕捉到JPEG,在WATCH可以用到0XFF,0XD8。我们在PC的串口工具上可以直接看到JPEG数据。注意图片上红色注释。
最后,放出图像样张:上位机工具自己写的,写的很烂,稳定性也不好,所以不放出了
|
感谢分享