STM32F429之DCMI 数字相机接口

article/2025/9/20 15:28:23

嵌入式系列文章
参考:《STM32F429_DM00031020_ENV19.pdf》
本文目的:翻译STM32F429的PRM,深入理解DCMI接口的工作原理,最后将DCMI工作原理转换成驱动代码。
DCMI:Digital camera interface,数字摄像头接口

15.1 介绍

数字摄像头接口是一种同步并行的接口,可以从外部8位、10位、12位或14位宽的CMOS摄像头模组获取高速数据流。支持不同的数据格式:YCbCr4:2:2/RGB565渐进式视频和压缩的数据(JPEG)。
这个接口用于黑白相机、X24和X5相机(24倍变焦和5倍变焦?),并且假设所有预处理(如调整大小)都在相机模块中执行。

15.2 DCMI主要功能

· 8-,10-,12-,或 14-位并行接口;
· 内嵌式或硬线式的行和帧同步;
· 连续或快照模式;
· 裁剪功能;
· 支持下面的数据格式:
– 8/10/12/14位渐进式视频:黑白单色或原始格式.raw原始格式.raw原始格式.raw
– YCbCr 4:2:2YCbCr 4:2:2YCbCr 4:2:2渐进式视频(渐进式progressive,翻译成“逐行扫描”更合适,与interlace隔行扫描相对应)
– RGB 565渐进式视频
– 压缩数据:JPEG

15.3 DCMI针脚

1.pic
全部是输入引脚。

15.4 DCMI时钟

DCMI时钟2个时钟域:像素时钟PIXCLK和模块时钟HCLK。在信号稳定后,跟随PIXCLK产生的信号在HCLK的上升沿被采样。HCLK域会产生一个使能信号,用于指示来自相机的数据已经稳定且能被采样。PIXCLK的最小周期必须大于2.5倍的HCLK的周期。
备注:
2.pic
根据STM32的时钟树,假设HCLK配置成180MHz,那么PIXCLK最大的频率不能超过180/2.5=72MHz,对某些相机接口来说,这个频率最大只能采集720p的图像。

15.5 DCMI功能概览

DCMI是一个同步并行接口,可以接收高速(最大可达54MByte/s)数据流。包括高达14根数据线(D13-D0)和一根像素时钟线。像素时钟线极性可编程,这样数据可以在像素时钟的上升沿或下降沿进行捕获。
数据被传送到一个32位的数据寄存器中(DCMI_DR),然后通过通用的DMA通道进行传输。图像缓存由DMA来管理,而不是DCMI接口来管理。
接收到的数据可以组织成行/帧(YUV/RGB/raw模式)或可以是JPEG图像序列。要使能JPEG图片接收,必须设置JPEG位(DCMI_CR寄存器的bit3)。
数据流可以使用HSYNC(水平同步)和VSYNC(垂直同步)这种硬线方式,也可以使用内嵌到数据流中的同步码的方式进行同步。
下图是DCMI模块框图:
3.pic
下图是DCMI模块顶层视图:
4.pic

15.5.1 DMA接口

当DCMI_CR寄存器中的CAPTURE位被设置时,DMA接口就会被激活。每次DCMI接收到32位的数据时就会产生一次DMA请求。

15.5.2 DCMI物理接口

接口包含11/13/15/17根输入线(分别对应8/10/12/14位宽),只支持从设备模式。
接口的位宽取决于DCMI_CR寄存器的EDM[1:0]位。如果位宽小于14,则没使用的数据引脚则不能被复用为DCMI接口。
5.pic

数据由PIXCLK进行同步,并且根据极性配置,在像素时钟的上升或下降沿进行改变。(备注:数据的改变由PIXCLK来驱动,DCMI内的数据采样是HCLK的上升沿)
HSYNC表示行数据的开始和结束;
VSYNC表示帧数据的开始和结束;
下图是DCMI 信号的时序图:
6.pic

1、图中捕获沿是PIXCLK的下降沿,HSYNC和VSYNC的激活状态是1。
1、HSYNC和VSYNC可以同时改变。
● 8位数据
当DCMI_CR中的EDM[1:0]配置为00,则接口从输入接口D[0:7]中捕获8位LSB数据,并把它们存储为8位数据,而D[13:8]就被忽略。这样获取32位的数据需要4个像素时钟周期。
最先捕获的数据放在32位数据的低地址处,而第4次捕获到的数据放在高地址处,如下图所示:
7.pic

● 10位数据
当DCMI_CR中的EDM[1:0]配置为01,则DCMI从输入引脚D[0…9]获取10位数据存入16位数据的低10位。剩下的高位(DCMI_CR的bit11~15)配置为0。这样32位数据需要2个像素时钟周期可填满。
存放方法同样是先来的数据存放在低地址处,如下图所示:
8.pic

12bit和14位同理。

15.5.3 同步

DCMI接口支持内嵌码或硬线(HSYNC和VSYNC)同步。在使用内嵌码同步时,数字摄像头模块必须保证0x00和0xFF只用于同步,而不是数据。内嵌码同步模式仅支持8位并行数据宽度(这样,DCMI_CR寄存器的EDM[1:0]位必须要清零)。
对于压缩的数据,DCMI只支持硬线同步模式。这样VSYNC作为图像的开始/结束,而HSYNC作为数据有效的信号。下图是JPEG的时序图:
9.pic

● 硬线同步模式
在硬线同步模式下,使用了两个同步信号(HSYNC和VSYNC)。
根据相机模组,数据会在水平/垂直同步期间传输。HSYNC/VSYNC 信号的作用类似于消隐信号,因为在 HSYNC/VSYNC 有效期间接收到的所有数据都将被忽略。(备注:HSYNC/VSYNC有效期间应该是指作为消隐信号时的有效期间)
为了正确地将图片传入DMA/RAM的缓存,数据需要在VSYNC信号的同步下进行传输。当使用硬线同步模式,且使能捕获(设置DCMI_CR的CAPTURE位),则数据传输由VSYNC的非激活状态(下一帧的开始)进行同步。
传输可以连续地,通过使用DMA将连续的帧传输到连续的缓存区或相同/循环的缓存区中。为了允许DMA管理连续的帧,VSIF(垂直同步中断标志)会在每帧结尾进行激活。
● 内嵌码同步模式
在这种同步模式下,数据流使用嵌入在数据流中的 32 位代码进行同步。 这些代码使用数据中不再使用的 0x00/0xFF 值。 有 4 种类型的代码,均采用 0xFF0000XY 格式。 嵌入式同步代码仅在 8 位并行数据宽度捕获中受支持(在 DCMI_CR 寄存器中,EDM[1:0] 位应编程为“00”)。 对于其他数据宽度,此模式会产生不可预知的结果,不得使用。
注意:相机模块可以有 8 个这样的代码(在交错模式下)。 出于这个原因,相机接口不支持交错模式(否则每隔半帧就会被丢弃)。
· 模式2
四个嵌入代码表示以下事件
– 帧开始:Frame start (FS)
– 帧结束:Frame end (FE)
– 行开始:Line start (LS)
– 行结束:Line end (LE)
四个代码的 0xFF0000XY 格式的 XY 值是可编程的(参见第 15.8.7 节:DCMI 嵌入式同步代码寄存器(DCMI_ESCR))。
[备注]:DCMI_ESCR寄存器:
`DCMI_ESCR寄存器
10.pic

FEC:Frame end delimiter code,帧结束分隔代码
该字节指定帧结束分隔符的代码。 代码由 0xFF、0x00、0x00、FEC 形式的 4 个字节组成。如果 FEC 编程为 0xFF,则所有未使用的代码 (0xFF0000XY)解释为帧结束分隔符。
LEC: Line end delimiter code,行结束分隔代码
该字节指定行尾分隔符的代码。 该代码由 0xFF、0x00、0x00、LEC 形式的 4 个字节组成。
LSC: Line start delimiter code,行开始分隔代码
该字节指定行起始分隔符的代码。 该代码由 4 个字节组成,形式为 0xFF、0x00、0x00、LSC。
FSC: Frame start delimiter code,帧起始分隔代码
如果 FSC 编程为 0xFF,则不会检测到帧起始分隔符。 但是,FEC 代码之后第一次出现的 LSC 将被解释为帧分隔符的开始。
0xFF被编程为“帧结束” ,意味着所有未使用的代码都被解释为有效的帧结束代码。
在此模式下,一旦启用了相机接口,帧捕获在第一次出现帧结束 (FE) 代码后开始,然后是帧开始 (FS) 代码。
· 模式1
另一种编码是相机模式 1。此模式与 ITU656 兼容。 这些代码标志着另一组事件:
– SAV(活动行)- 行开始
– EAV(活动行)- 行结束
– SAV(消隐)- 帧间消隐期间的行尾
– EAV(消隐) - 帧间消隐期间的行尾
通过编写以下代码可以支持此模式:
• FS ≤ 0xFF
• FE ≤ 0xFF
• LS ≤ SAV (active)
• LE ≤ EAV (active)
还为帧/行开始和帧/行结束代码实现了嵌入的非屏蔽码。 使用它,可以仅将选定的未屏蔽位与编程代码进行比较。 因此,您可以在嵌入代码中选择一个位进行比较并检测帧/行开始或帧/行结束。 这意味着帧/行开始和帧/行结束可以有不同的代码,但未屏蔽的位保持相同。
例如:
FS = 0xA5
FS的非屏蔽码是0x10
在这种情况下,帧起始码嵌入在帧起始码的第 4 位。
备注:非屏蔽码位取0表示屏蔽,1表示未屏蔽,通过屏蔽码,可以选择某个位作为同步信号,而被屏蔽的位可以取其他的值。对STM32来说,只关注未屏蔽未,只要未屏蔽位出现同步信号就会进行同步。

15.5.4 捕获模式

DCMI接口支持2种捕获模式:快照模式(单帧)和连续抓取。
● 快照模式(单帧)
在这种模式下,可以捕获到一个单帧(DMCI_CR寄存器中的CM=1)。在DCMI_CR的CAPTURE位被置位,在采样数据之前,DCMI接口要等待检测到一个帧启动信号。在完成第一帧的数据接收后,DCMI会自动除能(CAPTURE位被清零)。如果使能了中断则此时会产生一个中断。
当发生超限事件(overrun),则帧被丢弃,并且CAPTURE位被清零。快照模式下的时序图如下图所示:
11.pic

这里HSYNC和VSYNC的激活状态都是1,这两个信号可以同时变更状态。
● 连续抓取模式
在这种模式下(DCMI_CR的CM位为0),一旦DCMI_CR中的CAPTURE位被设置,则抓取程序会在下一个VSYNC信号或内嵌码模式下的帧开始FS信号到来后启动。该进程会一直持续直到CAPTURE位被清零。 一旦CAPTURE位被清零,抓取进程会持续到当前帧结束。
12.pic

在连续抓取模式下,你可以配置DCMI_CR寄存器中的FCRC位来抓取所有图像、每两帧抓一帧,或每四帧抓一帧,来减少帧的捕获率。
注意:在硬线同步模式下(DCMI_CR的ESS=0),IT_VSYNC中断依然会在CAPTURE=0时产生,所以,为了减少帧率,IT_VSYNC中断可以用来累计两次捕获的帧数,并且和快照模式结合起来用。这在内嵌码模式下是不允许的。

15.5.5 裁剪功能

使用裁剪功能,DCMI接口可以在接收到的图片中选取一个矩形窗。起点(左上角)坐标和大小(水平维度是像素时钟个数,而垂直维度是行数)由两个32位的寄存器(DCMI_CWSTRT和DCMI_CWSIZE)来指定。窗口的大小水平维度是像素时钟的个数,垂直维度是行数。
13

这些寄存器指定了捕获窗口的起始坐标,一个是行数(在一帧中是从0开始),一个是像素时钟数(在一行中是从0开始),还指定了窗口的大小,即行数和像素时钟数。DCMI_CSIZE中的CAPCNT值只能是4的倍数,这样才能正确地使用DMA进行传传输。
如果VSYNC在DCMI_CSIZE寄存器中的行数到达之前被激活,则捕获停止且IT_FRAME中断产生。
14

15.5.6 JPEG格式

为了允许JPEG格式图像的接收,需要设置DCMI_CR寄存器中的JPEG位。JPEG图片不是以行和帧的格式存储,所以VSYNC作为捕获的起始信号,而HSYNC作为数据使能信号。一行的数据字节数不一定是4的倍数,所以你需要小心处理这种情况,因为一个DMA请求是每次完成32位数据传输才会产生的。如果检测到了帧结束,但是32位数据没完全传输完,则剩下的数据会是0,而且产生DMA请求。
裁剪功能和内嵌码同步码不支持在JPEG格式下使用。

15.5.7 FIFO

一个四字的FIFO用来管理传输到AHB总线上的数据率。DCMI接口具备一个简单的FIFO控制器,每次从AHB接口读的时候增加读指针,每次往FIFO中写数据的时候增加写指针。这里没有过载保护以防止数据被写覆盖,如果AHB接口不支持该数据传输率的话。
一旦产生过载或同步信号的错误,则FIFO会被复位,并且DCMI等待新的帧启动信号。

15.6 数据格式描述

15.6.1 数据格式

支持三种类型的数据:
● 8位的渐进视频;
● YCbCr 422
● RGB565
压缩数据:JPEG
对黑白数据、YUV、RGB数据来说,最大输入尺寸是2048*2048。JPEG格式下没限制。
对于单色、RGB 和 YCbCr,帧缓冲区以光栅模式存储。使用32bit的数据宽度。只支持小端模式。下图是像素光栅扫描顺序。
15

15.6.2 单色格式

特点:
● 光栅格式
● 每个像素8位
下图展示了这种数据的存储方式:
16

15.6.3 RGB格式

特点:
● 光栅格式
● RGB
● 交错的:一个缓存中RGB交错,BRGBRGBRG等
● 针对显示输出进行了优化
RGB 平面格式与标准 OS 帧缓冲区显示格式兼容。只支持16BPP(bits per pixel),每32位数据2个像素。24BPP和灰度格式不支持。像素以光栅扫描顺序存储,即像素行从上到下,像素行内从左到右。 像素分量是 R(红色)、G(绿色)和 B(蓝色)。 所有组件都具有相同的空间分辨率(4:4:4 格式)。 一帧存储在一个单独的部分中,组件以像素为基础交错。下图是RGB565的存储格式:
17

15.6.4 YCbCr格式

特点:
● 光栅格式
● YCbCr 422
● 交错:一个缓存中,Y,Cb和Cr交错。
像素分量是 Y(亮度或“亮度”)、Cb 和 Cr(色度或“色度”蓝色和红色)。 每个分量都以 8 位编码。 亮度和色度存储在一起(交错),如下图 所示。
18

15.7 DCMI中断

产生五个中断。所有中断都可以被软件屏蔽。全局中断(IT_DCMI)是所有单个中断的逻辑或。下图是所有中断的列表。
19

15.8 寄存器描述

【未完待续】


http://chatgpt.dhexx.cn/article/qMBh8ALU.shtml

相关文章

DCMI接口

目录 DCMI数字摄像头接口 DCMI引脚 摄像头引脚 操作过程与通信方式 硬件连接图 写操作 读操作 图像输出 数据格式 rawRGB YUV RGB JPEG 代码实现过程简述 学习过程的问题 YUV是亮度和色度的格式,为什么UV中取Cb蓝和Cr红作为色度? 提问MIPI、DVP、DCMI是什…

stm32f4的数字摄像头接口(DCMI)使用

DCMI简介 STM32F4的DCMI接口包括如下信号 1,数据据输入(D[0:13]),接摄像头的数据输出。 2,水平同步(行同步)输入(HSYNC),接摄像头的HSYNC/HREF信号&#xff…

Java开发技术

1、基础技术 数据结构与算法 逻辑结构:数据对象中的数据元素之间的逻辑关系 1.集合结构:集合结构中的数据元素除了同属一个集合外,没有其他关系。 2.线性结构:线性结构中的数据元素之间是一对一的关系。 3.树形结构:树…

JAVA 中的代码生成包 CGLIB (Code Generation Library)

JAVA 中的代码生成包 CGLIB (Code Generation Library) CGLIB 是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为 JDK 的动态代理提供了很好的补充。通常可以使用Java的动态代理创建代理,但当要代…

Java开发实战讲解!java开发CPU最低要求

前言 本人是底层 211 本科,刚毕业,⽆科研经历,但是有些项⽬经历。 在国内监控行业某头部企业做过一段时间的实习。 想着投下字节,可以积累⼀下⾯试经验和为金九银十面招做准备。投了简历之后,过了一段时 间,HR 就打电话跟我约时间, 说明一下,我投的是北京 office。…

Java面试题技术类一

前端技术导航大全 1、面向对象编程的三大特性是什么? 2、String 和StringBuffer的区别 3、说出ArrayList,Vector, LinkedList的存储性能和特性 4、Collection 和 Collections的区别 5、HashMap和Hashtable的区别 6、final, finally, finalize的区别 7、Overload和Overri…

Java专项练习(三)

JAVA选择题 401、下列类定义代码,当用来声明对象car,并用Car carnew Car();实例化后,可以通过car对象直接赋值的字段是()402、以下哪个不是Collection的子接口?403、下列说法正确的是( )404、下面的程序将来…

Java学习汇总

6/28日已更新,错误已修改~~~有错误的地方,欢迎大家留言! 目录 一、Java基础篇 1.接口和抽象类的区别 2.重载和重写的区别 3.和equals的区别 4.异常处理机制 5.HashMap原理 6.想要线程安全的HashMap怎么办? 7.ConcurrentHa…

java面经整理

面试问题 一、Java基础1.jdk1.7到jdk1.8HashMap发生了什么变化(底层)?2.jdk1.7到jdk1.8虚拟机发生了什么变化3.String、StringBuilder、StringBuffer4.ArrayList和LinkedList有什么区别?5.ConcurrentHashMap的扩容机制6.接口和抽象…

获得阿里Java开发P7岗“农村穷苦”小伙就得安于现状?

前言 相信大家看到这个标题其实就已经可以联想到我大概是个什么样的情况了,很多人都在生活中或者是网络上甚至是家庭中都大致听过这样的话,“你这样的出生,达到现在这样的生活已经很不错了,还是别为了不切实际的梦想去冒险了&…

Java基础 常见数据结构与算法 项目总结

Java基础 1 Java基础必知必会 1.1 Java语言有哪些特点? 面向对象(封装,继承,多态);平台无关性,平台无关性的具体表现在于,Java 是“一次编写,到处运行(Wri…

Java面试知识点概览(持续更新)

Java 基础 说说自定义注解的场景及实现 利用自定义注解,结合SpringAOP可以完成权限控制、日志记录、统一异常处理、数字签名、数据加解密等功能。 实现场景(API接口数据加解密) 1)自定义一个注解,在需要加解密的方法上添加该注…

java开发工程师面试总结

面试中常被问到的问题 介绍jvmjvm内存模型程序计数器虚拟机栈本地方法栈方法区堆 垃圾回收判断对象是否存活引用计数算法可达性分析算法 垃圾收集算法复制算法标记清除算法,标记整理算法 垃圾收集器新生代收集器SerialParNewParallel Scavenge 老年代收集器Serial O…

Java面试经验总结

目录 Java面试知识点基础常识前端基础知识Java基础知识1、**并行与并发**2、**线程与进程**3、**HashMap和HashTable区别**4、**new对象创建过程原理(在JVM),从执行的角度(其他角度待续)**4、**Volatile和Synchronized**5、**线程创建的几种方法**6、**垃…

java怎么写api接口,绝对干货

正文 下文中截图来源于朋友一个pdf版本的面经,把所以知识点的答案整理了下来,耗费他至少1个月时间,在本文最后部分把这个pdf分享给大家,觉得有用的麻烦点赞关注走一波,谢谢!!!面经中有他的知识点的答案,如下图示例,非常详细(文末有领取方式)!!! 1.数据结构与算…

Java开发校招面经

面试 当前面经欠缺:docker,k8s容器,spark,flink,hbase,hive,java网络编程(netty) 一,JAVA 重写和重载 重写:方法签名要完全相同(方…

数据结构:链表逆序输出

数据结构&#xff08;一&#xff09;&#xff1a;链表逆序输出 题目描述&#xff1a;创建一个链表&#xff0c;并将链表逆序输出&#xff0c;链表中以输入0作为结束 关键代码详解&#xff1a; 附&#xff1a;全部代码 #include<stdio.h> #include<stdlib.h> #…

链表逆序 java_链表逆序(JAVA实现)

题目:将一个有链表头的单向单链表逆序 分析: 链表为空或只有一个元素直接返回; 设置两个前后相邻的指针p,q,使得p指向的节点为q指向的节点的后继; 重复步骤2,直到q为空; 调整链表头和链表尾; 图解: 以链表A->B->C->D为例,逆序此链表。 0.初始状态 …

2-6 链表逆序及其C++实现

更多系列博文请点击&#xff1a;0-数据结构与算法链接目录 2-6 链表逆序 我只介绍两种常用方法吧&#xff0c;非递归方法 和 递归 方法 我觉得够用就行 1、非递归方法&#xff1a; 将第二个元素后面的元素依次插入到头结点后面&#xff0c; 最后再把原始第一个元素放到原…

c语言 数据结构 双向循环链表逆序

双链循环链表排序&#xff1a; 原链表&#xff1a; 1 2 3 4 5 6 7 8 9 10 逆序后&#xff1a;10 9 8 7 6 5 4 3 2 1 思路&#xff1a; 把最后一个节点删除&#xff0c; 插到head下面去 数据 1 不用管&#xff0c; 把后面的数据往 1 前面怼&#xff0c; 1自然就是最后一个了…