基于STM32F429的DCMI实现OV7725-NF无缓存摄像头的图像采集HAL库

article/2025/9/20 15:12:32

基于STM32F429的OV7725-NF无缓存摄像头的DCMI图像采集 和LTDC显示

  • 0. 首先说明一下时钟配置
  • 1. DCMI配置
    • 1.1 首先点击DCMI进入配置页面后,要选择Mode
    • 1.2 然后要进行GPIO settings
    • 1.3 然后是Parameter settings参数设置
    • 1.4 DMA settings
    • 1.5 需要使用的HAL库函数
  • 3. OV7725配置寄存器
  • 4. LTDC显示器显示
    • 接口配置
    • 完成以上配置后,LTDC就可以工作了。当我们需要把OV7725采集的图像进行显示时,只要在DCMI的帧中断或垂直同步中断中,把帧图像缓存地址向LTDC的图层句柄的起始地址赋值,然后调用一次配置函数即可,这样每接收完一帧图像,即触发一次显示刷新。

STM32F429具备DCMI摄像头接口,可利用DMA功能实现快速的硬件级图像采集存储,大大降低了纯软件开发的难度。开发教程网络上一大堆,但本人一开始也是经历了九九八十一难,一直不出图像,过程中还是有不少坑需要自己填一下,以此记录。完整的案例代码见以下链接。
CAM2LCDonF429IGT6.rar

0. 首先说明一下时钟配置

在这里插入图片描述

1. DCMI配置

1.1 首先点击DCMI进入配置页面后,要选择Mode

不同的mode代表不同的数据格式。下图中,8bits Embedded Synchro是指码流中嵌入同步码元的编码形式,其他的External Synchro都是通过单独的硬线提供同步信号。8、10、12、14是指数据位宽,像OV7725是8位宽数据+硬线同步,所以应该选择“Slave 8 bits External Synchro”。
在这里插入图片描述

1.2 然后要进行GPIO settings

根据实际使用的电路连接选择对应的引脚,调整的时候要在“Pinout view”界面中进行修改。

1.3 然后是Parameter settings参数设置

一共就以下5个需要配置的:
在这里插入图片描述
前3个参数是和所接摄像头参数对应的,要保持一致,分别是指PCLK触发沿选择、垂直同步信号VSYNC极性、水平同步信号HREF极性,注意OV7725提供的水平同步信号是HREF而不是HSYNC。
从下图OV7725时序图可以看出,PCLK上升沿有效,所以选Active on Rising edge.
在这里插入图片描述
但是,从下图帧时序图中看到,当VSYNC低电平,且HREF、HSYNC高电平时,才传输有效数据,DCMI配置选项中的Active High是指高电平时进行同步,官方称为消隐信号,也就是低电平时进行传数。这个一定要选对,不然接收到的数据永远都是0x00。对应OV7725的正确选择应该是:V=Active high; H=Active low。
在这里插入图片描述

接下来是“Frequency of frame capture”,这个是指DCMI接收处理的帧频率,通俗点就是说摄像头在一直发送图像数据,可能帧频率是60fps,但我们实际不需要这么高的帧率,可以通过这个选项选择“每处理1帧,丢弃3帧”、“每处理1帧,丢弃1帧”、“全部处理”。根据实际需要选择。
在这里插入图片描述
最后一个JPEG mode是指接收的数据流传输的是否为JPEG压缩数据。OV7725输出的VGA、QVGA、CIF格式都是非压缩数据,所以这里要选Disabled。

1.4 DMA settings

DMA mode有normal和circular两个选项,normal指执行一次DMA传输后停止,circular指连续循环执行数据搬移。
Data Width的选择应与实际一致,我们要将OV7725通过DCMI传入的外设数据搬移到内部存储器中,OV7725在传给DCMI时一次传8bits,但DCMI内部会将接收到的摄像头数据放到一个 32 位数据寄存器(DCMI_DR)中,然后通过通用DMA 进行传输。也就是说DCMI接收处理4次放满32bits数据后才会发起一次DMA传输。如果想使用DMA的FIFO,可以选择Use Fifo,并选定Threshold参数。

此处我们的图像编码格式是RGB565,按照上述说明,DCMI输出的32位数据应该是下图这种排列方式,当LTDC读取时也是这样的格式,通过实现发现是可以直接解码的,不需要进行位变换,但这部分内部原理还需要摸清楚,这里暂时不展开。
在这里插入图片描述

在这里插入图片描述

1.5 需要使用的HAL库函数

  • 启动DCMI:HAL_StatusTypeDef HAL_DCMI_Start_DMA (DCMI_HandleTypeDef * hdcmi, uint32_t DCMI_Mode, uint32_t pData, uint32_t Length)

  • 结束DCMI:HAL_StatusTypeDef HAL_DCMI_Stop(DCMI_HandleTypeDef * hdcmi)

  • 行接收完毕中断:void HAL_DCMI_LineEventCallback(DCMI_HandleTypeDef * hdcmi)

  • 帧接收完毕中断:void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef * hdcmi) 或
    void HAL_DCMI_VsyncEventCallback(DCMI_HandleTypeDef *hdcmi)

3. OV7725配置寄存器

OV7725按照定义的引脚连接好后就可以工作了,具体各个引脚功能如下表所示:

信号作用描述信号作用描述
VCC3.3模块供电脚,接 3.3V 电源[输入]OV_PCLK像素时钟输出[输出]
GND模块地线[输入]OV_VSYNC帧同步信号[输出]
OV_SCLSCCB 通信时钟信号[输入]OV_HREF行同步信号[输出]
OV_SDASCCB 通信数据信号[双向]OV_RESET复位信号,低电平复位[输入]
SGM_CTRL传感器时钟选择控制,高电平时使用模块内部晶振,低电平时使用XCLK_IN外部时钟信号[输入]OV_D[7:0]数据输出(8 位)[输出]
XCLK_IN外部时钟输入[输入]我是用的摄像头内置晶振频率为12MHz

但是他的参数设置可是多的一批,一共有0x00-0xac个8位寄存器,要想获得优秀画质,就得摸透这些寄存器。下面是官方给出的有用的寄存器配置方案,具体应用时可适当调整:
【注意】:硬件I2C有一些bug,不太好用,总是busy状态,推荐使用软件I2C进行配置通信。

	//输出窗口设置{COM7,      0x46}, //QVGA RGB565{HSTART,    0x3f}, //水平起始位置{HSIZE,     0x50}, //水平尺寸{VSTRT,     0x03}, //垂直起始位置{VSIZE,     0x78}, //垂直尺寸{HREF,      0x00},{HOutSize,  0x50}, //输出尺寸高,QVGA320填0x50; VGA填0xA0;{VOutSize,  0x78}, //输出尺寸宽,QVGA480填0x78; VGA填0xF0;//帧率//30 fps, PCLK = 12Mhz{CLKRC, 	0x01}, //CLKRC, F/2/2;F(internal clock) = F(input clock)/(Bit[5:0]+1)/2{COM4, 		0x41}, //COM4, PLL 4倍频{EXHCH, 	0x00},{EXHCL, 	0x00},{DM_LNL, 	0x00},  //DM_LNL, Dummy Row Low 8 Bits{DM_LNH, 	0x00}, //DM_LNH, Dummy Row High 8 Bits{ADVFL, 	0x00},{ADVFH, 	0x00},{COM5, 		0xf5},//夜晚模式下自动帧率控制开启//DSP control{TGT_B,     0x80},//{TGT_B,     0x7f},{FixGain,   0x00},//0x09{AWB_Ctrl0, 0xf0},//0xe0{DSP_Ctrl1, 0x1f},//0xff{DSP_Ctrl2, 0x00},{DSP_Ctrl3, 0x10},{DSP_Ctrl4, 0x00},//AGC AEC AWB{COM8,		0x8f},//0xf0{COM4,		0x41}, //Pll AEC CONFIG{COM6,		0x43},//0xc5{COM9,		0x4a},//0x11{BDBase,	0xfF},//0x7f{BDMStep,	0x01},//0x03{AEW,		0x40},{AEB,		0x30},{VPT,		0xa1},{EXHCL,		0x9e},{AWBCtrl3,  0xaa},{COM8,		0xff},//matrix shapness brightness contrast{EDGE1,		0x08},{DNSOff,	0x01},{EDGE2,		0x03},{EDGE3,		0x00},{MTX1,		0xb0},{MTX2,		0x9d},{MTX3,		0x13},{MTX4,		0x16},{MTX5,		0x7b},{MTX6,		0x91},{MTX_Ctrl,  0x1e},{BRIGHT,	0x08},{CNST,		0x20},{UVADJ0,	0x81},{SDE, 		0X06},{USAT,		0x65},{VSAT,		0x65},{HUECOS,	0X80},{HUESIN, 	0X80},//GAMMA config{GAM1,		0x0c},{GAM2,		0x16},{GAM3,		0x2a},{GAM4,		0x4e},{GAM5,		0x61},{GAM6,		0x6f},{GAM7,		0x7b},{GAM8,		0x86},{GAM9,		0x8e},{GAM10,		0x97},{GAM11,		0xa4},{GAM12,		0xaf},{GAM13,		0xc5},{GAM14,		0xd7},{GAM15,		0xe8},{SLOP,		0x20},{COM3,		0x40},//Horizontal mirror image;默认0x10,即改变YUV为UVY格式。但是摄像头不是芯片而是模组时,要将0X10中的1变成0,即设置YUV格式{COM10,		0x00}, //默认VSYNC 低电平有效。如果要兼容OV2640 DCMI的配置这里需要VSYNC 高电平有效{COM2,		0x01}, //设置输出驱动能力为2倍

4. LTDC显示器显示

LTDC是一种TFT显示屏接口,全称为LCD-TFT display controller,属于显示像素接口的一种,显示控制器提供了一个并行的数字RGB(红、绿、蓝)信号、以及水平/垂直同步信号、像素时钟作为输出,直接与各种LCD和TFT面板连接,且显示面板不需要缓存。一帧开始后,从左向右、从上向下一个像素一个像素输出RGB值,类似VGA逐行扫描刷新。
STM32的LTDC使用非常简单,完成参数配置后,只要定时向图层句柄设置图像数据地址即可,代码量非常少,基本可以看成STM32的显卡。

接口配置

  1. LTDC主要的接口IO有像素时钟LCD_CLK、水平同步HSYNC、垂直同步VSYNC、数据有效DE和3组RGB数据信号并行线,STM32F429最大支持RGB888显示输出,Display Type选项要根据所使用的显示屏支持的数据格式进行选择。
    在这里插入图片描述
  2. configuration中的parameter settings是最核心的配置,其中下图红框中的参数是由所使用的显示屏决定的,通常显示屏datasheet中都会给出,比如我使用的TM043NDH02给出的配置参数见第二张图,只要一一对应匹配即可。
    在这里插入图片描述

在这里插入图片描述
3. signal polarity有效电平配置
这部分有效电平的设置一定要和使用的显示屏相符合,下图为我是用的显示屏datasheet对IO电平的要求。
在这里插入图片描述

  1. layer settings主要是对图层参数进行设置。
    STM32F429共提供两个图层,每个图层的配置基本相似,下面是单个图层的配置说明。
    在这里插入图片描述

完成以上配置后,LTDC就可以工作了。当我们需要把OV7725采集的图像进行显示时,只要在DCMI的帧中断或垂直同步中断中,把帧图像缓存地址向LTDC的图层句柄的起始地址赋值,然后调用一次配置函数即可,这样每接收完一帧图像,即触发一次显示刷新。

void HAL_DCMI_VsyncEventCallback(DCMI_HandleTypeDef *hdcmi)
{pLayerCfg.FBStartAdress =  IMG_ADDR;if (HAL_LTDC_ConfigLayer(&hltdc, &pLayerCfg, 0) != HAL_OK){Error_Handler();}
}

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

相关文章

stm32-DCMI—OV2640摄像头

第45章 DCMI—OV2640摄像头 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege 本章参考资料:《STM32F4xx参考手册》、《STM32F4xx规格书》、库帮助文档《stm32f…

stm32f407的高速并口12位ad——dcmi方式

stm32f407的高速并口12位ad——dcmi方式 关于dcmi 我们可以利用这个摄像头接口,进行一个54M以下的并口ad的数据处理。 这个是dcmi的时序图,时钟使用mco1输出系统时钟四分频也就是42m,我的是ad9926,上升沿触发,那么ad…

STM32H7B0 HAL库中关于DMA的注意事项以及DCMI调试遇到的问题及解决方法

先总结总结问题 问题1:MX_DCMI_Init();放到 MX_DMA_Init();后 问题2:DMA缓存缓存要放到SRAM中__align(32) uint32_t buffer[65535] __attribute((at(0X24040000))); 问题3:IO复用问题,DCMI数据口可以复用到其他IO口&#xff0…

STM32——DCMI接口与OV2640原理与配置

一、OV2640简介 1、什么是OV2640? OV2640是OmniVision公司生产的一颗1/4寸的CMOS UXGA(1632*1232)图像传感器。该传感器体积小、工作电压低,提供单片UXGA摄像头和影像处理器的所有功能。通过SCCB总线控制,可以输出整…

DCMI接口之OV2640摄像头

一、OV2640简介 OV2640是OmniVision公司生产的一颗1/4寸的CMOS UXGA(1632 * 1232)图像传感器。该传感器体积小、工作电压低,提供单片UXGA摄像头和影像处理器的所有功能。通过SCCB 总线控制,可以输出整帧、子采样、缩放和取窗口等…

OV2640 DCMI

OV2640 简介: 1/4寸CMOSUXGA (1632 * 1232)图像传感器。体积小、工作电压低,提供单片UXGA摄像头和影像处理器的所有功能。通过SCCB总线控制,可以输出整帧、子采样、缩放和取窗口等方式的各种分辨率8/10位影像数据。(此处一般选8位&#xff0…

STM32F429之DCMI 数字相机接口

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

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…