我对对应摄像头的认识最早应该是从之前飞思卡尔智能车(现在应该是恩智浦智能车了)开始的,那会儿有摄像头组,我参加的不是这个组别,但是对这个比较好奇,我是参加电磁组,采集的是磁场的中的几个点,根据点的值来推断通电导线位置。而摄像头是直接看一个面,低头看脚下,抬头看前方很是羡慕。再之后是参加论坛测评NXP LPC54100的时候想趁机会采集下摄像头,当时是用的之前的土办法,自己设行中断场中断来大致获取数据,数据量也有限,根本无法获得整张图片。 现在有了H7的板子,自然是要试试DCMI的,前面废话说了不少,马上开始正题。
DCMI配置大致如上图,再额外使能个串口。
下面是初始化代码
- DCMI->IER |= DCMI_IER_VSYNC_IE ;
- DCMI->CR |= DCMI_CR_CAPTURE | DCMI_CR_CM;
- DCMI->CR = 0x00094282;
复制代码
开中断,再中断里判断采集的状况。
- if((DCMI->RISR&DCMI_RIS_VSYNC_RIS)==DCMI_RIS_VSYNC_RIS)
- {
- DCMI->ICR |= DCMI_ICR_VSYNC_ISC;
- if(dcmi_line_cnt>0)finish_cnt[2]=dcmi_line_cnt;
- dcmi_line_cnt=0;
- if(dcmi_pixel_cnt>0)finish_cnt[0]=dcmi_pixel_cnt;
- dcmi_pixel_cnt=0;
-
- }
- if((DCMI->RISR&DCMI_RIS_LINE_RIS)==DCMI_RIS_LINE_RIS)
- {
- dcmi_line_cnt++;
- DCMI->ICR |= DCMI_ICR_LINE_ISC;
- }
- if((DCMI->RISR&DCMI_RIS_FRAME_RIS)==DCMI_RIS_FRAME_RIS)
- {
- if(dcmi_line_cnt>0)finish_cnt[3]=dcmi_line_cnt;
- dcmi_line_cnt=0;
- if(dcmi_pixel_cnt>0)finish_cnt[1]=dcmi_pixel_cnt;
- dcmi_pixel_cnt=0;
- DCMI->ICR |= DCMI_ICR_FRAME_ISC;
- vsync_flag=1;
- }
- if((DCMI->RISR&DCMI_RIS_OVR_RIS)==DCMI_RIS_OVR_RIS)
- {
- DCMI->ICR |= DCMI_ICR_OVR_ISC;
- }
- if((DCMI->RISR&DCMI_RIS_ERR_RIS)==DCMI_RIS_ERR_RIS)
- {
- DCMI->ICR |= DCMI_ICR_ERR_ISC;
- }
复制代码
在while循环里处理采集的数据,采集完完整的数据交给TFT显示,TFT显示是沿用之前的SPI TFT显示。
- if((DCMI->SR&DCMI_SR_FNE)==DCMI_SR_FNE)
- {
-
- d_temp.u32=DCMI->DR;
- d_buf[dcmi_pixel_cnt*2]=d_temp.u8[0];
- d_buf[dcmi_pixel_cnt*2+1]=d_temp.u8[2];
- dcmi_pixel_cnt++;
- if(dcmi_pixel_cnt>10000)
- dcmi_pixel_cnt=0;
- HAL_GPIO_TogglePin(LD3_GPIO_Port,LD3_Pin);
- }
- else
- {
- uart_decode();
- if(vsync_flag)
- {
- vsync_flag=0;
- showimageHUI2RGB(d_buf);
- //HAL_Delay(100);
- //DCMI->CR |= DCMI_CR_CAPTURE;
- }
- }
- }
复制代码
由于OV7620我用的只采灰度图像,TFT是彩屏,于是需要转换一下
tRGB =((x >> 3)|((x & ~3) << 3)|((x & ~7) << 8));
DCMI的功能很多,有各种功能,比如单次拍照,连续采集,全屏采集,指定区域采集,各种分配等。
除此调试有点摸不到头脑,于是写了个简单的上位机软件配合调试。
功能看下面串口解码函数就一目了然,上位机可以控制H7开始采集,可以将采集的数上传,也可以实时更改DCMI寄存器,这样调试就相对简单点,不用来回编译下载程序。
- void uart_decode(void)
- {
- if(uart_flag)
- {
- uart_flag=0;
- switch(uart_dara[2])
- {
- case 0:
- if(uart_dara[3])
- {
- DCMI->CR |= DCMI_CR_CAPTURE;
- }
- break;
- case 1:
- if(uart_dara[3])
- {
- HAL_UART_Transmit(&huart3,"START",5,100);
- HAL_UART_Transmit(&huart3,d_buf,19200,10000);
- HAL_UART_Transmit(&huart3,"END",3,100);
- DCMI->CR |= DCMI_CR_CAPTURE;
- }
- break;
- case 2:
- if(uart_dara[3])
- {
- DCMI->CR |= DCMI_CR_CM;
- }
- break;
- case 3:
- d_reg.u8[3]=uart_dara[4];
- d_reg.u8[2]=uart_dara[5];
- d_reg.u8[1]=uart_dara[6];
- d_reg.u8[0]=uart_dara[7];
- switch(uart_dara[3])
- {
- case 0:
-
- break;
- case 1:
- DCMI ->CR = d_reg.u32;
- break;
- case 2:
- DCMI ->CWSIZER = d_reg.u32;
- break;
- case 3:
- DCMI ->CWSTRTR = d_reg.u32;
- break;
- case 4:
- DCMI ->ESCR = d_reg.u32;
- break;
- case 5:
- DCMI ->ESUR = d_reg.u32;
- break;
- case 6:
- DCMI ->IER = d_reg.u32;
- break;
- }
- break;
-
- }
- }
- }
复制代码
上位机界面如下图
采集实拍
最后再来几张摄像头采集,TFT显示的图片。
DCMI的功能很强大,再配上H7的超高性能,应该可以做些人工智能或者机器视觉之类的东西,本次测评程序有点简陋,简单的测试了下DCMI的功能,没有使用DMA,这肯定很影响H7的正常发挥,希望H7不要介意。
本次测评到此结束,谢谢阅读!
此内容由EEWORLD论坛网友supermiao123原创,如需转载或用于商业用途需征得作者同意并注明出处