为什么用DCMI内存读取速度OV2640JPEG时要DMA用双缓存模式

全套200集视频教程和1000PDF教程请到秉吙论坛下载:

野火视频教程优酷观看网址:/firege

关于开发板配套的OV2640摄像头参数可查阅《ov2640datasheet》配套资料获知

STM32F4芯片具有浮点运算单元,适合对图像信息使用DSP进行基本的图像处理其处理速度比传统的816位机快得多,而且它还具有与摄像头通讯的专用DCMI接口所以使用它驱动摄像头采集圖像信息并进行基本的加工处理非常适合。本章讲解如何使用STM32驱动OV2640型号的摄像头

在各类信息中,图像含有最丰富的信息作为机器视觉領域的核心部件,摄像头被广泛地应用在安防、探险以及车牌检测等场合摄像头按输出信号的类型来看可以分为数字摄像头和模拟摄像頭,按照摄像头图像传感器材料构成来看可以分为CCDCMOS现在智能手机的摄像头绝大部分都是CMOS类型的数字摄像头。

45.1.1 数字摄像头跟模拟摄像头區别

数字摄像头输出信号为数字信号模拟摄像头输出信号为标准的模拟信号。

数字摄像头有USB接口(比如常见的PC端免驱摄像头)IEE1394火线接口(由蘋果公司领导的开发联盟开发的一种高速度传送接口数据传输率高达800Mbps)、千兆网接口(网络摄像头)。模拟摄像头多采用AV视频端子(信号線+地线)或S-VIDEO(即莲花头--SUPER VIDEO是一种五芯的接口,由两路视频亮度信号、两路视频色度信号和一路公共屏蔽地线共五条芯线组成)

模拟摄像頭的感光器件,其像素指标一般维持在752(H)*582(V)左右的水平像素数一般情况下维持在41万左右。现在的数字摄像头分辨率一般从数十万到数千万泹这并不能说明数字摄像头的成像分辨率就比模拟摄像头的高,原因在于模拟摄像头输出的是模拟视频信号一般直接输入至电视或监视器,其感光器件的分辨率与电视信号的扫描数呈一定的换算关系图像的显示介质已经确定,因此模拟摄像头的感光器件分辨率不是不能莋高而是依据于实际情况没必要做这么高。

摄像头的图像传感器CCDCMOS传感器主要区别如下:

由于CCD的像素由MOS电容构成内存读取速度电荷信號时需使用电压相当大(至少12V)的二相或三相或四相时序脉冲信号,才能有效地传输电荷因此CCD的取像系统除了要有多个电源外,其外设电路吔会消耗相当大的功率有的CCD取像系统需消耗2~5W的功率。而CMOS光电传感器件只需使用一个单电源5V3V耗电量非常小,仅为CCD1/8~1/10有的CMOS取像系统只消耗20~50mW的功率。

CCD传感器件制作技术起步早技术成熟,采用PN结或二氧化硅(sio2)隔离层隔离噪声所以噪声低,成像质量好与CCD相比,CMOS的主要缺点昰噪声高及灵敏度低不过现在随着CMOS电路消噪技术的不断发展,为生产高密度优质的CMOS传感器件提供了良好的条件现在的CMOS传感器已经占领叻大部分的市场,主流的单反相机、智能手机都已普遍采用CMOS传感器

本章主要讲解实验板配套的摄像头,它的实物见图 451该摄像头主要由鏡头、图像传感器、板载电路及下方的信号引脚组成。

镜头部件包含一个镜头座和一个可旋转调节距离的凸透镜通过旋转可以调节焦距,正常使用时镜头座覆盖在电路板上遮光,光线只能经过镜头传输到正中央的图像传感器它采集光线信号,然后把采集得的数据通过丅方的信号引脚输出数据到外部器件

图像传感器是摄像头的核心部件,上述摄像头中的图像传感器是一款型号为OV2640CMOS类型数字图像传感器该传感器支持输出最大为200万像素的图像 (分辨率),支持使用VGA时序输出图像数据输出图像的数据格式支持YUV(422/420)YCbCr422RGB565以及JPEG格式,若直接输出JPEG格式嘚图像时可大大减少数据量方便网络传输。它还可以对采集得的图像进行补偿支持伽玛曲线、白平衡、饱和度、色度等基础处理。根據不同的分辨率配置传感器输出图像数据的帧率从15-60帧可调,工作时功率在125mW-140mW之间

OV2640传感器采用BGA封装,它的前端是采光窗口引脚都在背面引出,引脚的分布见图 452

图中的非彩色部分是电源相关的引脚,彩色部分是主要的信号引脚介绍如下表 451

SCCB总线的时钟线可类比I2CSCL

SCCB总线嘚数据线,可类比I2CSDA

系统复位管脚低电平有效

掉电/省电模式,高电平有效

外部时钟输入端口可接外部晶振

下面我们配合图 453中的OV2640功能框圖讲解这些信号引脚。

标号?处的是OV2640的控制寄存器它根据这些寄存器配置的参数来运行,而这些参数是由外部控制器通过SIO_CSIO_D引脚写入的SIO_CSIO_D使用的通讯协议跟I2C十分类似,在STM32中我们完全可以直接用I2C硬件外设来控制

标号?处包含了OV2640的通信、控制信号及外部时钟,其中PCLKHREFVSYNC分別是像素同步时钟、行同步信号以及帧同步信号这与液晶屏控制中的信号是很类似的。RESETB引脚为低电平时用于复位整个传感器芯片,PWDN用於控制芯片进入低功耗模式注意最后的一个XCLK引脚,它跟PCLK是完全不同的XCLK是用于驱动整个传感器芯片的时钟信号,是外部输入到OV2640的信号;洏PCLKOV2640输出数据时的同步信号它是由OV2640输出的信号。XCLK可以外接晶振或由外部控制器提供若要类比XCLK之于OV2640就相当于HSE时钟输入引脚与STM32芯片的关系,PCLK引脚可类比STM32I2C外设的SCL引脚

标号?处的是感光矩阵,光信号在这里转化成电信号经过各种处理,这些信号存储成由一个个像素点表示嘚数字图像

标号?处包含了DSP处理单元,它会根据控制寄存器的配置做一些基本的图像处理运算这部分还包含了图像格式转换单元及压縮单元,转换出的数据最终通过Y0-Y9引脚输出一般来说我们使用8根据数据线来传输,这时仅使用Y2-Y9引脚OV2640与外部器件的连接方式见图

454 8位数据線接法

外部控制器对OV2640寄存器的配置参数是通过SCCB总线传输过去的,而SCCB总线跟I2C十分类似所以在STM32驱动中我们直接使用片上I2C外设与它通讯。SCCB与标准的I2C协议的区别是它每次传输只能写入或内存读取速度一个字节的数据而I2C协议是支持突发读写的,即在一次传输中可以写入多个字节的數据(EEPROM中的页写入时序即突发写)关于SCCB协议的完整内容可查看配套资料里的《SCCB协议》文档,下面我们简单介绍下

SCCB的起始、停止信号及数据囿效性

SCCB的起始信号、停止信号及数据有效性与I2C完全一样,见图 455及图 456

?    数据有效性:除了开始和停止状态,在数据传输过程中当SIO_C为高电岼时,必须保证SIO_D上的数据稳定也就是说,SIO_D上的电平变换只能发生在SIO_C为低电平的时候SIO_D的信号在SIO_C为高电平时被采集。

SCCB协议中定义的读写操作与I2C也是一样的只是换了一种说法。它定义了两种写操作即三步写操作和两步写操作。三步写操作可向从设备的一个目的寄存器中寫入数据见图 457。在三步写操作中第一阶段发送从设备的ID地址+W标志(等于I2C的设备地址:7位设备地址+读写方向标志),第二阶段发送从设备目標寄存器的8位地址第三阶段发送要写入寄存器的8位数据。图中的"X"数据位可写入10对通讯无影响。

而两步写操作没有第三阶段即只向從器件传输了设备ID+W标志和目的寄存器的地址,见图 458两步写操作是用来配合后面的读寄存器数据操作的,它与读操作一起使用实现I2C的复匼过程。

两步读操作它用于内存读取速度从设备目的寄存器中的数据,见图 459在第一阶段中发送从设备的设备ID+R标志(设备地址+读方向标志)囷自由位,在第二阶段中内存读取速度寄存器中的8位数据和写NA (非应答信号)由于两步读操作没有确定目的寄存器的地址,所以在读操作湔必需有一个两步写操作,以提供读操作中的寄存器地址

可以看到,以上介绍的SCCB特性都与I2C无区别而I2CSCCB还多出了突发读写的功能,所鉯SCCB可以看作是I2C的子集我们完全可以使用STM32I2C外设来与OV2640进行SCCB通讯。

控制OV2640涉及到它很多的寄存器可直接查询《ov2640datasheet》了解,通过这些寄存器的配置可以控制它输出图像的分辨率大小、图像格式及图像方向等。要注意的是OV2640有两组寄存器这两组寄存器有部分地址重合,通过设置地址为0xFFRA_DLMT寄存器可以切换寄存器组当RA_DLMT寄存器为0时,通过SCCB发送的寄存器地址在DSP相关的寄存器组寻址见图

官方还提供了一个《OV2640_Camera_app》的文档,它針对不同的配置需求提供了配置范例,见图 4512其中write_SCCB是一个利用SCCB向寄存器写入数据的函数,第一个参数为要写入的寄存器的地址第二个參数为要写入的内容。

4512 调节帧率的寄存器配置范例

45.2.5 像素数据输出时序

主控器控制OV2640时采用SCCB协议读写其寄存器而它输出图像时则使用VGA时序(還可用SVGAUXGA,这些时序都差不多)这跟控制液晶屏输入图像时很类似。OV2640输出图像时一帧帧地输出,在帧内的数据一般从左到右从上到下,一个像素一个像素地输出(也可通过寄存器修改方向)见图

4513 摄像头数据输出

例如,见图 4514和图 4515若我们使用Y2-Y9数据线,图像格式设置为RGB565进荇数据输出时,Y2-Y9数据线会在1个像素同步时钟PCLK的驱动下发送1字节的数据信号所以2PCLK时钟可发送1RGB565格式的像素数据。像素数据依次传输每傳输完一行数据时,行同步信号HREF会输出一个电平跳变信号每传输完一帧图像时,VSYNC会输出一个电平跳变信号

4514像素同步时序

4515 帧图像同步时序

Interface),它支持使用上述类似VGA的时序获取图像数据流支持原始的按行、帧格式来组织的图像数据,如YUVRGB也支持接收JPEG格式压缩的数据流。接收数据时主要使用HSYNCVSYNC信号来同步。

上图标号?处的是DCMI向外部引出的信号线DCMI提供的外部接口的方向都是输入的,接口的各个信号线說明见表 452

行同步信号(水平同步信号)

帧同步信号(垂直同步信号)

其中DCMI_D数据线的数量可选8101214位,各个同步信号的有效极性都可编程控制咜使用的通讯时序与OV2640的图像数据输出接口时序一致,见图

内部信号及PIXCLK的时钟频率

4516的标号?处表示DCMI与内部的信号线在STM32的内部,使用HCLK作为时鍾源提供给DCMI外设从DCMI引出有DCMI_IT信号至中断控制器,并可通过DMA_REQ信号发送DMA请求

DCMI从外部接收数据时,在HCLK的上升沿时对PIXCLK同步的信号进行采样它限淛了PIXCLK的最小时钟周期要大于2.5HCLK时钟周期,即最高频率为HCLK1/4

DCMI接口的内部结构见图 4518

同步器主要用于管理DCMI接收数据的时序它根据外部的信號提取输入的数据。

为了对数据传输加以管理STM32DCMI接口上实现了 4 个字(32bit x4)深度的 FIFO,用以缓冲接收到的数据

DCMI接口挂载在AHB总线上,在AHB总线中有一個DCMI接口的数据寄存器当我们内存读取速度该寄存器时,它会从FIFO中获取数据并且FIFO中的数据指针会自动进行偏移,使得我们每次内存读取速度该寄存器都可获得一个新的数据

DCMI的控制寄存器协调图中的各个结构运行,程序中可通过检测状态寄存器来获DCMI的当前运行状态

由于DCMI采集的数据量很大,我们一般使用DMA来把采集得的数据搬运至内存

DCMI接口支持硬件同步或内嵌码同步方式,硬件同步方式即使用HSYNCVSYNC作为同步信号的方式OV2640就是使用这种同步时序。

而内嵌码同步的方式是使用数据信号线传输中的特定编码来表示同步信息由于需要用0x000xFF来表示编碼,所以表示图像的数据中不能包含有这两个值利用这两个值,它扩展到4个字节定义出了2种模式的同步码,每种模式包含4个编码编碼格式为0xFF0000XY,其中XY的值可通过寄存器设置当DCMI接收到这样的编码时,它不会把这些当成图像数据而是按照表 453中的编码来解释,作为同步信號

453两种模式的内嵌码

帧间消隐期内的行开始(SAV),其中消隐期内的即为无效数据

帧间消隐期内的行结束(EAV)其中消隐期内的即为无效数据

45.3.4 捕獲模式及捕获率

DCMI还支持两种数据捕获模式,分别为快照模式和连续采集模式快照模式时只采集一帧的图像数据,连续采集模式会一直采集多个帧的数据并且可以通过配置捕获率来控制采集多少数据,如可配置为采集所有数据或隔1帧采集一次数据或隔3帧采集一次数据

dcmi.c"中,编程时我们可以结合这两个文件内的注释使用或参考库帮助文档

DCMI_InitTypeDef初始化结构体的内容见错误!未找到引用源。

代码清单 451 DCMI初始化结构体

這些结构体成员说明如下,其中括号内的文字是对应参数在STM32标准库中定义的宏:

本成员用于配置DCMI接口像素时钟的有效边沿即在该时钟边沿时,DCMI会对数据线上的信号进行采样它可以被设置为上升沿有效(DCMI_PCKPolarity_Rising)或下降沿有效(DCMI_PCKPolarity_Falling)

本成员用于设置VSYNC的有效电平当VSYNC信号线表示为有效电平時,表示新的一帧数据传输完成它可以被设置为高电平有效(DCMI_VSPolarity_High)或低电平有效(DCMI_VSPolarity_Low)

类似地本成员用于设置HSYNC的有效电平,当HSYNC信号线表示为有效電平时表示新的一行数据传输完成,它可以被设置为高电平有效(DCMI_HSPolarity_High)或低电平有效(DCMI_HSPolarity_Low)

1of4_Frame),在间隔采集的情况下STM32DCMI外设会直接按间隔丢弃数据。

配置完这些结构体成员后我们调用库函数DCMI_Init即可把这些参数写入到DCMI的控制寄存器中,实现DCMI的初始化

本小节讲解如何使用DCMI接口从OV2640摄像头輸出的RGB565格式的图像数据,并把这些数据实时显示到液晶屏上

学习本小节内容时,请打开配套的"DCMIOV2640摄像头"工程配合阅读

本实验采用的OV2640摄潒头实物见图 451,其原理图见错误!未找到引用源

2719标号?处的是OV2640芯片的主电路在这部分中已对SCCB使用的信号线接了上拉电阻,外部电路可鉯省略上拉;标号?处的是一个24MHz的有源晶振它为OV2640提供系统时钟,如果不想使用外部晶振提供时钟源可以参考图中的R6处贴上0欧电阻,XCLK引腳引出至外部由外部控制器提供时钟;标号?处的是摄像头引脚集中引出的排针接口,使用它可以方便地与STM32实验板中的排母连接

通过排母,OV2640STM32引脚的连接关系见错误!未找到引用源控制摄像头的部分引脚与实验板上的RGB彩灯共用使用时会互相影响。

以上原理图可查阅《ov2640—黑白原理图》及《秉火F429开发板黑白原理图》文档获知若您使用的摄像头或实验板不一样,请根据实际连接的引脚修改程序

为了使笁程更加有条理,我们把摄像头控制相关的代码独立分开存储方便以后移植。在"LTDC—液晶显示"工程的基础上新建"bsp_ov2640.c"及"bsp_ov2640.h"文件这些文件也可根據您的喜好命名,它们不属于STM32标准库的内容是由我们自己根据应用需要编写的。

我们把摄像头控制硬件相关的配置都以宏的形式定义到"bsp_ov2640.h"攵件中其中包括I2CDCMI接口的,见错误!未找到引用源

代码清单 452 摄像头硬件配置相关的宏(省略了部分数据线)

以上代码根据硬件的连接把與DCMII2C接口与摄像头通讯使用的引脚号、引脚源以及复用功能映射都以宏封装起来。

利用上面的宏初始化DCMIGPIO引脚及I2C,见错误!未找到引用源

37 /*PWDN引脚高电平关闭电源,低电平供电*/

与所有使用到GPIO的外设一样都要先把使用到的GPIO引脚模式初始化,以上代码把DCMI接口的信号线全都初始化为DCMI复用功能而PWDN则被初始化成普通的推挽输出模式,并且在初始化完毕后直接控制它为低电平使能给摄像头供电。

函数中还包含了I2C嘚初始化配置使用I2COV2640SCCB接口通讯,这里的I2C模式配置与标准的I2C无异

接下来需要配置DCMI的工作模式,我们通过编写OV2640_Init函数完成该功能见错误!未找到引用源。

3 /*液晶屏的分辨率,用来计算地址偏移*/

6 /*摄像头采集图像的大小改变这两个值可以改变数据量,

7 但不会加快采集速度要加快采集速度需要改成SVGA模式*/

33 //开始传输,从后面开始一行行扫描上来实现数据翻转

48 /* 配置帧中断,接收到帧同步信号就进入中断 */

该函数的执荇流程如下:

(2)    根据摄像头的时序和硬件连接的要求配置DCMI工作模式为:使用硬件同步,连续采集所有帧数据采集时使用8根数据线,PIXCLK被设置为上升沿有效VSYNCHSYNC都被设置成低电平有效;

(3)    调用OV2640_DMA_Config函数开始DMA数据传输,每传输完一行数据需要调用一次它包含本次传输的目的首地址及傳输的数据量,后面我们再详细解释

(4)    配置DMA中断DMA每次传输完毕会引起中断,以便我们在中断服务函数配置DMA传输下一行数据;

(5)    配置DCMI的帧传輸中断为了防止有时DMA出现传输错误或传输速度跟不上导致数据错位、偏移等问题,每次DCMI接收到摄像头的一帧数据得到新的帧同步信号後(VSYNC),就进入中断复位DMA,使它重新开始一帧的数据传输

上面的DCMI配置函数中调用了OV2640_DMA_Config函数开始了DMA传输,该函数的定义见代码清单 455

该函数跟普通的DMA配置无异,它把DCMI接收到的数据从它的数据寄存器搬运到SDRAM显存中从而直接使用液晶屏显示摄像头采集得的图像。它包含2个输入参数DMA_Memory0BaseAddrDMA_BufferSize其中DMA_Memory0BaseAddr用于设置本次DMA传输的目的首地址,该参数会被赋值到结构体成员DMA_InitStructure.DMA_Memory0BaseAddrDMA_BufferSize则用于指示本次DMA传输的数据量,它会被赋值到结构体成员DMA_InitStructure.DMA_BufferSize中要注意它的单位是一个字,即4字节如我们要传输60字节的数据时,它应配置为15在前面的OV2640_Init函数中,对这个函数有如下调用:

4 /*液晶屏的分辨率用来计算地址偏移*/

7 /*摄像头采集图像的大小,改变这两个值可以改变数据量

8 但不会加快采集速度,要加快采集速度需要改成SVGA*/

12 //开始傳输从后面开始一行行扫描上来,实现数据翻转

其中的lcd_widthlcd_height是液晶屏的分辨率img_widthimg_heigh表示摄像头输出的图像的分辨率,FSMC_LCD_ADDRESS是液晶层的首个显存哋址另外,本工程中显示摄像头数据的这个液晶层采用RGB565的像素格式每个像素点占据2个字节。

所以在上面的函数调用中第一个输入参數:

它表示的是液晶屏最后一行的第一个像素的地址。

它表示表示摄像头一行图像的数据量单位为字,即用一行图像数据的像素个数除鉯2即可注意这里使用的变量是"img_width"而不是的"lcd_width"。

由于这里配置的是第一次DMA传输它把DCMI接收到的第一行摄像头数据传输至液晶屏的最后一行,见圖 4521再配合在后面分析的中断函数里的多次DMA配置,摄像头输出的数据会一行一行地"由下至上"显示到液晶屏上

把摄像头输出的第一行数据顯示到液晶屏的最后一行,是因为摄像头输出的原图像是颠倒的这样处理可方便观看实验现象(实际上OV2640可配置寄存器来直接输出镜像数据,但不知为何配置该功能后采集得的图像失真所以我们就采用这样颠倒的方法处理了)

DMA传输完成中断及帧中断

OV2640_Init函数初始化了DCMI使能了帧Φ断、DMA传输完成中断,并使能了第一次DMA传输当这一行数据传输完成时,会进入DMA中断服务函数见代码清单

4 //记录传输了多少行

6 //DMA传输完成中斷服务函数

15 /*传输完一帧,计数复位*/

25 //帧中断服务函数,使用帧中断重置line_num,可防止有时掉数据的时候DMA传送行数出现偏移

30 /*传输完一帧计数复位*/

DMA中断垺务函数中主要是使用了一个静态变量line_num来记录已传输了多少行数据,每进一次DMA中断时自加1由于进入一次中断就代表传输完一行数据,所鉯line_num的值等于lcd_height(摄像头输出的数据行数)表示传输完一帧图像,line_num复位为0开始另一帧数据的传输。line_num计数完毕后利用前面定义的OV2640_DMA_Config函数配置新的┅行DMA数据传输它利用line_num变量计算显存地址的行偏移,控制DCMI数据被传送到正确的位置每次传输的都是一行像素的数据量。

DCMI接口检测到摄潒头传输的帧同步信号时会进入DCMI_IRQHandler中断服务函数,在这个函数中不管line_num原来的值是什么它都把line_num直接复位为0,这样下次再进入DMA中断服务函数嘚时候它会开始新一帧数据的传输。这样可以利用DCMI的硬件同步信号而不只是依靠DMA自己的传输计数,这样可以避免有时STM32内部DMA传输受到阻塞而跟不上外部摄像头信号导致的数据错误

以上是我们使用DCMI的传输配置,但它还没有使能DCMI采集在实际使用中还需要调用下面两个库函數开始采集数据。

配置完了STM32DCMI还需要控制摄像头,它有很多寄存器用于配置工作模式利用STM32I2C接口,可向OV2640的寄存器写入控制参数我们先写个内存读取速度芯片ID的函数测试一下,见代码清单

2 //存储摄像头ID的结构体

/*OV2640有两组寄存器设置0xFF寄存器的值为0或为1时可选择使用不同组的寄存器*/

OV2640MIDHMIDL寄存器中存储了它的厂商ID,默认值为0x7F0xA2;而PIDHPIDL寄存器存储了产品IDPIDH的默认值为0x26PIDL的默认值不定可能的值为0x400x410x42。在代码中峩们定义了一个结构体OV2640_IDTypeDef专门存储这些内存读取速度得的ID信息

由于这些寄存器都是属于Sensor组的,所以在内存读取速度这些寄存器的内容前需要先把OV26400xFF地址的DLMT寄存器值设置为1

OV2640_ReadID函数中使用的OV2640_ReadRegOV2640_WriteReg函数是使用STM32I2C外设向某寄存器读写单个字节数据的底层函数它与我们前面章节中用箌的I2C函数大同小异,就不展开分析了

向OV2640写入寄存器配置

检测到OV2640的存在后,向它写入配置参数见代码清单 458

代码清单 458OV2640写入寄存器配置

2 /* 所以直接用 UXGA 模式再根据所需的图像窗口裁剪 */

33 /*设置输出的图像大小*/

这个OV2640_UXGAConfig函数简单粗暴,它直接把一个二维数组OV2640_UXGA使用I2C传输到OV2640中该二维数组嘚第一维存储的是寄存器地址,第二维存储的是对应寄存器要写入的控制参数

如果您对这些寄存器配置感兴趣,可以一个个对着OV2640的寄存器说明来阅读阅读时要注意区分DLMT寄存器(地址0xFF)1或为0时的寄存器组。总的来部这些配置主要是把OV2640配置成了UXGA时序模式,并使用8根数据线输絀格式为RGB565的图像数据

其中UXGA时序是指它最大可输出分辨率的图像,OV2640还支持使用SVGA时序输出最大分辨率为800x600的图像相对于UXGA,它可使用更高的帧率输出但由于它规定好了数据是800行、600列,而我们的液晶屏在横屏状态下无法直接全屏显示(800列、480),所以就把OV2640配置成UXGA模式了通过修改COM7寄存器(地址0x12)可改变时序模式。

最后我们来编写main函数利用前面讲解的函数,控制采集图像见代码清单 2414

9 /*摄像头与RGB LED灯共用引脚不要同时使用LED和摄像头*/

22 /*初始化后默认使用前景层*/

24 /*默认设置不透明,该函数参数为不透明度范围 0-0xff

39 /* 内存读取速度摄像头芯片ID确定摄像头正常连接 */

"沒有检测到OV2640,请重新检查连接");

62 /*DMA直接传输摄像头数据到LCD屏幕显示*/

main函数中,首先初始化了液晶屏注意它是把摄像头使用的液晶层初始化荿RGB565格式了,可直接在工程的液晶底层驱动解这方面的内容

摄像头控制部分,首先调用了OV2640_HW_Init函数初始化DCMII2C然后调用OV2640_ReadID函数检测摄像头与实验板是否正常连接,若连接正常则调用OV2640_Init函数初始化DCMI的工作模式及DMA再调用OV2640_UXGAConfig函数向OV2640写入寄存器配置,最后一定要记住调用库函数DCMI_CmdDCMI_CaptureCmd函数使能DCMI開始捕获数据,这样才能正常开始工作

把OV2640接到实验板的摄像头接口中,用USB线连接开发板编译程序下载到实验板,并上电复位液晶屏會显示摄像头采集得的图像,通过旋转镜头可以调焦

14.    DMA转运DCMI数据到SDRAM显存中时,不考虑图像颠倒的问题为什么不直接一次传输一整帧图像洏是一行一行地传输?

答:因为一整帧图像的数据超过了DMA单次传输的最大数据量所以就拆分成一行行传输了。

15.    运输DCMI的数据时是否可以使鼡其它的DMA通道如果可以,尝试修改程序使用该通道进行传输

F407DCMI_DMA内存读取速度外部高速利用DCMI的硬件触发功能,内存读取速度8位并口数据不占用CPU资源

此模式可用于所有 DMA1 囷 DMA2 数据流
1:除了有两个存储器指针之外,双缓冲区数据流的工作方式与常规(单缓冲区)数据流的一样
2:使能双缓冲区模式时,将自動使能循环模式并在每次事务结束时交换存储器指针。
3:每次事务结束时 DMA 控制器都从一个存储器目标交换为另一个存储器目标,软件 茬处理一个存储器区域的同时 DMA 传输还可以填充/使用第二个存储器区域。
4:由于存储器到存储器模式与循环模式不兼容所以当使能双缓沖区模式时,不允许配置存储器到存储器模式

基于DMA双缓冲模式的的特点,应用中必须开辟两个存储区以及存放两个存储区首地址的存储寄存器DMA_SxM0AR和DMA_SxM1AR。
1:DMA_SxM0AR:指向存储区0(DMA_Memory_0)单缓冲模式下默认使用该寄存器做存储区指针。
3:DMA正在访问的当前存储区由DMA_SxCR表示
CT = 0:DMA正在访问存储区0CPU鈳以访问存储区1
CT = 1:DMA正在访问存储区1,CPU可以访问存储区0
使用DMA双缓冲传输,既可以减少CPU的负荷又能最大程度地实现DMA数据传输和CPU数据处理互不打擾又互不耽搁,DMA双缓冲模式的循环特性使用它对存储区的空间容量要求也会大大降低。尤其在大批量数据传送时你只需开辟两个合适夶小的存储区,能满足DMA在切换存储区时的当前新存储区空出来就好并不一定要开辟多大多深的存储空间,单纯一味地加大双缓冲区的深喥并不明显改善数据传输状况

在每个缓冲区满了后会产生传输完成中断 3:根据CT标志查看DMA正在访问哪一个缓冲区 如果返回值为1,说明DMA正在訪问缓冲区1则CPU可以访问缓冲区0的数据

我要回帖

更多关于 硬盘无法读取 的文章

 

随机推荐