【Arduino TFT】 记录使用DMA优化TFT屏帧率

news2025/1/15 12:50:59

忘记过去,超越自己

  • ❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️
  • ❤️ 本篇创建记录 2023-10-18 ❤️
  • ❤️ 本篇更新记录 2023-10-18 ❤️
  • 🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言📝
  • 🙏 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请留言轰炸哦!及时修正!感谢支持!
  • 🔥 Arduino ESP8266教程累计帮助过超过1W+同学入门学习硬件网络编程,入选过选修课程,刊登过无线电杂志 🔥零基础从入门到熟悉Arduino平台下开发ESP8266,同时会涉及网络编程知识。专栏文章累计超过60篇,分为基础篇、网络篇、应用篇、高级篇,涵盖ESP8266大部分开发技巧。

快速导航
单片机菜鸟的博客快速索引(快速找到你要的)

如果觉得有用,麻烦点赞收藏,您的支持是博主创作的动力。

文章目录

    • 1. 前言
    • 2. 优化前ino代码
    • 3. 优化后ino代码

1. 前言

在这里插入图片描述

在上一篇

【Arduino TFT】 记录ESP32驱动显示二维码 显示gif动图,涉及TFT_eSPI、TJpg_Decoder库、使用python脚本一键生成测试代码

在这里插入图片描述
one.h文件内容:

编码有点多,这里不贴出来。

2. 优化前ino代码

#include <TFT_eSPI.h>
#include <SPI.h>
#include <TJpg_Decoder.h>
#include <Arduino.h>
#include "one.h"  //引入gif生成的.h文件

typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
// LCD屏幕相关设置是什么屏幕什么驱动
// 引脚需配置tft_espi库中的 User_Setup.h文件
TFT_eSPI tft = TFT_eSPI();
//动画更新时间记录
int Amimate_reflash_Time = 0;
int Animate_key = -1; //初始化图标显示帧数

//从动图数组里面获取一帧图像数据
void imgAnim(const uint8_t **Animate_value, uint32_t *Animate_size){
    Animate_key++;
    *Animate_value = one[Animate_key];
    *Animate_size = one_size[Animate_key];
    if (Animate_key >= (sizeof(one)/sizeof(one[0])-1))  //gif动图帧数
            Animate_key = -1;
}

// TFT屏幕输出函数
bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t *bitmap){
    if (y >= tft.height())
        return 0;
    tft.pushImage(x, y, w, h, bitmap);
    return 1;
}

void setup(){
    Serial.begin(115200);
    tft.begin();
    tft.invertDisplay(1); //反转所有显示颜色1反转0正常
    tft.setRotation(0);
    tft.fillScreen(0x0000);
    TJpgDec.setJpgScale(1);
    TJpgDec.setSwapBytes(true);
    TJpgDec.setCallback(tft_output);
    tft.fillScreen(TFT_BLACK);
}

void loop(){
    const uint8_t *Animate_value; //指向关键帧的指针
    uint32_t Animate_size;        //指向关键帧大小的指针
    if (millis() - Amimate_reflash_Time > 30){
    Amimate_reflash_Time = millis();
    imgAnim(&Animate_value, &Animate_size);
    TJpgDec.drawJpg(0, 0, Animate_value, Animate_size);
    }
}

3. 优化后ino代码

#include <TFT_eSPI.h>
#include <SPI.h>
#include <TJpg_Decoder.h>
#include <Arduino.h>
#include "one.h"  //引入gif生成的.h文件

typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
// LCD屏幕相关设置是什么屏幕什么驱动
// 引脚需配置tft_espi库中的 User_Setup.h文件
TFT_eSPI tft = TFT_eSPI();
//动画更新时间记录
int Amimate_reflash_Time = 0;
int Animate_key = -1; //初始化图标显示帧数

// DMA 双缓冲模式
// DMA 直接内存搬运技术,使数据不经过cpu,直接从内存搬运到spi的发送的寄存器里面,这样做的好处是减少cpu的负担,而且能大大提升显示屏的刷新速率
uint16_t dmaBuffer1[32 * 32]{};  // Toggle buffer for 32*32 MCU block, 1024bytes
uint16_t dmaBuffer2[32 * 32]{};  // Toggle buffer for 32*32 MCU block, 1024bytes
uint16_t *dmaBufferPtr = dmaBuffer1;
// 当前使用的DMA缓冲
bool dmaBufferSel = 0;

//从动图数组里面获取一帧图像数据
void imgAnim(const uint8_t **Animate_value, uint32_t *Animate_size){
    Animate_key++;
    *Animate_value = one[Animate_key];
    *Animate_size = one_size[Animate_key];
    if (Animate_key >= (sizeof(one)/sizeof(one[0])-1))  //gif动图帧数
            Animate_key = -1;
}

// TFT屏幕输出函数
bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t *bitmap){
    if (y >= tft.height())
        return 0;
    if (dmaBufferSel) {
        dmaBufferPtr = dmaBuffer2;
    } else {
        dmaBufferPtr = dmaBuffer1;
    }
    dmaBufferSel = !dmaBufferSel;
    tft.pushImageDMA(x, y, w, h, bitmap, dmaBufferPtr);
    return 1;
}

void setup(){
    Serial.begin(115200);
    tft.begin();
    tft.invertDisplay(1); //反转所有显示颜色1反转0正常
    tft.setRotation(0);
    tft.initDMA();
    tft.fillScreen(0x0000);
    TJpgDec.setJpgScale(1);
    TJpgDec.setSwapBytes(true);
    TJpgDec.setCallback(tft_output);
    tft.fillScreen(TFT_BLACK);
}

void loop(){
    const uint8_t *Animate_value; //指向关键帧的指针
    uint32_t Animate_size;        //指向关键帧大小的指针
    if (millis() - Amimate_reflash_Time > 30){
    Amimate_reflash_Time = millis();
    imgAnim(&Animate_value, &Animate_size);
    // 必须先使用startWrite,以便TFT芯片选择保持低的DMA和SPI通道设置保持配置
    tft.startWrite();
    // 在左上角的0,0处绘制图像——在这个草图中,DMA请求在回调tft_output()中处理
    TJpgDec.drawJpg(0, 0, Animate_value, Animate_size);
    // 必须使用endWrite来释放TFT芯片选择和释放SPI通道
    tft.endWrite();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1104832.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件外包开发设计文档

编写软件设计文档是项目开发过程中的关键步骤&#xff0c;它有助于明确系统的设计和架构&#xff0c;并为开发人员提供指导。以下是编写软件设计文档的一般步骤和建议&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;…

Python中Scrapy框架搭建ip代理池教程

在网络爬虫开发中&#xff0c;使用代理IP池可以提高爬取效率和匿名性&#xff0c;避免被目标网站封禁IP。本文将介绍如何使用Python中的Scrapy框架搭建IP代理池&#xff0c;并提供代码实例&#xff0c;帮助您快速搭建一个稳定可靠的代理池。 Python中Scrapy框架搭建ip代理池教程…

Excel·VBA制作工资条

看到一篇博客《excel表头_Excel工资表怎么做&#xff1f;3分钟学会利用函数生成工资表》&#xff0c;使用排序功能、函数制作工资条。但如果需要经常制作工资条&#xff0c;显然使用VBA更加方便 VBA制作工资条 Sub 制作工资条()Dim title_row&, blank_row&, ws_new$,…

变电站数字孪生3D可视化运维系统,实现电力行业智慧化数字化信息化转型升级

变电站数字孪生3D可视化运维系统&#xff0c;实现电力行业智慧化数字化信息化转型升级。近年来&#xff0c;随着科技不断发展与进步&#xff0c;我国在智慧电网国网电力建设方面取得了长足进展。目前已经在多个地区和国家建立起了智慧电网电力项目并投入运行&#xff0c;这些项…

Ask Milvus Anything!聊聊被社区反复@的那些事儿ⅠⅠ

在上月的 “Ask Milvus” 专题直播中&#xff0c;我们为大家带来了 Backup 的技术解读&#xff0c;收到了社区成员很多积极的反馈。本期直播&#xff0c;我们将继续为大家带来社区呼声很高的 “Birdwatcher” 和 “Range Search” 两项功能的技术解读。 BirdWatcher 作为 Milvu…

Go语言入门心法(八): mysql驱动安装报错onnection failed

一: go语言安装mysql驱动报错 安装最新版mysql驱动&#xff1a; PS D:\program_file\go_workspace> go install github.com/go-sql-driver/mysqllatest 报错信息&#xff1a; go: github.com/go-sql-driver/mysqllatest: module github.com/go-sql-driver/mysql: Get "…

如何转换Corona和Vray材质?cr材质转vr材质的方法

cr材质转vr材质的方法一&#xff1a;使用CG Magic插件&#xff0c;一键转换 CG Magic是一款基于3ds Max深度开发的智能化辅助插件&#xff0c;上千项实用功能&#xff0c;降低渲染时长&#xff0c;节省时间和精力&#xff0c;大幅简化工作流程&#xff0c;助力高效完成创作。 …

Nessus已激活,New Scan按钮不可点击

刷新后会给出下面的提示 Plugins are compiling. Nessus will be limited until compilation is complete. 因为插件编译中&#xff0c;所以扫描功能被禁用了。 查看编辑进度&#xff0c;鼠标放到两个循环箭头上即可查看。

中运宝APP:光伏能源——绿色投资的未来之星

光伏能源概念股&#xff0c;即在资本市场中与光伏能源产业相关的股票。随着全球对可再生能源的关注度不断提高&#xff0c;光伏能源概念股也逐渐受到投资者的热捧。中运宝APP将深入探讨光伏能源概念股的相关信息&#xff0c;以期帮助投资者更好地了解这一领域的投资潜力。 光伏…

小程序的console中出现:。。。不在以下 request 合法域名列表中,请参考文档:。。。的报错解决

报错效果&#xff1a; 其实这个报错不代表自己的代码有问题 但是本强迫症研究了一下&#xff0c;按照以下方法关掉就不会显示这个报错了。 点微信开发者工具中的右上角的详情。点本地设置。勾选不校验。。。HTTPS证书。 即可关闭该报错&#xff1a;

IntelliJ IDEA Maven加载超时问题

IDEA创建Maven项目遇到如下错误&#xff1a; Could not transfer artifact org.apache.maven.plugins:maven-compiler-plugin:pom:3.10.1 from/to central (Central Repository:): Connect to repo.maven.apache.org:443 [repo.maven.apache.org/146.75.112.215] failed: conn…

Xposed hook 抖音账户信息

本篇主要讲下hook获取 抖音账户的相关信息&#xff0c;直接上代码。 public class DouHook {private static final String TAG "DouHook";public static void hook(XC_LoadPackage.LoadPackageParam lpparam) {Log.e(TAG, "DouHook start");if (lpparam …

Visual Studio2019 与 MySQL连接 版本关系

Refer: VS 连接MySQL | mysql-for-visualstudio 的安装-CSDN博客 【精选】用VS2019&#xff08;C#&#xff09;连接MYSQL(从0入门&#xff0c;手把手教学&#xff09;_mysql-for-visualstudio-1.2.9.msi_Flying___rabbit的博客-CSDN博客 一、工具&#xff1a;VS2019需要连接M…

【 Python ModuleNotFoundError: No module named ‘xxx‘可能的解决方案大全】

Python ModuleNotFoundError: No module named ‘xxx‘可能的解决方案大全 本文主要介绍了Python ModuleNotFoundError: No module named ‘xxx‘可能的解决方案大全&#xff0c;文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值&#x…

学习老徐关于写作的思考,价值很大

* 戳上方蓝字“前端队长”关注我&#xff0c;每日更新 大家好啊&#xff0c;我是Daotin。 今天分享 IDO 老徐关于写作的建议和思考&#xff0c; 每一条都值得好好学习。 建议收藏&#xff0c;有条件的打印下来&#xff0c;贴在电脑边&#xff0c;随时能看到。 多思考&#xff0…

红包场景的系统设计和实践

一、红包系统的业务场景 红包场景的业务处理流程&#xff1a; 包红包&#xff1a;需要查询用户账户金额&#xff0c;需要调用账户查询服务发红包&#xff1a;需要红包服务生成红包订单id抢红包&#xff1a;通过红包订单id实时生成单笔金额凭证拆红包&#xff1a;有两条处理主…

C++ “引用”究竟是什么?(代码实测)

C的引用是个挺好用的东西&#xff0c;相当于指针的另一种写法&#xff0c;虽然引用有一些约束&#xff0c;比如必须初始化而且不能修改引用目标&#xff0c;但确实非常大地增加了编程的清晰度和灵活性。 引用主要有这些价值&#xff1a; 简化指针访问&#xff0c;“.”比“-&g…

简单方法建立个人网站,不用编程

对于很多没有编程知识的小白来说&#xff0c;建立个人网站似乎是一件困难而遥远的事情。然而&#xff0c;现在有了一个无需编程的方法&#xff0c;小白也能够轻松建立自己的个人网站&#xff0c;让自己的才华和创意得到更好的展示&#xff01; 首先&#xff0c;你需要登录乔拓云…

【快刊推荐】综合类EI,最新案例29天录用,国人友好!

综合类 • 快刊推荐 01 期刊简介 检索数据库&#xff1a;EI &Scopus &Google Scholar 版面类别&#xff1a;正刊 数据库收录年份&#xff1a;2009年 国人占比&#xff1a;47%&#xff0c;对国人友好 年发文量&#xff1a;20篇左右 02 接收领域 生物&#xff…

常见场景面试题-接口重试策略、二维码扫描原理、幂等性、排行榜(三)

typora-copy-images-to: imgs微信二维码扫描原理&#xff1a; 答&#xff1a;流程&#xff1a; 总的来说&#xff0c;PC 端需要进行扫码登陆的原理是通过二维码绑定移动端的身份信息以及PC端的设备信息&#xff0c;根据这两个信息生成 token 给 PC 端&#xff0c;PC 端就登陆成…