本帖最后由 colin2135 于 2017-1-17 23:18 编辑
上一次分享是学习笔记,对代码的一些解释,这一篇是当时自己看完代码后,作了一点小小的改动。
官方的DEMO里,需要把JPEG图片放到SD卡中,并改名为image.jpg,非常不方便。
这篇分享,我更改了官方的demo,图片的输入源通过F446连接相机获取JPEG图片,通过串口发送到F769,再进行JPEG解码,并显示到LCD。
原理我画了个小图,如下:
先放最终的效果图吧,看完有兴趣的继续看,没兴趣的点个赞哈。
模特找了个小公仔,也不知道是叫啥,图片用的是320*240分辨率,在这个800*480的屏幕上显得有点少。
用杜邦线接的线,有点乱,但是功能正常。
保存到SD卡后,用电脑显示:
OK,下面开始又是代码介绍啦,想看的继续哈。
关于F446部分就不再介绍了,之前以前发过帖子了,【f446RE开发板试用】教你用HAL库DCMI捕捉OV2640
先说下控制流程(F769):
按USER键 -> 启动外部中断 ->中断回调用串口发送拍照指令0x12,0x34->等待F446返回8字节大小数据(关于JPEG图像的大小length)->接收长度为length长度的Jpeg图像->保存到SD卡->调用Jpeg解码->将ARGB8888图像显示到LCD->回到第一步
非常简单明了,下面只讲重点。
1.外部中断回调,发送拍照指令,aTxBuffer是拍照指令Buffer为0x12,0x34
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == GPIO_PIN_0)
{
/* Toggle LED2 */
BSP_LED_Toggle(LED2);
HAL_UART_Transmit_DMA(&UartHandle, (uint8_t*)aTxBuffer, 2);
}
}
2.串口接收中断里设置两个标志位rxLengthFlag、rxDataFlag,一个是接收到JPEG数据长度标志,一个是接收到JPEG图像标志
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
/* Set transmission flag: trasfer complete*/
if(rxLengthFlag==0)
rxLengthFlag=1;
else{
rxDataFlag=1;
}
}
3.当接收到图像长度标志位时,解析这个8字节的数据包,在F446里,我设置了8个字节发送,前面4个字节是”JPEG“,后面4字节是JPEG长度
uint32_t *p=(uint32_t *)(aRxBuffer+4);
dataLength=(uint32_t)*p;知道长度后,就可以调用DMA接收图像了,图像放在uint8_t JPEGDate[10240]一个10K的数组里面,对了320*240的JPEG图像只有6K左右,所以足够
if(rxLengthFlag==1){
if(rxDataFlag==0){
if(aRxBuffer[0]=='J' && aRxBuffer[1]=='P' && aRxBuffer[2]=='E' && aRxBuffer[3]=='G' ){
uint32_t *p=(uint32_t *)(aRxBuffer+4);
dataLength=(uint32_t)*p;
HAL_UART_Receive_DMA(&UartHandle, (uint8_t *)JPEGDate, dataLength);
}
}
4.接收完成图像后,在SD卡里新建一张叫Image.jpg的图像,注意这里的参数FA_CREATE_ALWAYS|FA_WRITE,字面的意思是说,每次的创建新的一张,并且可读。if(f_open(&JPEG_File, "image.jpg", FA_CREATE_ALWAYS|FA_WRITE) == FR_OK)
5.把JPEGDate数据里的JPEG图像数据写入image.jpg
while(f_write (&JPEG_File, JPEGDate, dataLength,&bw)!=FR_OK) /* Write data to a file */
{
}
f_close(&JPEG_File);
6.下面的就跟官方demo里的一样了,调用Jpeg解码,并显示到LCD,很简单,原理参考上一 讲的笔记。
|