【正点原子探索者STM32F407开发板例程连载+教学】第40章 OV2640摄像头实验实验

2019-07-20 15:03发布

第四十章 摄像头实验

       [mw_shl_code=c,true] 1.硬件平台:正点原子探索者STM32F407开发板 2.软件平台:MDK5.1 3.固件库版本:V1.4.0 [/mw_shl_code]
ALIENTEK探索者STM32F4开发板具有DCMI接口,并板载了一个摄像头接口(P8),该接口可以用来连接ALIENTEK OV2640等摄像头模块。本章,我们将使用STM32驱动ALIENTEK OV2640摄像头模块,实现摄像头功能。本章分为如下几个部分: 40.1 OV2640&DCMI简介 40.2 硬件设计 40.3 软件设计 40.4 下载验证  

40.1 OV2640&DCMI简介

本节将分为两个部分,分别介绍OV2640STM32F4DCMI接口。

40.1.1 OV2640简介

OV2640OVOmniVision)公司生产的一颗1/4寸的CMOS UXGA1632*1232)图像传感器。该传感器体积小、工作电压低,提供单片UXGA摄像头和影像处理器的所有功能。通过SCCB 总线控制,可以输出整帧、子采样、缩放和取窗口等方式的各种分辨率8/10位影像数据。该产品UXGA图像最高达到15/秒(SVGA可达30帧,CIF可达60帧)。用户可以完全控制图像质量、数据格式和传输方式。所有图像处理功能过程包括伽玛曲线、白平衡、对比度、 {MOD}度等都可以通过SCCB接口编程。OmmiVision 图像传感器应用独有的传感器技术,通过减少或消除光学或电子缺陷如固定图案噪声、拖尾、浮散等,提高图像质量,得到清晰的稳定的彩 {MOD}图像。 OV2640的特点有: l  高灵敏度、低电压适合嵌入式应用 l  标准的SCCB接口,兼容IIC接口 l  支持RawRGBRGB(RGB565/RGB555)GRB422YUV(422/420)YCbCr422)输出格式 l  支持UXGASXGASVGA以及按比例缩小到从SXGA40*30的任何尺寸 l  支持自动曝光控制、自动增益控制、自动白平衡、自动消除灯光条纹、自动黑电平校准等自动控制功能。同时支持 {MOD}饱和度、 {MOD}相、伽马、锐度等设置。 l  支持闪光灯 l  支持图像缩放、平移和窗口设置 l  支持图像压缩,即可输出JPEG图像数据 l  自带嵌入式微处理器 OV2640的功能框图图如图40.1.1.1所示:
40.1.1.1 OV2640功能框图        OV2640传感器包括如下一些功能模块。        1.感光整列(Image Array OV2640总共有1632*1232个像素,最大输出尺寸为UXGA1600*1200),即200W像素。 2.模拟信号处理(Analog Processing 模拟信号处理所有模拟功能,并包括:模拟放大(AMP)、增益控制、通道平衡和平衡控制等。 3.10A/D 转换(A/D 原始的信号经过模拟放大后,分GBR两路进入一个10 位的A/D 转换器,A/D 转换器工作频率高达20M,与像素频率完全同步(转换的频率和帧率有关)。除A/D转换器外,该模块还有黑电平校正(BLC)功能。 4.数字信号处理器(DSP 这个部分控制由原始信号插值到RGB 信号的过程,并控制一些图像质量: l  边缘锐化(二维高通滤波器) l  颜 {MOD}空间转换(原始信号到RGB或者YUV/YCbYCr)RGB {MOD}彩矩阵以消除串扰 l  {MOD}相和饱和度的控制 l  黑/白点补偿 l  降噪 l  镜头补偿 l  可编程的伽玛 l  十位到八位数据转换 5.输出格式模块(Output Formatter 该模块按设定优先级控制图像的所有输出数据及其格式。 6.压缩引擎(Compression Engine 压缩引擎框图如图40.1.1.2所示:  40.1.1.2 压缩引擎框图        从图可以看出,压缩引擎主要包括三部分:DCTQZentropy encoder(熵编码器),将原始的数据流,压缩成jpeg数据输出。 7.微处理器(Microcontroller OV2640自带了一个8位微处理器,该处理器有512字节SRAM4KBROM,它提供一个灵活的主机到控制系统的指令接口,同时也具有细调图像质量的功能。 8.SCCB接口(SCCB Interface SCCB接口控制图像传感器芯片的运行,详细使用方法参照光盘的《OmniVision Technologies Seril Camera Control Bus(SCCB) Specification》这个文档 9.数字视频接口(Digital Video Port OV2640拥有一个10位数字视频接口(支持8位接法),其MSBLSB可以程序设置先后顺序,ALIENTEK OV2640模块采用默认的8位连接方式,如图40.1.1.3所示:  40.1.1.3 OV2640默认8位连接方式 OV2640的寄存器通过SCCB时序访问并设置,SCCB时序和IIC时序十分类似,在本章我们不做介绍,请大家参考光盘《OmniVision Technologies Seril Camera Control Bus(SCCB) Specification》这个文档。 接下来,我们介绍一下OV2640的传感器窗口设置、图像尺寸设置、图像窗口设置和图像输出大小设置,这几个设置与我们的正常使用密切相关,有必要了解一下。其中,除了传感器窗口设置是直接针对传感器阵列的设置,其他都是DSP部分的设置了,接下来我们一个个介绍。 传感器窗口设置,该功能允许用户设置整个传感器区域(1632*1220)的感兴趣部分,也就是在传感器里面开窗,开窗范围从2*2~1632*1220都可以设置,不过要求这个窗口必须大于等于随后设置的图像尺寸。传感器窗口设置,通过:0X03/0X19/0X1A/0X07/0X17/0X18等寄存器设置,寄存器定义请看OV2640_DS(1.6).pdf这个文档(下同)。 图像尺寸设置,也就是DSP输出(最终输出到LCD的)图像的最大尺寸,该尺寸要小于等于前面我们传感器窗口设置所设定的窗口尺寸。图像尺寸通过:0XC0/0XC1/0X8C等寄存器设置。 图像窗口设置,这里起始和前面的传感器窗口设置类似,只是这个窗口是在我们前面设置的图像尺寸里面,再一次设置窗口大小,该窗口必须小于等于前面设置的图像尺寸。该窗口设置后的图像范围,将用于输出到外部。图像窗口设置通过:0X51/0X52/0X53/0X54/0X55/0X57等寄存器设置。 图像输出大小设置,这是最终输出到外部的图像尺寸。该设置将图像窗口设置所决定的窗口大小,通过内部DSP处理,缩放成我们输出到外部的图像大小。该设置将会对图像进行缩放处理,如果设置的图像输出大小不等于图像窗口设置图像大小,那么图像就会被缩放处理,只有这两者设置一样大的时候,输出比例才是11的。 因为OmniVision 公司公开的文档,对这些设置实在是没有详细介绍。只能从他们提供的初始化代码(还得去linux源码里面移植过来)里面去分析规律,所以,这几个设置,都是作者根据OV2640的调试经验,以及相关文档总结出来的,不保证百分比正确,如有错误,还请大家指正。 以上几个设置,光看文字可能不太清楚,这里我们画一个简图有助于大家理解,如图40.1.1.4所示:  40.1.1.4 OV2640图像窗口设置简图        上图,最终红 {MOD}框所示的图像输出大小,才是OV2640输出给外部的图像尺寸,也就是显示在LCD上面的图像大小。当图像输出大小与图像窗口不等时,会进行缩放处理,在LCD上面看到的图像将会变形。 最后,我们介绍一下OV2640的图像数据输出格式。首先我们简单介绍一些定义: UXGA,即分辨率位1600*1200的输出格式,类似的还有:SXGA(1280*1024)WXGA+(1440*900)XVGA(1280*960)WXGA(1280*800)XGA(1024*768)SVGA(800*600)VGA(640*480)CIF(352*288)WQVGA(400*240)QCIF(176*144)QQVGA(160*120)等。 PCLK,即像素时钟,一个PCLK时钟,输出一个像素(或半个像素) VSYNC,即帧同步信号。 HREF /HSYNC,即行同步信号。 OV2640的图像数据输出(通过Y[9:0])就是在PCLKVSYNCHREF/ HSYNC的控制下进行的。首先看看行输出时序,如图40.1.1.5所示:  40.1.1.5 OV2640行输出时序 从上图可以看出,图像数据在HREF为高的时候输出,当HREF变高后,每一个PCLK时钟,输出一个8/10位数据。我们采用8位接口,所以每个PCLK输出1个字节,且在RGB/YUV输出格式下,每个tp=2Tpclk,如果是Raw格式,则一个tp=1Tpclk。比如我们采用UXGA时序,RGB565格式输出,每2个字节组成一个像素的颜 {MOD}(高低字节顺序可通过0XDA寄存器设置),这样每行输出总共有1600*2PCLK周期,输出1600*2个字节。 再来看看帧时序(UXGA模式),如图40.1.1.6所示:  40.1.1.6 OV2640帧时序 上图清楚的表示了OV2640UXGA模式下的数据输出。我们按照这个时序去读取OV2640的数据,就可以得到图像数据。 最后说一下OV2640的图像数据格式,我们一般用2种输出方式:RGB565JPEG。当输出RGB565格式数据的时候,时序完全就是上面两幅图介绍的关系。以满足不同需要。而当输出数据是JPEG数据的时候,同样也是这种方式输出(所以数据读取方法一模一样),不过PCLK数目大大减少了,且不连续,输出的数据是压缩后的JPEG数据,输出的JPEG数据以:0XFF,0XD8开头,以0XFF,0XD9结尾,且在0XFF,0XD8之前,或者0XFF,0XD9之后,会有不定数量的其他数据存在(一般是0),这些数据我们直接忽略即可,将得到的0XFF,0XD8~0XFF,0XD9之间的数据,保存为.jpg/.jpeg文件,就可以直接在电脑上打开看到图像了。 OV2640自带的JPEG输出功能,大大减少了图像的数据量,使得其在网络摄像头、无线视频传输等方面具有很大的优势。OV2640我们就介绍到这。

40.1.2 STM32F4 DCMI接口简介

STM32F4自带了一个数字摄像头(DCMI)接口,该接口是一个同步并行接口,能够接收外部8位、10位、12位或 14 CMOS 摄像头模块发出的高速数据流。可支持不同的数据格式:YCbCr4:2:2/RGB565逐行视频和压缩数据 (JPEG) STM32F4 DCM接口特点: 8 位、10 位、12 位或 14 位并行接口 ● 内嵌码/外部行同步和帧同步 ● 连续模式或快照模式 ● 裁剪功能 ● 支持以下数据格式: 18/10/12/14 位逐行视频:单 {MOD}或原始拜尔(Bayer)格式 2YCbCr 4:2:2逐行视频 3RGB 565 逐行视频 4,压缩数据:JPEG DCMI接口包括如下一些信号: 1,  数据输入(D[0:13]),用于接摄像头的数据输出,接OV2640我们只用了8位数据。 2,  水平同步(行同步)输入(HSYNC),用于接摄像头的HSYNC/HREF信号。 3,  垂直同步(场同步)输入(VSYNC),用于接摄像头的VSYNC信号。 4,  像素时钟输入(PIXCLK),用于接摄像头的PCLK信号。 DCMI接口是一个同步并行接口,可接收高速(可达 54 MB/s)数据流。该接口包含多达14条数据线(D13-D0)和一条像素时钟线(PIXCLK)。像素时钟的极性可以编程,因此可以在像素时钟的上升沿或下降沿捕获数据。 DCMI接收到的摄像头数据被放到一个32位数据寄存器(DCMI_DR)中,然后通过通用 DMA进行传输。图像缓冲区由 DMA 管理,而不是由摄像头接口管理。 从摄像头接收的数据可以按行/帧来组织(原始YUV/RGB/拜尔模式),也可以是一系列 JPEG图像。要使能 JPEG 图像接收,必须将 JPEG 位(DCMI_CR 寄存器的位 3)置 1 数据流可由可选的 HSYNC(水平同步)信号和 VSYNC(垂直同步)信号硬件同步,或者通 过数据流中嵌入的同步码同步。 STM32F4 DCMI接口的框图如图40.1.2.1所示:  40.1.2.1 DCMI接口框图 DCMI接口的数据与PIXCLK(即PCLK)保持同步,并根据像素时钟的极性在像素时钟上升沿/下降沿发生变化。HSYNCHREF)信号指示行的开始/结束,VSYNC信号指示帧的开始/结束。DCMI信号波形如图40.1.2.2所示:  40.1.2.2 DCMI信号波形        上图中,对应设置为:DCMI_PIXCLK的捕获沿为下降沿,DCMI_HSYNCDCMI_VSYNC的有效状态为1,注意,这里的有效状态实际上对应的是指示数据在并行接口上无效时,HSYNC/VSYNC引脚上面的引脚电平。        本章我们用到DCMI8位数据宽度,通过设置DCMI_CR中的EDM[1:0]=00设置。此时DCMI_D0~D7有效,DCMI_D8~D13上的数据则忽略,这个时候,每次需要4个像素时钟来捕获一个32位数据。捕获的第一个数据存放在32位字的LSB位置,第四个数据存放在32位字的MSB位置 ,捕获数据字节在32位字中的排布如表40.1.2.1所示:  40.1.2.1 8位捕获数据在32位字中的排布 从表40.1.2.1可以看出,STM32F4DCMI接口,接收的数据是低字节在前,高字节在后的,所以,要求摄像头输出数据也是低字节在前,高字节在后才可以,否则就还得程序上处理字节顺序,会比较麻烦。 DCMI接口支持DMA传输,当DCMI_CR寄存器中的CAPTURE位置1时,激活DMA接口。摄像头接口每次在其寄存器中收到一个完整的32位数据块时,都将触发一个DMA请求。 DCMI接口支持两种同步方式:内嵌码同步和硬件(HSYNCVSYNC)同步。我们简单介绍下硬件同步,详细介绍请参考《STM32F4xx中文数据手册》第13.5.3节。 硬件同步模式下将使用两个同步信号 (HSYNC/VSYNC)。根据摄像头模块/模式的不同,可能在水平/垂直同步期间内发送数据。由于系统会忽略HSYNC/VSYNC信号有效电平期间内接收的所有数据,HSYNC/VSYNC 信号相当于消隐信号。 为了正确地将图像传输到 DMA/RAM 缓冲区,数据传输将与VSYNC信号同步。选择硬件同步模式并启用捕获(DCMI_CR中的CAPTURE位置1)时,数据传输将与VSYNC信号的 无效电平同步(开始下一帧时)。之后传输便可以连续执行,由DMA将连续帧传输到多个连续的缓冲区或一个具有循环特性的缓冲区。为了允许DMA管理连续帧,每一帧结束时都将激活VSIF(垂直同步中断标志,即帧中断),我们可以利用这个帧中断来判断是否有一帧数据采集完成,方便处理数据。 DCMI接口的捕获模式支持:快照模式和连续采集模式。一般我们使用连续采集模式,通过DCMI_CR中的CM位设置。另外,DCMI接口还支持实现了4个字深度的 FIFO,配有一个简单的FIFO控制器,每次摄像头接口从AHB读取数据时读指针递增,每次摄像头接口向FIFO写入数据时写指针递增。因为没有溢出保护,如果数据传输率超过AHB接口能够承受的速率,FIFO中的数据就会被覆盖。如果同步信号出错,或者 FIFO 发生溢出,FIFO 将复位,DCMI 接口将等待新的数据帧开始。 关于DCMI接口的其他特性,我们这里就不再介绍了,请大家参考《STM32F4xx中文参考手册》第13章相关内容。 本章,我们将使用STM32F407ZGT6DCMI接口连接ALIENTEK OV2640摄像头模块,该模块采用8位数据输出接口,自带24M有源晶振,无需外部提供时钟,采用百万高清镜头,单独3.3V 供电即可正常使用。 ALIENTEK OV2640摄像头模块外观如图40.1.2.3所示:  40.1.2.3 ALIENTEK OV2640摄像头模块外观图 模块原理图如图40.1.2.4所示:  40.1.2.4 ALIENTEK OV2640摄像头模块原理图        从上图可以看出,ALIENTEK OV2640摄像头模块自带了有源晶振,用于产生24M时钟作为OV2640XVCLK输入。同时自带了稳压芯片,用于提供OV2640稳定的2.8V1.3V工作电压,模块通过一个2*9的双排排针(P1)与外部通信,与外部的通信信号如表40.1.2.2所示: 信号 作用描述 信号 作用描述 VCC3.3 模块供电脚,接3.3V电源 OV_PCLK 像素时钟输出 GND 模块地线 OV_PWDN 掉电使能(高有效) OV_SCL SCCB通信时钟信号 OV_VSYNC 帧同步信号输出 OV_SDA SCCB通信数据信号 OV_HREF 行同步信号输出 OV_D[7:0] 8位数据输出 OV_RESET 复位信号(低有效)40.1.2.2 OV2640模块信号及其作用描述        本章,我们将OV2640默认配置为UXGA输出,也就是1600*1200的分辨率,输出信号设置为:VSYNC高电平有效,HREF高电平有效,输出数据在PCLK的下降沿输出(即上升沿的时候,MCU才可以采集)。这样,STM32F4DCMI接口就必须设置为:VSYNC低电平有效、HSYNC低电平有效和PIXCLK上升沿有效,这些设置都是通过DCMI_CR寄存器控制的,该寄存器描述如图40.1.2.5所示:  40.1.2.5 DCMI_CR寄存器各位描述        ENABLE,该位用于设置是否使能DCMI,不过,在使能之前,必须将其他配置设置好。        FCRC[1:0],这两个位用于帧率控制,我们捕获所有帧,所以设置为00即可。        VSPOL,该位用于设置垂直同步极性,也就是VSYNC引脚上面,数据无效时的电平状态,根据前面说所,我们应该设置为0        HSPOL,该位用于设置水平同步极性,也就是HSYNC引脚上面,数据无效时的电平状态,同样应该设置为0        PCKPOL,该位用于设置像素时钟极性,我们用上升沿捕获,所以设置为1        CM,该位用于设置捕获模式,我们用连续采集模式,所以设置为0即可。 CAPTURE,该位用于使能捕获,我们设置为1。该位使能后,将激活DMADCMI等待第一帧开始,然后生成DMA请求将收到的数据传输到目标存储器中。注意:该位必须在DCMI的其他配置(包括DMA)都设置好了之后,才设置!!     DCMI_CR寄存器的其他位,我们就不介绍了,另外DCMI的其他寄存器这里也不再介绍,请大家参考《STM32F4xx中文参考手册》第13.8节。 最后,我们来看下怎么用库函数实现DCMI驱动OV2640的步骤: 1)配置OV2640控制引脚,并配置OV2640工作模式。 在启动DCMI之前,我们先设置好OV2640OV2640通过OV_SCLOV_SDA进行寄存器配置,同时还有OV_PWDN/OV_RESET等信号,我们也需要配置对应IO状态,先设置OV_PWDN=0,退出掉电模式,然后拉低OV_RESET复位OV2640,之后再设置OV_RESET1,结束复位,然后就是对OV2640的大把寄存器进行配置了,这里我们配置成UXGA输出。 然后,可以根据我们的需要,设置成RGB565输出模式,还是JPEG输出模式。        学习到这里,怎么使能相关IO口时钟以及配置相关模式这里我们就不再讲解,大家可以打开我们实验源码查看,OV2640的初始化配置以及相关操作函数在我们实验的ov2640.c源文件中,其中初始化在OV2640_Init函数中,大家可以打开看看相关步骤。 2)配置相关引脚的模式和复用功能(AF13),使能时钟。 OV2640配置好之后,再设置DCMI接口与摄像头模块连接的IO口,使能IODCMI时钟,然后设置相关IO口为复用功能模式,复用功能选择AF13(DCMI复用) 使能DCMI时钟的方法为: RCC _AHB2PeriphClockCmd(RCC_AHB2Periph_DCMI,ENABLE);//使能DCMI时钟 关于相关IO口设置复用功能的方法之前已经多次讲解,这里我们就只贴出关键代码片段:   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能输出 接下来我们就是设置复用映射,方法为: GPIO_PinAFConfig(GPIOA,GPIO_PinSource4,GPIO_AF_DCMI);//PA4,DCMI_HSYNC GPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_AF_DCMI); //PA6, DCMI_PCLK  GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_DCMI); //PB7, DCMI_VSYNC ……//省略部分IO映射代码 GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_DCMI); //PB6,DCMI_D5 GPIO_PinAFConfig(GPIOE,GPIO_PinSource5,GPIO_AF_DCMI); //PE5,DCMI_D6 GPIO_PinAFConfig(GPIOE,GPIO_PinSource6,GPIO_AF_DCMI); //PE6,DCMI_D7 3)配置DCMI相关设置。 这一步,主要通过DCMI_CR寄存器设置,包括VSPOL/HSPOL/PCKPOL/数据宽度等重要参数,都在这一步设置,同时我们也开启帧中断,编写DCMI中断服务函数,方便进行数据处理(尤其是JPEG模式的时候)。不过对于CAPTURE位,我们等待DMA配置好之后再设置,另外对于OV2640输出的JPEG数据,我们也不使用DCMIJPEG数据模式(实测设置不设置都一样),而是采用正常模式,直接采集。 DCMI相关寄存器的配置是通过函数DCMI_Init来实现的。接下来我们看看函数申明: void DCMI_Init(DCMI_InitTypeDef* DCMI_InitStruct); 同样,我们来看看结构体DCMI_InitTypeDef的定义: typedef struct {   uint16_t DCMI_CaptureMode;       uint16_t DCMI_SynchroMode;      uint16_t DCMI_PCKPolarity;       uint16_t DCMI_VSPolarity;        uint16_t DCMI_HSPolarity;        uint16_t DCMI_CaptureRate;       uint16_t DCMI_ExtendedDataMode; } DCMI_InitTypeDef; 结构体DCMI_InitTypeDef一共有7个成员变量,接下来我们来看看每个成员变量的含义: 第一个参数DCMI_CaptureMode是用来设置捕获模式为连续捕获模式还是快照模式。我们实验采取的是连续捕获模式值DCMI_CaptureMode_Continuous,也就是通过DMA连续传输数据到目标存储区。 第二个参数DCMI_SynchroMode用来选择同步方式为硬件同步还是内嵌码同步。如果选择硬件同步值DCMI_SynchroMode_Hardware,那么数据捕获由HSYNC/VSYNC信号同步,如果选择内嵌码同步方式值DCMI_SynchroMode_Embedded,那么数据捕获由数据流中嵌入的同步码同步。 第三个参数DCMI_PCKPolarity用来设置像素时钟极性为上升沿有效还是下降沿有效。我们实验使用的是上升沿有效,所以值为DCMI_PCKPolarity_Rising 第四个参数DCMI_VSPolarity用来设置垂直同步极性VSYNC为低电平有效还是高电平有效。也就是VSYNC引脚上面,数据无效时的电平状态。我们设置为VSYNC低电平有效。所以值为DCMI_VSPolarity_Low 第五个参数DCMI_HSPolarity用来设置水平同步极性为高电平有效还是低电平有效,也就是HSYNC引脚上面,数据无效时的电平状态。我们设置为HSYNC低电平有效。所以值为DCMI_HSPolarity_Low 第六个参数DCMI_CaptureRate用来设置帧捕获率。如果设置为值DCMI_CaptureRate_All_Frame,也就是全帧捕获,设置为DCMI_CaptureRate_1of2_Frame,也就2帧捕获一帧,设置为DCMI_CaptureRate_1of4_Frame,也就是4帧捕获一帧。 第七个参数DCMI_ExtendedDataMode用来设置扩展数据模式。可以设置为每个像素时钟捕获8位,10位,12位以及14位数据。这里我们设置为8位值DCMI_ExtendedDataMode_8b DCMI初始化实例如下: DCMI_InitTypeDef DCMI_InitStructure; DCMI_InitStructure.DCMI_CaptureMode=DCMI_CaptureMode_Continuous;//连续模式 DCMI_InitStructure.DCMI_CaptureRate=DCMI_CaptureRate_All_Frame;//全帧捕获 DCMI_InitStructure.DCMI_ExtendedDataMode= DCMI_ExtendedDataMode_8b;//8位格式  DCMI_InitStructure.DCMI_HSPolarity= DCMI_HSPolarity_Low;//HSYNC 低电平有效 DCMI_InitStructure.DCMI_PCKPolarity= DCMI_PCKPolarity_Rising;//PCLK 上升沿有效 DCMI_InitStructure.DCMI_SynchroMode= DCMI_SynchroMode_Hardware;//硬件同步 DCMI_InitStructure.DCMI_VSPolarity=DCMI_VSPolarity_Low;//VSYNC 低电平有效 DCMI_Init(&DCMI_InitStructure);//初始化DCMI 4)配置DMA 本章采用连续模式采集,并将采集到的数据输出到LCDRGB565模式)或内存(JPEG模式),所以源地址都是DCMI_DR,而目的地址可能是LCD->RAM或者SRAM的地址。DCMIDMA传输采用的是DMA2数据流1的通道1来实现的,关于DMA的介绍,请大家参考前面的DMA实验章节。这里我们列出本章我们的DMA配置源码如下: DMA_InitTypeDef  DMA_InitStructure; DMA_InitStructure.DMA_Channel = DMA_Channel_1;  //通道1 DCMI通道 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&DCMI->DR;//外设地址为CMI->DR DMA_InitStructure.DMA_Memory0BaseAddr = (u32)&LCD->LCD_RAM;//存储器0地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;//外设到存储器模式 DMA_InitStructure.DMA_BufferSize = 1;//数据传输量 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设非增量模式 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器增量模式 DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;// 使用循环模式 DMA_InitStructure.DMA_Priority = DMA_Priority_High;//高优先级 DMA_InitStructure.DMA_FIFOMode=DMA_FIFOMode_Enable; //FIFO模式        DMA_InitStructure.DMA_FIFOThreshold=DMA_FIFOThreshold_Full;//使用全FIFO DMA_InitStructure.DMA_MemoryBurst=DMA_MemoryBurst_Single;//外设突发单次传输 DMA_InitStructure.DMA_PeripheralBurst=DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream1, &DMA_InitStructure);//初始化DMA Stream 5)设置OV2640的图像输出大小,使能DCMI捕获。 图像输出大小设置,分两种情况:在RGB565模式下,我们根据LCD的尺寸,设置输出图像大小,以实现全屏显示(图像可能因缩放而变形);在JPEG模式下,我们可以自由设置输出图像大小(可不缩放);最后,开启DCMI捕获,即可正常工作了。开启DCMI捕获的方法为: DCMI_CaptureCmd(ENABLE);//DCMI捕获使能 设置过程就给大家讲解到这里。

40.2 硬件设计

并可选择RGB565JPEG两种输出格式,当使用RGB565时,输出图像将经过缩放处理(完全由OV2640DSP控制),显示在LCD上面。当使用JPEG数据输出的时候,我们将收到的JPEG数据,通过串口2115200波特率),送给电脑,并利用电脑端上位机软件,显示接收到的图片,。 本章实验功能简介:开机后,初始化摄像头模块(OV2640),如果初始化成功,则提示选择模式:RGB565模式,或者JPEG模式。KEY0用于选择RGB565模式,KEY1用于选择JPEG模式。 当使用RGB565时,输出图像(固定为:UXGA)将经过缩放处理(完全由OV2640DSP控制),显示在LCD上面。我们可以通过KEY_UP按键选择:1:1显示,即不缩放,图片不变形,但是显示区域小(液晶分辨率大小),或者缩放显示,即将1600*1200的图像压缩到液晶分辨率尺寸显示,图片变形,但是显示了整个图片内容。通过KE0Y按键,可以设置对比度;KEY1按键,可以设置饱和度;KEY2按键,可以设置特效。 当使用JPEG模式时,图像可以设置任意尺寸(QQVGA~UXGA),采集到的JPEG数据将先存放到STM32F4的内存里面,每当采集到一帧数据,就会关闭DMA传输,然后将采集到的数据发送到串口2(此时可以通过上位机软件(串口摄像头.exe)接收,并显示图片),之后再重新启动DMA传输。我们可以通过KEY_UP设置输出图片的尺寸(QQVGA~UXGA)。通过KEY0按键,可以设置对比度;KEY1按键,可以设置饱和度;KEY2按键,可以设置特效。 同时时可以通过串口1,借助USMART设置/读取OV2640的寄存器,方便大家调试。DS0指示程序运行状态,DS1用于指示帧中断。 本实验用到的硬件资源有: 1)  指示灯DS0DS1 2)  4个按键 3)  串口1和串口2 4)  TFTLCD模块 5)  OV2640摄像头模块 这些资源,基本上都介绍过了,这里我们用到串口2来传输JPEG数据给上位机,其配置同串口1几乎一模一样,支持串口2的时钟来自APB1,频率为42Mhz     我们重点介绍下探索者STM32F4开发板的摄像头接口与ALIENTEK OV2640摄像头模块的连接。在开发板的左下角的2*9P8排座,是摄像头模块/OLED模块共用接口,在第十七章,我们曾简单介绍过这个接口。本章,我们只需要将ALIENTEK OV2640摄像头模块插入这个接口即可,该接口与STM32的连接关系如图40.2.1所示:  40.2.1 摄像头模块接口与STM32连接图       从上图可以看出,OV2640摄像头模块的各信号脚与STM32的连接关系为:               DCMI_VSYNCPB7;              DCMI_HREFPA4;              DCMI_PCLKPA6;               DCMI_SCLPD6;               DCMI_SDAPD7; DCMI_RESETPG15; DCMI_PWDNPG9; DCMI_XCLKPA8(本章未用到); DCMI_D[7:0]PE6/PE5/PB6/PC11/PC9/PC8/PC7/PC6; 这些线的连接,探索者STM32F4开发板的内部已经连接好了,我们只需要将OV2640摄像头模块插上去就好了。特别注意:DCMI摄像头接口和I2S接口、DACSDIO以及1WIRE_DQ等有冲突,使用的时候,必须分时复用才可以,不可同时使用。实物连接如图40.2.2所示:  图40.2.2 OV2640摄像头模块与开发板连接实物图

40.3 软件设计

 软件设计请直接下载附件的pdf讲解和实验工程。

40.4 下载验证

在代码编译成功之后,我们通过下载代码到ALIENTEK探索者STM32F4开发板上,在OV2640初始化成功后,屏幕提示选择模式,此时我们可以按KEY0,进入RGB565模式测试,也可以按KEY1,进入JPEG模式测试。 当按KEY0后,选择RGB565模式,LCD满屏显示压缩放后的图像(有变形),如图40.4.1所示:
40.4.1 RGB565模式测试图片 此时,可以按KEY_UP切换为1:1显示(不变形)。同时还可以通过KEY0按键,设置对比度;KEY1按键,设置饱和度;KEY2,可以设置特效。 当按KEY1后,选择JPEG模式,此时屏幕显示JPEG数据传输进程,如图40.4.2所示:  40.4.2 JPEG模式测试图 默认条件下,图像分辨率是QVGA(320*240)的,硬件上:我们需要一根RS232串口线连接开发板的COM2(注意要用跳线帽将P9的:COM2_RX连接在PA2(TX))。如果没有RS232线,也可以借助我们开发板板载的USB转串口实现(有2个办法:1,改代码;2,杜邦线连接P9PA2(TX)P6RX)。 我们打开上位机软件:串口摄像头.exe(路径:光盘à6,软件资料à软件à串口摄像头软件à串口摄像头.exe),选择正确的串口,然后波特率设置为115200,打开即可收到下位机传过来的图片了,如图40.4.3所示:  40.4.3 串口摄像头软件接收并显示JPEG图片 我们可以通过KEY_UP设置输出图像的尺寸(QQVGA~UXGA)。通过KEY0按键,设置对比度;KEY1按键,设置饱和度;KEY2按键,设置特效。  同时,你还可以在串口,通过USMART调用SCCB_WR_Reg等函数,来设置OV2640的各寄存器,达到调试测试OV2640的目的,如图40.4.4所示:  40.4.4 USMART调试OV2640        从上图还可以看出,帧率为15帧,这和我们前面介绍的OV2640UXGA模式,输出帧率是15帧是一致的。
  实验详细手册和源码下载地址:http://www.openedv.com/posts/list/41586.htm  正点原子探索者STM32F407开发板购买地址http://item.taobao.com/item.htm?id=41855882779
  


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
30条回答
heitu103
1楼-- · 2019-07-22 17:35
原子兄,OV2640的这个函数OV2640_OutSize_Set(u16 width,u16 height),这个函数设置图像输出的高和宽不是任意窗口是吧,找了OV的手册,上面没具体说
正点原子
2楼-- · 2019-07-22 17:57
 精彩回答 2  元偷偷看……
heitu103
3楼-- · 2019-07-22 20:43
回复【21楼】正点原子:
---------------------------------
看了,就是宽高有倍数关系,不知道咋弄成任意窗口
正点原子
4楼-- · 2019-07-23 02:02
 精彩回答 2  元偷偷看……
至尊宝19900810
5楼-- · 2019-07-23 06:36
 精彩回答 2  元偷偷看……
俊志俊
6楼-- · 2019-07-23 09:06
这个太棒了

一周热门 更多>