[022] [STM32] 使用DCMI(DVP)驱动OV2640

STM32
Contents
OV2640摄像头简介
OV2640引脚
及功能框图
SCCB时序
OV2640的寄存器
像素输出时序
STM32的DCMI外设
外部接口及时序
DCMI时钟
DCMI功能概述
数据格式说明
DCMI中断
STM32的DCMI编程
控制相关结构体
软件设计(使
用CH32验证)

1 OV2640摄像头简介

OV2640为CMOS类型数字图像传感器,支持输出最大为200万像素(1600*1200分辨率)的图像,支持使用VGA时序输出图像数据,输出图像的数据格式支持YUV(422/420)、YCbCr422、RGB565以及JPEG格式,若直接输出JPEG格式的图像时可大大减少数据量。

可进行图像补偿:支持伽玛曲线、白平衡、饱和度、色度等基础处理。

根据不同的分辨率配置,传感器输出图像数据的帧率从15-60帧可调,工作时功率在125mW-140mW之间。

1.1 OV2640引脚及功能框图

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

image-20220712103053232

图中非彩色部分是电源相关的引脚,彩色部分是主要的信号引脚

管脚名称 管脚类型 管脚描述
SIO_C 输入 SCCB总线的时钟线,可类比I2C的SCL
SIO_D I/O SCCB总线的数据线,可类比I2C的SDA
RESETB 输入 系统复位管脚,低电平有效
PWDN 输入 掉电/省电模式,高电平有效
HREF 输出 行同步信号
VSYNC 输出 帧同步信号
PCLK 输出 像素同步时钟输出信号
XCLK 输入 外部时钟输入端口,可接外部晶振
Y0…Y9 输出 像素数据输出端口

表中高亮引脚即为VGA时序输出引脚。

image-20220712104224661

▲ OV2640功能框图
  1. 控制寄存器
    控制寄存器配置摄像头的相关参数,如对比度、曝光参数等,通过SCCB(与I2C类似)外设的SIO_C和SIO_D引脚写入。

  2. 通信、控制信号及时钟
    其中PCLKHREFVSYNC分别是像素同步时钟、行同步信号以及帧同步信号。RESETB引脚为低电平时,用于复位整个传感器芯片,PWDN用于控制芯片进入低功耗模式。

XCLK是用于驱动整个传感器芯片的时钟信号,由外部时钟源(外接晶振或由外部控制器提供)输入到OV2640;而PCLK是OV2640输出数据时的同步信号,由OV2640输出。

  1. 感光矩阵

image-20220712113413141

感光矩阵用于将光信号转化为电信号,在2,010,624像素中, 有1,991,040 (1632x1220)是活跃的。 经过AMP(Analog Amplifier)模拟放大、(Gain Control)增益控制、10位A/D转换、通道平衡(Channel Balance)、黑电平1补偿(Black Level Compensation)处理,将信号存储成由像素点表示的数字图像。

  1. 数据输出信号
    包含了DSP处理单元,它会根据控制寄存器的配置做一些基本的图像处理运算,如色彩饱和度调整、边缘增强等。这部分还包含了图像格式转换单元及压缩单元,转换出的数据最终通过Y0-Y9引脚输出,一般使用8根据数据线传输,此时仅使用Y2-Y9引脚,OV2640的数据信号与外部器件的连接方式:

image-20220712135302263

1.2 SCCB时序

外部控制器对OV2640寄存器的配置参数通过SCCB总线传输配置,而SCCB总线时序与I2C基本一致,所以在STM32中可直接使用片上I2C外设与它通讯。(OV2640 device slave addresses are 0x60 for write and 0x61 for read.)

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

SCCB的起始信号、停止信号及数据有效性与I2C完全一样。

  • 起始信号:在SCL(图中为SIO_C)为电平时,SDA(图中为SIO_D)出现一个下降沿,则SCCB开始传输
  • 停止信号:在SCL为电平时,SDA出现一个上升沿,则SCCB停止传输。
  • 数据有效性:除了开始和停止状态,在数据传输过程中,当SCL为高电平时,必须保证SDA上的数据稳定,即当SCL为低电平时SDA电平变换才能变换,SDA的信号在SCL为高电平时被采集。

image-20220712141008394

▲ SCCB起始与停止信号

image-20220712141204967

▲ SCCB的数据有效性

1.2.2 SCCB数据读写过程

SCCB协议中定义的读写操作与I2C同样一致。

1.2.2.1 写数据

SCCB定义了两种写操作:

三步写操作

  • phase1:发送从设备的ID地址+W标志(相当于I2C的设备地址:7位设备地址+读写方向标志)

  • phase2:发送从设备目标寄存器的8位地址

  • phase3:发送要写入寄存器的8位数据

image-20220712141907051

图中的“X”数据位可写入1或0,对通讯无影响。

二步写操作

两步写相对于三步写操作,没有phase3,一般用来配合后面的读寄存器数据操作,它与读操作一起使用,实现I2C的复合过程。

image-20220712142056650

1.2.2.2 读数据

两步读操作,用于读取从设备目的寄存器中的数据。

  • phase1:发送从设备的设备ID+R标志(设备地址+读方向标志)和自由位

  • phase2:读取寄存器中的8位数据和写NA 位(非应答信号)

image-20220712142458312

由于两步读操作「没有确定目的寄存器的地址」,所以在读操作前,必须有一个两步写操作,以提供读操作中的寄存器地址。

1.3 OV2640的寄存器

查询ov2640datasheet.pdf进行了解,通过寄存器配置可控制输出图像的分辨率大小、图像格式、图像处理及图像方向等。

注意OV2640有两组寄存器,这两组寄存器有部分地址重合,通过设置地址为0xFFRA_DLMT寄存器可以切换寄存器组:

  • RA_DLMT = 0:通过SCCB发送的寄存器地址在DSP相关的寄存器组寻址
  • RA_DLMT = 1:通过SCCB发送的寄存器地址在Sensor相关的寄存器组寻址

image-20220712150951950

官方还提供了OV2640_Camera_app.pdf文档,它针对不同的配置需求,提供了配置范例:

image-20220909153017033

1.3.1 常用寄存器

  • 帧率配置(0xFF = 0)

    image-20220908163643622

  • PLCK分频值(0xFF = 0)

image-20220909154005900

  • 设置原始图像的大小(0xFF = 0)

image-20220909154223660

  • 设置显示图像的局部大小(非等比缩放,该寄存器会将写入的数值自动向下取整为4的整数倍)(0xFF = 0)

image-20220909154355701

  • 设置垂直窗口的start与end的最低2位(0xFF = 1)

image-20220909163157863

  • OV2640的制造商ID与产品ID(0xFF = 1)

image-20220909163719975

  • 设置图像分辨率模式(UXGA/CIF/SVGA),其中Bit1为测试用的彩色条纹图案(0xFF = 1)

image-20220909163836904

  • 设置垂直窗口的start与end的高8位(0xFF = 1)

image-20220909164524756

1.4 像素输出时序

单个像素大小取决于图像格式,如RGB565格式单个像素大小为2字节。

OV2640输出的每帧图像的数据默认从左到右,从上到下输出每个采集像素(可通过寄存器修改方向),如下图所示。与控制液晶屏输出图像数据类似。

image-20220712153342784

OV2640输出图像时则使用UXGA1600×1200@15fps, SVGA@30fps, 或CIF@60fps时序,通过COM7寄存器切换模式。

image-20220712155606775

自定义窗口像素范围:

  • UXGA:2 x 4 to 1632 x 1220
  • SVGA:OV2640固定为800 x 600
  • CIF:固定为408 x 304

视频格式尺寸详见「VGA、QVGA、CIF、SXGA等视频格式尺寸解释

它们的像素输出格式如下图所示:

image-20220712161927164

下面以UXGA为例进行分析:

数据在PCLK上升沿阶段维持稳定,并在1个像素同步时钟PCLK的驱动下发送[9:0]位数据信号。

当行同步信号HREF电平时,像素数据依次传输,每传完一行数据时,HREF输出一个电平跳变信号间隔;当帧同步信号VSYNC电平时,各行的像素数据依次开始传输,每传完一帧图像时,VSYNC会输出一个电平跳变信号。

image-20220712162813754

UXGA模式下的Frame/Pixel Rates:

image-20220909143046574

2 STM32的DCMI外设

STM32F4系列的控制器具有DCMI(Digital camera Interface)数字摄像头接口,它支持使用类似VGA时序获取图像数据流,支持原始的按行、帧格式来组织的图像数据,如YUV、RGB,也支持接收JPEG格式压缩的数据流。接收数据时,主要使用HSYNC及VSYNC信号来同步。

image-20220712172142799

▲ DCMI接口顶层框图

2.1 外部接口及时序

DCMI向外部引出的信号线,方向均为输入:

引脚名称 说明
DCMI_D[0:13] 数据线
DCMI_PIXCLK 像素同步时钟
DCMI_HSYNC 行同步信号(水平同步信号)
DCMI_VSYNC 帧(场)同步信号(垂直同步信号)

其中DCMI_D数据线的数量可选8、10、12或14位(通过DCMI_CR的EDM[1:0]控制]),其中10/12/14需扩展到16位进行存储。

以10位数据为例,此时DCMI接口将捕获输入至D[0…9]的10位数据,将其存至16位字的低10位,其余最高有效位清零(位11~15)。因此,此情况下每两个像素时钟周期会生成1个32位的字。

image-20220713095432923

一般采用某端口的编号连续的引脚读取数据。如传输8位数据时,采用PB8~PB15引脚读取,直接读取GPIOB端口IDR寄存器的高8位即可。

DCMI通讯时序示例:

image-20220712172935153

图中DCMI_PIXCLK的捕获沿为下降沿,DCMI_HSYNCDCMI_VSYNC的有效电平为1。(捕获沿、有效电平均可通过寄存器配置,HSYNC和VSYNC的有效电平指的是采集完一行/帧图像后的状态电平

2.2 DCMI时钟

STM32内部使用HCLK(168M)为DCMI外设提供时钟源,从DCMI引出DCMI_IT信号至中断控制器,并可通过DMA_REQ信号发送DMA请求。

DCMI从外部接收数据时,在HCLK的上升沿时对PIXCLK同步的信号进行采样,PIXCLK的最大周期必须大于2.5 个 HCLK 周期,即最高频率为HCLK的1/4(42M)。

2.3 DCMI功能概述

image-20220712173742728

▲ DCMI接口的内部结构

2.3.1 同步器

2.3.1.1 硬件同步模式

使用HSYNC和VSYNC作为同步信号的方式(OV2640即采用此同步方式),VSYNC用于指示一帧图像的起始, HSYNC被用作数据有效信号。其时序图如下图所示:

HSYNC与VSYNC的有效极性通过DCMI_CR的HSPOL位和VSPOL位配置。

image-20220713101452753

根据摄像头模块/模式的不同,可能在水平/垂直同步期间内发送数据,但此时由于系统会忽略HSYNC/VSYNC信号有效电平期间内接收的所有数据,HSYNC/VSYNC信号相当于消隐信号。

选择硬件同步模式并启用捕获DCMI_CR中的CAPTURE位置1)时,数据传输将与VSYNC信号的无效电平(从有效电平切换到无效电平,即开始下一帧时)同步,每一帧结束时都将激活VSIF(垂直同步中断标志)。

注意:对于压缩数据(如JPEG格式),DCMI仅支持硬件同步模式。

2.3.1.2 内嵌码同步模式

该同步模式一般在特定场合下使用。

使用数据流中嵌入的特定的32 位码来表示同步信息,并且需用0x000xFF来表示编码,所以要确保 0x00 和 0xFF 值仅用于同步(不用于数据中)。共有 4 种同步码类型,均采用 0xFF0000XY 格式(XY值可编程)。

摄像头2种模式下的同步码如下表所示:

模式2的内嵌码 模式1的内嵌码
帧开始**(FS)** 有效行开始(SAV)
帧结束**(FE)** 有效行结束(EAV)
行开始**(LS)** 帧间消隐期内的行开始(SAV),其中消隐期内的即为无效数据
行结束**(LS)** 帧间消隐期内的行结束(EAV),其中消隐期内的即为无效数据

FS=0xff意味着所有除此之外的同步码均视为有效的帧结束同步码。在此模式下,一旦使能DCMI,将在首次出现帧结束 (FE) 同步码并且后接帧开始(FS) 同步码之后开始捕获帧。

此外,还针对FS/E和LS/E同步码实现了非屏蔽位功能(通过DCMI_ESUR寄存器配置),这样可仅用同步码中未被屏蔽的位进行比较。因此,可以选择一个位用于同步码的比较,来检测FS/E和LS/E,同时可用多个同步码表示FS/E和LS/E,它们仅在未被屏蔽的位相同即可。

示例

FS = 0x2e,FSU(FS的非屏蔽码) = 0x30。则只需比较位4和位5即可。

image-20220713133444931

注意:只有8位并行数据接口宽度支持内嵌码同步码。

2.3.2 数据FIFO

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

DMCI向AHB总线读取数据时读指针自动递增,向FIFO写入数据时写指针自动递增

注意:此FIFO没有溢出保护,如果数据传输率超过了AHB接口能够承受的速率,FIFO中的数据就会被覆盖。当如同步信号出错或FIFO溢出时,FIFO将复位,DCMI接口将等待新的数据帧开始。

DCMI接口挂载在AHB总线上,在AHB总线中有一个DCMI接口的数据寄存器,当我们读取该寄存器时,它会从FIFO中获取数据,并且FIFO中的数据指针会自动进行偏移。

2.3.3 DMA接口

DCMI_CR寄存器中的CAPTURE位置1时,激活DMA接口。摄像头接口每次在其寄存器中收到一个完整的32位数据块时,都将触发一个DMA请求。

2.3.4 捕获模式

快照模式(单帧)

DCMI_CR 寄存器中的 CM =1。当DCMI_CR的CAPTURE位置 1 后,DCMI等待帧起始信号,然后对数据采样。采样完一帧数据后自动清除CAPTURE位,禁止再次采样。

image-20220713141607181

注意:若数据溢出,则此帧丢失且依然会清除CAPTURE位。

连续采集模式

DCMI_CR 寄存器中的 CM = 0。当DCMI_CR的CAPTURE位置 1 后,DCMI等待帧起始信号,然后对数据采样,采样过程一直持续至CAPTURE位被清零。CAPTURE 位清零后,采集过程将持续到当前帧结束。

image-20220713142057224

在连续采集模式下,通过DCMI_CR中的FCRC位可设置捕获率来控制采集的数据量,如下图所示:

image-20220713142225823

2.3.5 裁剪功能

DCMI_CR寄存器的CROP位置1后,即开启采集功能。可从采集的图像从选择一个矩形窗口来裁剪图像。(注意若窗口大小超出图片大小,则进捕获图片大小)。

通过DCMI_CSTRT的VSTHOFFCNT位可设置窗口起点(Y,X),DCMI_CSIZE的VLINECAPCNT位可设置水平垂直尺寸,如下图所示:

image-20220713144039508

注意CAPCNT值只能是4的倍数(两个最低有效位强制为0),才能通过DMA正确传输数据。

image-20220713144419002

如果在捕获DCMI_CWSIZE寄存器中指定行数完成之前,VSYNC信号已有效,那么捕获将停止,并且在中断使能时生成IT_FRAME中断。

2.4 数据格式说明

DMCI支持单色、RGB 和 YCbCr数据格式(最大输入大小为2048×2048像素),以及JPEG压缩格式(大小无限制)。

对于单色、RGB 和 YCbCr,帧缓冲区以光栅模式存储(即从顶部像素行到底部像素行,从像素行的左侧到右侧)。使用32位字。仅支持小端对齐格式。

image-20220713151429861

▲ 像素光栅扫描顺序

2.4.1 JPEG 格式

DCMI_CR的JPEG位置1时,用于JPEG2(Joint photographic experts group)图像数据传输。

JPEG图像不按行和帧存储,因此VSYNC信号用于启动捕获过程,而HSYNC则用作数据使能信号。行中包含的字节数可能不是4的倍数,因此处理此类情况时应十分谨慎,因为需要每次从捕获的数据形成一个完整的32位字时,才生成一个DMA请求。检测到帧结束并且尚未凑成32位字时,将使用“0”进行填充,并触发一个DMA请求

注意:裁剪功能和内嵌码同步不适用JPEG格式。

2.4.2 单色格式

每个像素 8 位,单色逐行视频格式的数据存储方式如下表所示:

image-20220713152143217

2.4.3 RGB格式

仅支持16BPP(每个像素16位):RGB565(每32位表示2个像素);不支持24BPP(托盘化格式)和灰度格式。

像素分量包括 R(红色)、G(绿色)和 B(蓝色),一帧数据中各个分量交替间隔存储(低/高16位字节中R、G、B从MSB->LSB依次存储)。以 RGB 逐行视频格式存储数据格式如下表所示:

image-20220713152529838

注意:若OV2640红色R与蓝色B错位,可通过0xda地址的bit0配置数据LSB先行还是MSB先行,同时0xc2地址的寄存器bit4会影响该的配置。

image-20220909153354724

image-20220909153504711

经实际测试,如下配置在UXGA模式下RGB颜色可正常显示:

0xFF, 0x00,	// 切换到DSP地址
0xc2, 0x0c,   //^ bit4配置为1时 swap RGB中的R与B
0xda, 0x09,   // BIT[3:2] = 10 - RGB565  BIT[0] = 1 LSB先行

2.4.4 YCbCr 格式

YCbCr 4:2:2。像素分量包括Y(亮度)、Cb(蓝色色度)和Cr(红色色度)。每个分量都采用8位进行编码。亮度和色度(交替)存储在一起,如下表所示。

image-20220713152830780

2.5 DCMI中断

image-20220713153346102

全局中断 (IT_DCMI) 是所有单个中断的逻辑或运算所得结果。

3 STM32的DCMI编程

3.1 控制相关结构体

typedef struct
{
    
    
  uint16_t DCMI_CaptureMode;      /*!< 捕获模式,可选连续模式或快照模式 */
  uint16_t DCMI_SynchroMode;      /*!< 同步模式,可选硬件同步模式或内嵌码模式 */
  uint16_t DCMI_PCKPolarity;      /*!<像素时钟PIXCLK的有效边沿 */
  uint16_t DCMI_VSPolarity;       /*!< VSYNC的有效电平 */
  uint16_t DCMI_HSPolarity;       /*!< HSYNC的有效电平 */
  uint16_t DCMI_CaptureRate;      /*!< 捕获频率,可选all或1/2或1/4 */
  uint16_t DCMI_ExtendedDataMode; /*!< 数据线宽度 可选8/10/12/14*/
} DCMI_InitTypeDef;

3.2 软件设计(使用CH32验证)

由于项目使用ch32v307芯片,因此基于此芯片完成本次实验,STM32配置流程类似。

使用DVP外设(即STM32的DCMI外设)采集摄像头数据,将DVP的FIFO数据缓存到内部RAM中,再使用DMA的M2M模式搬运到FSMC外设控制的内存中,最后让图像在屏幕上显示。

3.2.1 外设初始化

DVP外设与IIC外设GPIO初始化
使能并复位OV2640
初始化DMA与DVP外设
使用IIC接口配置OV2640为UXGA模式
设置FSMC屏幕开窗大小
使能DMA与DVP外设
int8_t OV2640_Init(uint16_t img_w, uint16_t img_h)
{
    
    
    uint16_t ov_pid, ov_mid;
    OV2640_IDTypeDef OV2640_Camera_ID;

    img_width = img_w;
    img_height = img_h;

    OV2640_GPIO_Init();
    OV2640_Reset();

    OV2640_ReadID(&OV2640_Camera_ID);
    ov_mid = OV2640_Camera_ID.MIDH << 8 | OV2640_Camera_ID.MIDL;
    ov_pid = OV2640_Camera_ID.PIDH << 8 | OV2640_Camera_ID.PIDL;

    DBG_RAW("MID: %x", ov_mid);
    DBG_RAW("PID: %x", ov_pid);

    if (ov_mid != OV2640_MID)		return -1;
    else if (ov_pid != OV2640_PID)	return -2;

    OV2640_DMA_Init((uint32_t)dvp_buf0, FSMC_LCD_DATA_ADDR, lcd.width);
    OV2640_DVP_Init((uint32_t*)dvp_buf0, (uint32_t*)dvp_buf1, RGB565_COL_NUM, RGB565_ROW_NUM);

    return 0;
}

理论配置:OV2640捕获沿PCLK上升沿采样,HSYNC低电平有效,VSYNC高电平有效;

实际配置:OV2640捕获沿PCLK上升沿采样,HSYNC高电平有效,VSYNC高电平有效。(可见理论与实际存在差异zz)
注:有效电平指的是采集完一行/帧图像后的状态电平

ch32v307的DMA与DVP外设关键信息如下:

「DMA外设(与STM32基本无异)」

  • DMA传输一次性最大数据量为65535,同时M2M不支持循环模式,且一但使能即开始后传输数据,因此数据传输完后需要手动加载DMA_CNTRx剩余传输数据数目寄存器的初始值,同时若DMA_PADDRx外设基址寄存器和DMA_MADDRx内存基址寄存器配置了地址增量模式,需要重新设置基址。

  • DMA通道关闭后,DMA_PADDRx/DMA_MADDRx/DMA_CNTRx/DMA_CFGRx寄存器仅当相应的DMA通道关闭下才可写入。

「DAP外设(即STM32的DCMI外设)」

  • 对于RGBYUV数据流,硬件在每次帧信号从无效电平变为有效电平时会复位选择BUF0开始,存满一行数据将会切换的BUF1,实现交替存储R16_DVP_COL_NUM表示一行数据的有效PCLK周期数,R16_DVP_ROW_NUM表示一帧图像数据内包含的行数;
  • 对于JPEG压缩数据,硬件会根据设置的DMA接收长度设置BUF0和BUF1的切换阈值。此模式下,R16_DVP_COL_NUM用于配置DMA长度R16_DVP_ROW_NUM寄存器不起作用。

CH32的DAP外设与STM32的DCMI外设差异较大,其使用双BUF的FIFO缓存数据。在RGB模式下每个BUF交替采集每行数据;同时CH32的DMA不支持直接将DVP外设的FIFO数据通过DMA传输到内存(P2M),因此只能使用RAM先缓存FIFO数据,再通过DMA的M2M模式传输。

3.2.2 DVP中断处理

volatile uint16_t dvp_buf0[OV2640_RGB565_WIDTH];
volatile uint16_t dvp_buf1[OV2640_RGB565_WIDTH]
volatile uint32_t frame_cnt = 0, addr_cnt = 0, href_cnt = 0;
void DVP_IRQHandler(void)
{
    
    

    if (DVP->IFR & RB_DVP_IF_ROW_DONE)         // 行中断
    {
    
    
        /* Write 0 clear 0 */
        DVP->IFR &= ~RB_DVP_IF_ROW_DONE;  //clear Interrupt

        if ((addr_cnt & 0x01) == 0)     //buf1 done
        {
    
    
            addr_cnt++;
            DMA_Transmit_Set((uint32_t)dvp_buf0, lcd.width);  //Send DVP data to LCD
        }
        else   //buf0 done
        {
    
    
            addr_cnt++;
            DMA_Transmit_Set((uint32_t)dvp_buf1, lcd.width);
        }

        href_cnt++;
    }

    if (DVP->IFR & RB_DVP_IF_FRM_DONE)
    {
    
    
        DVP->IFR &= ~RB_DVP_IF_FRM_DONE;  //clear Interrupt
        addr_cnt = 0;
        href_cnt = 0;
    }

    if (DVP->IFR & RB_DVP_IF_STR_FRM)       // 帧起始中断
    {
    
    
        DVP->IFR &= ~RB_DVP_IF_STR_FRM;
        // 每帧图像采集完需要重新设置屏幕开窗大小, 否则会有图像分割现象
        LCD_OpenWindow((lcd.width - img_width) / 2, (lcd.height - img_height) / 2, img_width, img_height);
        frame_cnt++;
    }

    if (DVP->IFR & RB_DVP_IF_STP_FRM)       // 帧结束中断
    {
    
    
        DVP->IFR &= ~RB_DVP_IF_STP_FRM;
    }

    if (DVP->IFR & RB_DVP_IF_FIFO_OV)
    {
    
    
        DVP->IFR &= ~RB_DVP_IF_FIFO_OV;
        LOG_RAW("Dvp FIFO overflow!\n");
    }
}

在每行数据采集完后会触发行中断,在行中断里使用DMA_Transmit_Set函数切换相应的buf地址为DMA源寄存器地址,并重新设置传输的数据量:

void DMA_Transmit_Set(uint32_t source_addr, uint16_t size)
{
    
    
    DMA_Cmd(DMA2_Channel5, DISABLE);
    DMA2_Channel5->CNTR = size;
    DMA2_Channel5->PADDR = source_addr;
    DMA_Cmd(DMA2_Channel5, ENABLE);
}

为了防止有时DMA 出现传输错误或传输速度跟不上导致数据错位、偏移等问题,需要在帧中断里使用LCD_OpenWindow函数重新设置LCD显示窗口,可使它重新开始一帧的数据传输。

frame_cnt记录采集的图像帧数,可以用于计算FPS:

uint16_t fps_cnt = 0;
void TIM1_UP_IRQHandler(void)	// 5ms周期
{
    
    
    if(TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
    {
    
    
        TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
        if (++fps_cnt >= 1000){
    
    
            DBG_RAW("FPS:%.1f/s", (float)frame_cnt / 5.0);
            fps_cnt = 0;
            frame_cnt = 0;
        }
    }
}

image-20220909173009462

▲ 摄像头实验现象

END


  1. 指在经过一定校准的显示装置上,没有一行光亮输出的视频信号电平。 定义图像数据为0时对应的信号电平,调节黑电平不影响信号的放大倍数,而仅仅是对信号进行上下平移。 ↩︎

  2. 有损压缩,但损失的部分是人视觉不易察觉的部分,利用人眼对计算机色彩中高频信息部分不敏感的特点。去除视觉上多余信息(空间冗余度),去除数据本身的多余信息(结构冗余度)。 ↩︎

猜你喜欢

转载自blog.csdn.net/kouxi1/article/details/126787264
022