第四十章 摄像头实验
[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简介
本节将分为两个部分,分别介绍
OV2640和
STM32F4的
DCMI接口。
40.1.1 OV2640简介
OV2640是
OV(
OmniVision)公司生产的一颗
1/4寸的
CMOS UXGA(
1632*1232)图像传感器。该传感器体积小、工作电压低,提供单片
UXGA摄像头和影像处理器的所有功能。通过
SCCB 总线控制,可以输出整帧、子采样、缩放和取窗口等方式的各种分辨率
8/10位影像数据。该产品
UXGA图像最高达到
15帧
/秒(
SVGA可达
30帧,
CIF可达
60帧)。用户可以完全控制图像质量、数据格式和传输方式。所有图像处理功能过程包括伽玛曲线、白平衡、对比度、 {MOD}度等都可以通过
SCCB接口编程。
OmmiVision 图像传感器应用独有的传感器技术,通过减少或消除光学或电子缺陷如固定图案噪声、拖尾、浮散等,提高图像质量,得到清晰的稳定的彩 {MOD}图像。
OV2640的特点有:
l
高灵敏度、低电压适合嵌入式应用
l
标准的
SCCB接口,兼容
IIC接口
l
支持
RawRGB、
RGB(RGB565/RGB555)、
GRB422、
YUV(422/420)和
YCbCr(
422)输出格式
l
支持
UXGA、
SXGA、
SVGA以及按比例缩小到从
SXGA到
40*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个像素,最大输出尺寸为
UXGA(
1600*1200),即
200W像素。
2.模拟信号处理(Analog Processing)
模拟信号处理所有模拟功能,并包括:模拟放大(
AMP)、增益控制、通道平衡和平衡控制等。
3.10位A/D 转换(A/D)
原始的信号经过模拟放大后,分
G和
BR两路进入一个
10 位的
A/D 转换器,
A/D 转换器工作频率高达
20M,与像素频率完全同步(转换的频率和帧率有关)。除
A/D转换器外,该模块还有黑电平校正(
BLC)功能。
4.数字信号处理器(DSP)
这个部分控制由原始信号插值到
RGB 信号的过程,并控制一些图像质量:
l
边缘锐化(二维高通滤波器)
l
颜 {MOD}空间转换(原始信号到
RGB或者
YUV/YCbYCr)
l
RGB {MOD}彩矩阵以消除串扰
l
{MOD}相和饱和度的控制
l
黑
/白点补偿
l
降噪
l
镜头补偿
l
可编程的伽玛
l
十位到八位数据转换
5.输出格式模块(Output Formatter)
该模块按设定优先级控制图像的所有输出数据及其格式。
6.压缩引擎(Compression Engine)
压缩引擎框图如图
40.1.1.2所示:
图
40.1.1.2 压缩引擎框图
从图可以看出,压缩引擎主要包括三部分:
DCT、
QZ和
entropy encoder(熵编码器),将原始的数据流,压缩成
jpeg数据输出。
7.微处理器(Microcontroller)
OV2640自带了一个
8位微处理器,该处理器有
512字节
SRAM,
4KB的
ROM,它提供一个灵活的主机到控制系统的指令接口,同时也具有细调图像质量的功能。
8.SCCB接口(SCCB Interface)
SCCB接口控制图像传感器芯片的运行,详细使用方法参照光盘的《
OmniVision Technologies Seril Camera Control Bus(SCCB) Specification》这个文档
9.数字视频接口(Digital Video Port)
OV2640拥有一个
10位数字视频接口
(支持
8位接法
),其
MSB和
LSB可以程序设置先后顺序,
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处理,缩放成我们输出到外部的图像大小。该设置将会对图像进行缩放处理,如果设置的图像输出大小不等于图像窗口设置图像大小,那么图像就会被缩放处理,只有这两者设置一样大的时候,输出比例才是
1:
1的。
因为
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])就是在
PCLK,
VSYNC和
HREF/ HSYNC的控制下进行的。首先看看行输出时序,如图
40.1.1.5所示:
图
40.1.1.5 OV2640行输出时序
从上图可以看出,图像数据在
HREF为高的时候输出,当
HREF变高后,每一个
PCLK时钟,输出一个
8位
/10位数据。我们采用
8位接口,所以每个
PCLK输出
1个字节,且在
RGB/YUV输出格式下,每个
tp=2个
Tpclk,如果是
Raw格式,则一个
tp=1个
Tpclk。比如我们采用
UXGA时序,
RGB565格式输出,每
2个字节组成一个像素的颜 {MOD}(高低字节顺序可通过
0XDA寄存器设置),这样每行输出总共有
1600*2个
PCLK周期,输出
1600*2个字节。
再来看看帧时序(
UXGA模式),如图
40.1.1.6所示:
图
40.1.1.6 OV2640帧时序
上图清楚的表示了
OV2640在
UXGA模式下的数据输出。我们按照这个时序去读取
OV2640的数据,就可以得到图像数据。
最后说一下
OV2640的图像数据格式,我们一般用
2种输出方式:
RGB565和
JPEG。当输出
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 位并行接口
● 内嵌码
/外部行同步和帧同步
● 连续模式或快照模式
● 裁剪功能
● 支持以下数据格式:
1,
8/10/12/14 位逐行视频:单 {MOD}或原始拜尔(
Bayer)格式
2,
YCbCr 4:2:2逐行视频
3,
RGB 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)保持同步,并根据像素时钟的极性在像素时钟上升沿
/下降沿发生变化。
HSYNC(
HREF)信号指示行的开始
/结束,
VSYNC信号指示帧的开始
/结束。
DCMI信号波形如图
40.1.2.2所示:
图
40.1.2.2 DCMI信号波形
上图中,对应设置为:
DCMI_PIXCLK的捕获沿为下降沿,
DCMI_HSYNC和
DCMI_VSYNC的有效状态为
1,注意,这里的有效状态实际上对应的是指示数据在并行接口上无效时,
HSYNC/VSYNC引脚上面的引脚电平。
本章我们用到
DCMI的
8位数据宽度,通过设置
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可以看出,
STM32F4的
DCMI接口,接收的数据是低字节在前,高字节在后的,所以,要求摄像头输出数据也是低字节在前,高字节在后才可以,否则就还得程序上处理字节顺序,会比较麻烦。
DCMI接口支持
DMA传输,当
DCMI_CR寄存器中的
CAPTURE位置
1时,激活
DMA接口。摄像头接口每次在其寄存器中收到一个完整的
32位数据块时,都将触发一个
DMA请求。
DCMI接口支持两种同步方式:内嵌码同步和硬件(
HSYNC和
VSYNC)同步。我们简单介绍下硬件同步,详细介绍请参考《
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章相关内容。
本章,我们将使用
STM32F407ZGT6的
DCMI接口连接
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时钟作为
OV2640的
XVCLK输入。同时自带了稳压芯片,用于提供
OV2640稳定的
2.8V和
1.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才可以采集)。这样,
STM32F4的
DCMI接口就必须设置为:
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。该位使能后,将激活
DMA,
DCMI等待第一帧开始,然后生成
DMA请求将收到的数据传输到目标存储器中。注意:该位必须在
DCMI的其他配置(包括
DMA)都设置好了之后,才设置!!
DCMI_CR寄存器的其他位,我们就不介绍了,另外
DCMI的其他寄存器这里也不再介绍,请大家参考《
STM32F4xx中文参考手册》第
13.8节。
最后,我们来看下怎么用库函数实现
DCMI驱动
OV2640的步骤:
1)配置OV2640控制引脚,并配置OV2640工作模式。
在启动
DCMI之前,我们先设置好
OV2640。
OV2640通过
OV_SCL和
OV_SDA进行寄存器配置,同时还有
OV_PWDN/OV_RESET等信号,我们也需要配置对应
IO状态,先设置
OV_PWDN=0,退出掉电模式,然后拉低
OV_RESET复位
OV2640,之后再设置
OV_RESET为
1,结束复位,然后就是对
OV2640的大把寄存器进行配置了,这里我们配置成
UXGA输出。
然后,可以根据我们的需要,设置成
RGB565输出模式,还是
JPEG输出模式。
学习到这里,怎么使能相关
IO口时钟以及配置相关模式这里我们就不再讲解,大家可以打开我们实验源码查看,
OV2640的初始化配置以及相关操作函数在我们实验的
ov2640.c源文件中,其中初始化在
OV2640_Init函数中,大家可以打开看看相关步骤。
2)配置相关引脚的模式和复用功能(AF13),使能时钟。
OV2640配置好之后,再设置
DCMI接口与摄像头模块连接的
IO口,使能
IO和
DCMI时钟,然后设置相关
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数据,我们也不使用
DCMI的
JPEG数据模式(实测设置不设置都一样),而是采用正常模式,直接采集。
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。
本章采用连续模式采集,并将采集到的数据输出到
LCD(
RGB565模式)或内存(
JPEG模式),所以源地址都是
DCMI_DR,而目的地址可能是
LCD->RAM或者
SRAM的地址。
DCMI的
DMA传输采用的是
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 硬件设计
并可选择
RGB565和
JPEG两种输出格式,当使用
RGB565时,输出图像将经过缩放处理(完全由
OV2640的
DSP控制),显示在
LCD上面。当使用
JPEG数据输出的时候,我们将收到的
JPEG数据,通过串口
2(
115200波特率),送给电脑,并利用电脑端上位机软件,显示接收到的图片,。
本章实验功能简介:开机后,初始化摄像头模块(OV2640),如果初始化成功,则提示选择模式:RGB565模式,或者JPEG模式。KEY0用于选择RGB565模式,KEY1用于选择JPEG模式。
当使用
RGB565时,输出图像(固定为:
UXGA)将经过缩放处理(完全由
OV2640的
DSP控制),显示在
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) 指示灯
DS0和
DS1
2) 4个按键
3) 串口
1和串口
2
4) TFTLCD模块
5) OV2640摄像头模块
这些资源,基本上都介绍过了,这里我们用到串口
2来传输
JPEG数据给上位机,其配置同串口
1几乎一模一样,支持串口
2的时钟来自
APB1,频率为
42Mhz。
我们重点介绍下探索者
STM32F4开发板的摄像头接口与
ALIENTEK OV2640摄像头模块的连接。在开发板的左下角的
2*9的
P8排座,是摄像头模块
/OLED模块共用接口,在第十七章,我们曾简单介绍过这个接口。本章,我们只需要将
ALIENTEK OV2640摄像头模块插入这个接口即可,该接口与
STM32的连接关系如图
40.2.1所示:
图
40.2.1 摄像头模块接口与
STM32连接图
从上图可以看出,
OV2640摄像头模块的各信号脚与
STM32的连接关系为:
DCMI_VSYNC接
PB7;
DCMI_HREF接
PA4;
DCMI_PCLK接
PA6;
DCMI_SCL接
PD6;
DCMI_SDA接
PD7;
DCMI_RESET接
PG15;
DCMI_PWDN接
PG9;
DCMI_XCLK接
PA8(本章未用到)
;
DCMI_D[7:0]接
PE6/PE5/PB6/PC11/PC9/PC8/PC7/PC6;
这些线的连接,探索者
STM32F4开发板的内部已经连接好了,我们只需要将
OV2640摄像头模块插上去就好了。
特别注意:DCMI摄像头接口和
I2S接口、
DAC、
SDIO以及
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,杜邦线连接P9的PA2(TX)和P6的RX)。
我们打开上位机软件:串口摄像头.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帧,这和我们前面介绍的OV2640在UXGA模式,输出帧率是15帧是一致的。
实验详细手册和源码下载地址:http://www.openedv.com/posts/list/41586.htm
正点原子探索者STM32F407开发板购买地址:http://item.taobao.com/item.htm?id=41855882779
一周热门 更多>