026 - STM32学习笔记 - 液晶屏控制(三) - DMA2D快速绘制矩形、直线
026- STM32学习笔记 - 液晶屏控制(三) - DMA2D快速绘制矩形、直线等

上节直接操作LTDC在先视频上直接显示,我们直接操作显存地址空间中的内容,用来显示图形,但是相对来说,这种方法费时费力,这节使用DMA2D来快速绘制图形。首先看一下DMA2D的初始化结构体:
/** * @brief DMA2D初始化结构体 */
typedef struct
{uint32_t DMA2D_Mode; /* 配置DMA2D模式,可选模式有:DMA2D_M2M、DMA2D_M2M_PFC、DMA2D_M2M_BLEND、DMA2D_R2M */uint32_t DMA2D_CMode; /* 配置颜色模式,可选有:DMA2D_ARGB8888、DMA2D_RGB888、DMA2D_RGB565、DMA2D_ARGB1555、DMA2D_ARGB4444 */uint32_t DMA2D_OutputBlue; /* 配置输出图像的蓝色通道值ARGB8888(0x00 - 0xFF)、RGB888(0x00 - 0xFF)、RGB565(0x00 - 0x1F)、ARGB1555(0x00 - 0x1F)、ARGB4444(0x00 - 0x0F) */uint32_t DMA2D_OutputGreen; /* 配置输出图像的绿色通道值ARGB8888(0x00 - 0xFF)、RGB888(0x00 - 0xFF)、RGB565(0x00 - 0x2F)、ARGB1555(0x00 - 0x1F)、ARGB4444(0x00 - 0x0F)*/uint32_t DMA2D_OutputRed; /* 配置输出图像的红色通道值ARGB8888(0x00 - 0xFF)、RGB888(0x00 - 0xFF)、RGB565(0x00 - 0x1F)、ARGB1555(0x00 - 0x1F)、ARGB4444(0x00 - 0x0F) */uint32_t DMA2D_OutputAlpha; /* 配置输出图像的红色通道值ARGB8888(0x00 - 0xFF)、ARGB1555(0x00 - 0x01)、ARGB4444(0x00 - 0x0F) */uint32_t DMA2D_OutputMemoryAdd; /* 指定内存地址,地址范围应在0x00000000 - 0xFFFFFFFF */uint32_t DMA2D_OutputOffset; /* 指定偏移值,取值范围为0x0000 - 0x3FFF */uint32_t DMA2D_NumberOfLine; /* 配置传输区域行数,配置值为:0x0000 - 0xFFFF */ uint32_t DMA2D_PixelPerLine; /* 配置要传输的区域的每行像素数,配置值为:0x0000 - 0x3FFF */
} DMA2D_InitTypeDef;
DMA2D_Mode
用于配置DMA2D的工作模式,可以设置的值如下:
| 宏 | 说明 |
|---|---|
| DMA2D_M2M | 从存储器到存储器(仅限FG获取数据源) |
| DMA2D_M2M_PFC | 存储器到存储器并执行 PFC(仅限FG PFC激活时的FG获 取) |
| DMA2D_M2M_BLEND | 存储器到存储器并执行混合(执行PFC和混合时的FG和BG获取) |
| DMA2D_R2M | 寄存器到存储器(无FG和BG,仅输出阶段激活) |
以上这四种模式主要区分数据的来源、是否使能PFC以及是否使能混合器,使用DMA2D时,可以将数据从某个位置搬运到现存,源位置可以时DMA2D本身的寄存器,也可以是设置好的DMA2D前景地址、背景地址。如果是能了PFC,则存储器中的数据源会经过转换后在送到显存,如果使能混合器,DMA2D会把两个数据源中的数据混合后再送到显存。
若使用存储器到存储器模式,需要调用库函数DMA2D_FGConfig,使用初始化结构体DMA2D_FG_InitTypeDef配置数据源的格式、地址等参数。背景层使用函数DMA2D_BGConfig和结构体DMA2D_BG_InitTypeDef)
DMA2D_CMode
用于配置DMA2D的输出PFC颜色格式,也就是将要传输给显存的格式,可选的参数有:DMA2D_ARGB8888、DMA2D_RGB888、DMA2D_RGB565、DMA2D_ARGB1555、DMA2D_ARGB4444。
DMA2D_OutputBlue/DMA2D_OutputGreen/DMA2D_OutputRed/DMA2D_OutputAlpha
用于配置DMA2D的输出颜色值,如果DMA2D工作模式设置为寄存器到存储器模式,则此颜色值作为数据源,会被DA2D复制到显存空间,目标空间就会被填入这一种颜色,每个通道的参数取值范围,请参照结构体说明中的注释内容。。
DMA2D_OutputMemoryAdd
用于配置DMA2D的输出FIFO的地址,DMA2D的数据会被搬运到该空间,一般将此设置为传输显示位置的起始地址。
DMA2D_OutputOffset
用于配置行偏移,行偏移会被添加到各行的结尾,用于确定下一行的起始地址,如下,绿色表示要显示的像素列,黄色表示行偏移,,假如左边显示的是一条竖线,竖线的宽度为1像素,所以行偏移的值为7-1=6,右边的线宽为2像素,行偏移的值为7-2=5,这样可以总结
行偏移的值 = 行宽度 − 线宽 行偏移的值 = 行宽度 - 线宽 行偏移的值=行宽度−线宽

DMA2D_NumberOfLine
用于配置 DMA2D 一共要传输多少行数,如上图中,一共有8行数据。
DMA2D_PixelPerLine
用于配置每行有多少个像素点,如上图左侧表示每行有1个像素点,右侧表示每行有2个像素点。
上节的程序中,我们在显示屏初始化时编写了一个显存初始化的函数void VRAM_Init(void),之后在其内部使用for循环对第二层的显存空间进行覆盖填写我们需要的颜色,如果只是填充一种颜色倒还好,若整个屏幕需要用颜色复杂度较高的图像,就会比较耗费CPU资源,因此这里采用DMA2D来传输,无需耗费CPU资源。
这里我们可以使用DMA2D来快速绘制矩形、直线等,可以在上面的程序中修改得到需要的功能如下:
绘制矩形
/*** @brief DMA2D绘制矩形* @param None* @retval None*/
void DMA_Draw_Rect(void)
{/* 记得要开时钟!!!这里我在上节内容中已经在LCD_Layer_Init中开过DMA2D的时钟了,这里就不在开了 */DMA2D_InitTypeDef DMA2D_InitStruct;/* 传输模式设置位从寄存器到存储器 */DMA2D_InitStruct.DMA2D_Mode = DMA2D_R2M;/* 颜色模式取决于上面我们设置的LTDC第二层的颜色模式 */DMA2D_InitStruct.DMA2D_CMode = DMA2D_ARGB8888;/* 配置透明通道 */DMA2D_InitStruct.DMA2D_OutputAlpha = 0xff;/* 配置蓝色通道 */DMA2D_InitStruct.DMA2D_OutputBlue = 0xff;/* 配置绿色通道 */DMA2D_InitStruct.DMA2D_OutputGreen = 0x00;/* 配置红色通道 */DMA2D_InitStruct.DMA2D_OutputRed = 0xff;/* 配置传输到第二层的显存首地址,此处是将矩形向右偏移350px,向下偏移200px */DMA2D_InitStruct.DMA2D_OutputMemoryAdd = LCD_LAYER2_START_ADDR+LCD_WIDTH*200*4+350*4;/* 如果是整屏配置,这里无需偏移,偏移取决与行像素数 */DMA2D_InitStruct.DMA2D_OutputOffset = 800-100;/* 设置每行像素数,即矩形宽为100px */DMA2D_InitStruct.DMA2D_PixelPerLine = 100;/* 设置显示的行数,即矩形长为100px */DMA2D_InitStruct.DMA2D_NumberOfLine = 100;/* 初始化DMA2D */DMA2D_Init(&DMA2D_InitStruct);/* 启动DMA2D传输 */DMA2D_StartTransfer();/* 等待DMA2D传输完成 */while(DMA2D_GetFlagStatus(DMA2D_FLAG_TC)== RESET);
}

绘制横直线:
/*** @brief DMA2D绘制线宽为1px,线长为100px的横线* @param None* @retval None*/
void DMA_Draw_Horiz_Line(void)
{DMA2D_InitTypeDef DMA2D_InitStruct;/* 传输模式设置位从寄存器到存储器 */DMA2D_InitStruct.DMA2D_Mode = DMA2D_R2M;/* 颜色模式取决于上面我们设置的LTDC第二层的颜色模式 */DMA2D_InitStruct.DMA2D_CMode = DMA2D_ARGB8888;/* 配置透明通道 */DMA2D_InitStruct.DMA2D_OutputAlpha = 0xff;/* 配置蓝色通道 */DMA2D_InitStruct.DMA2D_OutputBlue = 0x00;/* 配置绿色通道 */DMA2D_InitStruct.DMA2D_OutputGreen = 0x00;/* 配置红色通道 */DMA2D_InitStruct.DMA2D_OutputRed = 0xff;/* 配置传输到第二层的显存首地址,此处是将矩形向右偏移250px,向下偏移200px */DMA2D_InitStruct.DMA2D_OutputMemoryAdd = LCD_LAYER2_START_ADDR+LCD_WIDTH*200*4+250*4;/* 如果是整屏配置,这里无需偏移,偏移取决与行像素数 */DMA2D_InitStruct.DMA2D_OutputOffset = 800-100;/* 设置每行像素数 */DMA2D_InitStruct.DMA2D_PixelPerLine = 100;/* 设置显示的行数 */DMA2D_InitStruct.DMA2D_NumberOfLine = 1;/* 初始化DMA2D */DMA2D_Init(&DMA2D_InitStruct);/* 启动DMA2D传输 */DMA2D_StartTransfer();/* 等待DMA2D传输完成 */while(DMA2D_GetFlagStatus(DMA2D_FLAG_TC)== RESET);
}
效果图:晚上拍的照,颜色显示不是很明显

绘制竖直线:
/*** @brief DMA2D绘制线宽为1px,线长为100px的竖线* @param None* @retval None*/
void DMA_Draw_Vertical_Line(void)
{DMA2D_InitTypeDef DMA2D_InitStruct;/* 传输模式设置位从寄存器到存储器 */DMA2D_InitStruct.DMA2D_Mode = DMA2D_R2M;/* 颜色模式取决于上面我们设置的LTDC第二层的颜色模式 */DMA2D_InitStruct.DMA2D_CMode = DMA2D_ARGB8888;/* 配置透明通道 */DMA2D_InitStruct.DMA2D_OutputAlpha = 0xff;/* 配置蓝色通道 */DMA2D_InitStruct.DMA2D_OutputBlue = 0x00;/* 配置绿色通道 */DMA2D_InitStruct.DMA2D_OutputGreen = 0x00;/* 配置红色通道 */DMA2D_InitStruct.DMA2D_OutputRed = 0xff;/* 配置传输到第二层的显存首地址,此处是将矩形向右偏移250px,向下偏移200px */DMA2D_InitStruct.DMA2D_OutputMemoryAdd = LCD_LAYER2_START_ADDR+LCD_WIDTH*200*4+250*4;/* 如果是整屏配置,这里无需偏移,偏移取决与行像素数 */DMA2D_InitStruct.DMA2D_OutputOffset = 800-1;/* 设置每行像素数 */DMA2D_InitStruct.DMA2D_PixelPerLine = 1;/* 设置显示的行数 */DMA2D_InitStruct.DMA2D_NumberOfLine = 100;/* 初始化DMA2D */DMA2D_Init(&DMA2D_InitStruct);/* 启动DMA2D传输 */DMA2D_StartTransfer();/* 等待DMA2D传输完成 */while(DMA2D_GetFlagStatus(DMA2D_FLAG_TC)== RESET);
}
效果图:晚上拍的照,颜色显示不是很明显

OK,本节内容就学习到这里,下一节继续学习关于LCD更深层次的内容。
相关文章:
026 - STM32学习笔记 - 液晶屏控制(三) - DMA2D快速绘制矩形、直线
026- STM32学习笔记 - 液晶屏控制(三) - DMA2D快速绘制矩形、直线等 上节直接操作LTDC在先视频上直接显示,我们直接操作显存地址空间中的内容,用来显示图形,但是相对来说,这种方法费时费力,这节…...
【牛客网】OR59 字符串中找出连续最长的数字串
题目 思路 创建两个字符串 temp 和 ret 创建指针i用来遍历字符串通过i遍历字符串,如果遇到数字则将这个数组加到字符串temp中 i,如果遇到字母,则判断temp字符串的长度和ret字符串的长度,如果temp<ret则说明这个字符串不是要的字符串,如果temp>ret则说明此时temp字符串是…...
云原生监控系统Prometheus:基于Prometheus构建智能化监控告警系统
目录 一、理论 1.Promethues简介 2.监控告警系统设计思路 3.Prometheus监控体系 4.Prometheus时间序列数据 5.Prometheus的生态组件 6.Prometheus工作原理 7.Prometheus监控内容 8.部署Prometheus 9.部署Exporters 10.部署Grafana进行展示 二、实验 1.部署Prometh…...
C++ 学习系列 -- std::list
一 std::list 介绍 list 是 c 中的序列式容器,其实现是双向链表,每个元素都有两个指针,分别指向前一个节点与后一个节点 链表与数组都是计算机常用的内存数据结构,与数组连续内存空间不一样的地方在于,链表的空间是不…...
YOLOv8血细胞检测(6):多维协作注意模块MCA | 原创独家创新首发
💡💡💡本文改进:多维协作注意模块MCA,效果秒杀ECA、SRM、CBAM,创新性十足,可直接作为创新点使用。 MCA | 亲测在血细胞检测项目中涨点,map@0.5 从原始0.895提升至0.910 收录专栏: 💡💡💡YOLO医学影像检测:http://t.csdnimg.cn/N4zBP ✨✨✨实战医学影…...
FFmpeg横竖版视频互换背景模糊一键生成
视频处理是现代多媒体应用中常见的需求。其中横竖版视频互换和背景模糊是视频编辑中常见的操作。FFmpeg是一个功能强大的工具,适用于这些任务。 本文将详细介绍如何使用FFmpeg进行横竖版视频互换和背景模糊。 文章目录 操作命令与命令说明横版转竖版竖版转横版背景模糊处理横…...
Java 华为真题-小朋友分班
需求: 题目描述 幼儿园两个班的小朋友在排队时混在了一起,每位小朋友都知道自己是否与前面一位小朋友同班,请你帮忙把同班的小朋友找出来小朋友的编号是整数,与前一位小朋友同班用Y表示,不同班用N表示学生序号范围(0&…...
机器学习必修课 - 编码分类变量 encoding categorical variables
1. 数据预处理和数据集分割 import pandas as pd from sklearn.model_selection import train_test_split导入所需的Python库 !git clone https://github.com/JeffereyWu/Housing-prices-data.git下载数据集 # Read the data X pd.read_csv(/content/Housing-prices-data/t…...
ClickHouse进阶(二十二):clickhouse管理与运维-服务监控
进入正文前,感谢宝子们订阅专题、点赞、评论、收藏!关注IT贫道,获取高质量博客内容! 🏡个人主页:IT贫道_大数据OLAP体系技术栈,Apache Doris,Kerberos安全认证-CSDN博客 📌订阅:拥抱独家专题,你的订阅将点燃我的创作热情! 👍点赞:赞同优秀创作,你的点赞是对我创…...
Hadoop使用hdfs指令查看hdfs目录的根目录显示被拒
背景 分布式部署hadoop,服务机只有namenode节点,主机包含其他所有节点 主机关机后,没有停止所有节点,导致服务机namenode继续保存 再次开启主机hadoop,使用hdfs查看hdfs根目录的时候显示访问被拒 解决方案 1.主机再次开启hadoop并继续执行关闭 2.服务器再次开启hadoop并继…...
[Mac] 安装paddle-pipelines出现 ERROR: Failed building wheel for lmdb
今天在mac换了新系统,然后重新安装paddle-piplines的时候出现了下面的问题: xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrunerror: comma…...
LED灯亮灭
.text .global _start _start: 设置GPIO寄存器的时钟使能 RCC_MP_AHB4ENSETR[4]->1 0x50000a28LDR R0,0x50000A28LDR R1,[R0] 从R0为起始地址的4个字节数据取出放入R1中ORR R1,R1,#(0x1<<4) 第四位设置为1STR R1,[R0] 写回LDR R0,0x5000…...
Acwing.143 最大异或对(trie树)
题目 在给定的N个整数A1,A2 . …Ax中选出两个进行xor(异或)运算,得到的结果最大是多少? 输入格式 第一行输入一个整数N。 第二行输入N个整数A1~AN。 输出格式 输出一个整数表示答案。 数据范围 1 ≤N ≤105,0≤A<231 输入样例: 3 1 2 3输出样…...
day10.8ubentu流水灯
流水灯 .text .global _start _start: 1.设置GPIOE寄存器的时钟使能 RCC_MP_AHB4ENSETR[4]->1 0x50000a28LDR R0,0X50000A28LDR R1,[R0] 从r0为起始地址的4字节数据取出放在R1ORR R1,R1,#(0x1<<4) 第4位设置为1STR R1,[R0] 写回2.设置PE10管脚为输出模式 G…...
transformer系列5---transformer显存占用分析
Transformer显存占用分析 1 影响因素概述2 前向计算临时Tensor显存占用2.1 self-attention显存占用2.2 MLP显存占用 3 梯度和优化器显存占用3.1 模型训练过程两者显存占用3.2 模型推理过程两者显存占用 1 影响因素概述 模型训练框架:例如pytorch框架的cuda context…...
Docker项目部署
目录 一、前端项目部署 1、上传文件 2、开启容器 3、测试 二、后端项目部署 1、打包java项目 2、将jar包和Dockerfile文件长传到Linux系统 3、构建镜像 4、开启容器 5、测试 三、DockerCompose快速部署 基本语法 一、前端项目部署 1、上传文件 里面包括页面和配置文…...
vue3实现文本超出鼠标移入的时候文本滚动
判断文本长度是否大于容器长度 鼠标移入的时候判断,此处使用了tailwindcss,注意一下要设置文本不换行。 <divref"functionsItems"mouseenter"enterFunctionsItem($event, index)"><img class"w-5 h-5" :src&quo…...
光伏系统MPPT、恒功率控制切换Simulink仿真
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
mysql双主互从通过KeepAlived虚拟IP实现高可用
mysql双主互从通过KeepAlived虚拟IP实现高可用 在mysql 双主互从的基础上, 架构图: Keepalived有两个主要的功能: 提供虚拟IP,实现双机热备通过LVS,实现负载均衡 安装 # 安装 yum -y install keepalived # 卸载 …...
苹果应用高版本出现:“无法安装此app,因为无法验证其完整性”是怎么回事?竟然是错误的?
最近经常有同学私聊我问苹果应用签名后用落地页下载出现高版本是什么意思?我一脸懵!还有这个操作?高版本是个啥玩意!所以我就上了一下科技去搜索引擎搜索了下,哈哈哈,然后了解下来发现是这样的首先我们确定…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案
一、延迟敏感行业面临的DDoS攻击新挑战 2025年,金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征: AI驱动的自适应攻击:攻击流量模拟真实用户行为,差异率低至0.5%,传统规则引…...
拟合问题处理
在机器学习中,核心任务通常围绕模型训练和性能提升展开,但你提到的 “优化训练数据解决过拟合” 和 “提升泛化性能解决欠拟合” 需要结合更准确的概念进行梳理。以下是对机器学习核心任务的系统复习和修正: 一、机器学习的核心任务框架 机…...
