忘记过去,超越自己
- ❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️
- ❤️ 本篇创建记录 2023-10-18 ❤️
- ❤️ 本篇更新记录 2023-10-18 ❤️
- 欢迎关注 点赞 收藏 ⭐️留言
- 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请留言轰炸哦!及时修正!感谢支持!
- Arduino ESP8266教程累计帮助过超过1W+同学入门学习硬件网络编程,入选过选修课程,刊登过无线电杂志 零基础从入门到熟悉Arduino平台下开发ESP8266,同时会涉及网络编程知识。专栏文章累计超过60篇,分为基础篇、网络篇、应用篇、高级篇,涵盖ESP8266大部分开发技巧。
快速导航
单片机菜鸟的博客快速索引(快速找到你要的)
如果觉得有用,麻烦点赞收藏,您的支持是博主创作的动力。
在上一篇
【Arduino TFT】 记录ESP32驱动显示二维码 显示gif动图,涉及TFT_eSPI、TJpg_Decoder库、使用python脚本一键生成测试代码
编码有点多,这里不贴出来。
#include
#include
#include
#include
#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);
}
}
#include
#include
#include
#include
#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();
}
}