当前位置: 首页 > news >正文

esp32驱动带字库芯片TFT屏幕

前言

学习esp32单片机开发,前段时间在网上买了一块2.0寸TFT屏幕。

长这个样子,这个屏幕带汉字字库的硬件模块。我仔细看了一下这个字库模块上面写的字是25Q32FVSIG 1336

在这里插入图片描述在这里插入图片描述

文档

卖家也发来了开发文档,是个doc文档,张这个样子。

在这里插入图片描述
在这里插入图片描述

开发准备

下面开始根据文档进行开发,调用这个字库文件内的汉字,并且把它显示出来。
这个是我的接线,没有走硬件spi,这样直接插上去,就免去了接线线。
引脚对应

ST7789_GND GND
ST7789_VCC 15 VCC
ST7789_SCL 2  (SCLK)
ST7789_SDA 4  (MOSI)
ST7789_SDO 16  (MISO)
ST7789_RST 17
ST7789_DC 5
ST7789_CS 18
ST7789_CSF 19  
ST7789_BLK 21 VCC

在这里插入图片描述

创建工程 PlatformIO工程
配置和引用

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
upload_speed = 921600
lib_deps = bodmer/TFT_eSPI@^2.5.43tikaflow/UTF8ToGB2312@^1.1.52
1.引入TFT_eSPI.h 下载地址:https://github.com/Bodmer/TFT_eSPI
2.在User_Setup.h中放开注释: #define TFT_WIDTH  240放开注释: #define TFT_HEIGHT 320放开注释: #define ST7789_DRIVER 注释掉:默认的#define ILI9341_DRIVER#define TFT_MOSI 4
#define TFT_SCLK 2
#define TFT_CS   18  // Chip select control pin
#define TFT_DC   5   // Data Command control pin
#define TFT_RST  17  // Reset pin (could connect to RST pin)
#define TFT_BL   21  // LED back-light

源码实现

根据上面文档,实现读取模块中汉字并且渲染到屏幕上。下面是源码

main.cpp

#include <Arduino.h>
#include <TFT_eSPI.h>
#include <SPI.h>
#include "UTF8ToGB2312.h"
TFT_eSPI tft;
// 字库芯片引脚
#define FLASH_CS 19
#define FLASH_MISO 16// 字库结构体
struct FontInfo {uint8_t fontSize;      // 字号uint32_t byteSize;     // 字库占用字节数 实际占用是 byteSize * fontSizeuint32_t addr;         // 字库偏移地址
};// ASCII 字库信息
const FontInfo ASCII_FONTS[] = {{12, 1, 0X1000L},  // 6x12{14, 1, 0X1600L},  // 7x14{16, 1, 0X1D00L},  // 8x16{18, 2, 0X2500L},  // 9x18{20, 2, 0X3700L},  // 10x20{22, 2, 0X4B00L},  // 11x22{24, 2, 0X6100L},  // 12x24{26, 2, 0X7900L}   // 13x26
};// GB2312 字库信息
const FontInfo GB2312_FONTS[] = {{12, 2, 0X9300L},     // 12x12{14, 2, 0X39300L},    // 14x14{16, 2, 0X71300L},    // 16x16{18, 3, 0XB1300L},    // 18x18{20, 3, 0X11D300L},   // 20x20{22, 3, 0X195300L},   // 22x22{24, 3, 0X219300L},   // 24x24{26, 4, 0X2A9300L}    // 26x26
};// 初始化 SPI Flash
void initFlash() {pinMode(FLASH_CS, OUTPUT);digitalWrite(FLASH_CS, HIGH);SPI.begin(TFT_SCLK, FLASH_MISO, TFT_MOSI, FLASH_CS);SPI.setFrequency(1000000);SPI.setDataMode(SPI_MODE0);
}// 读取字库数据
uint8_t readFontData(uint32_t addr) {uint8_t data;digitalWrite(FLASH_CS, LOW);SPI.transfer(0x03);SPI.transfer((addr >> 16) & 0xFF);SPI.transfer((addr >> 8) & 0xFF);SPI.transfer(addr & 0xFF);data = SPI.transfer(0x00);digitalWrite(FLASH_CS, HIGH);return data;
}// 显示一个汉字 (GB2312)
void drawGB2312Char(uint16_t x, uint16_t y, uint16_t ch, uint16_t color, uint8_t fontSize) {if (fontSize < 12 || fontSize > 26 || (fontSize % 2) != 0) {return; // 无效的字体大小}const FontInfo& fontInfo = GB2312_FONTS[(fontSize - 12) / 2];uint32_t fontAddr = fontInfo.addr + (((ch >> 8) - 0xA1) * 94 + (ch & 0xFF) - 0xA1) * fontInfo.fontSize * fontInfo.byteSize;for (uint16_t i = 0; i < fontInfo.fontSize; i++) {for (uint16_t j = 0; j < fontInfo.byteSize; j++) {uint8_t data = readFontData(fontAddr + i * fontInfo.byteSize + j);for (uint8_t k = 0; k < 8; k++) {if (data & (0x80 >> k)) {tft.drawPixel(x + j * 8 + k, y + i, color);}}}}
}// 显示一个 ASCII 字符
void drawASCIIChar(uint16_t x, uint16_t y, uint8_t ch, uint16_t color, uint8_t fontSize) {if (fontSize < 12 || fontSize > 26 || (fontSize % 2) != 0) {return; // 无效的字体大小}const FontInfo& fontInfo = ASCII_FONTS[(fontSize - 12) / 2];uint32_t fontAddr = fontInfo.addr + ch * fontInfo.byteSize * fontInfo.fontSize;for (uint16_t i = 0; i < fontInfo.fontSize; i++) {for (uint16_t j = 0; j < fontInfo.byteSize; j++) {uint8_t data = readFontData(fontAddr + i * fontInfo.byteSize + j);for (uint8_t k = 0; k < 8; k++) {if (data & (0x80 >> k)) {tft.drawPixel(x + j * 8 + k, y + i, color);}}}}
}// 显示字符串 (兼容汉字、英文字符和数字)
void drawString(uint16_t x, uint16_t y, const char *str, uint16_t color, uint8_t fontSize = 16) {String gbStr = GB.get(str); // UTF-8 to GB2312const char *gbCharPtr = gbStr.c_str();uint16_t xPos = x;while (*gbCharPtr) {uint8_t ch = (uint8_t)gbCharPtr[0];if (ch >= 0xA1) { // 汉字uint16_t gbCh = (ch << 8) | (uint8_t)gbCharPtr[1];drawGB2312Char(xPos, y, gbCh, color, fontSize);xPos += fontSize;gbCharPtr += 2;} else if (ch >= 32 && ch <= 126) { // ASCII 字符drawASCIIChar(xPos, y, ch, color, fontSize);gbCharPtr++;xPos += fontSize / 2;} else { // 其他字符或错误处理gbCharPtr++; // 跳过未知字符}}
}void setup() {Serial.begin(115200);pinMode(15, OUTPUT);pinMode(21, OUTPUT);digitalWrite(15, HIGH);digitalWrite(21, HIGH);tft.init();tft.fillScreen(TFT_BLACK);initFlash();drawString(0, 0, "12号:你好,世界!123abc", TFT_GREEN, 12);drawString(0, 12, "14号:你好,世界!123abc", TFT_GREEN, 14);drawString(0, 26, "16号:你好,世界!123abc", TFT_GREEN, 16);drawString(0, 42, "18号:你好,世界!123abc", TFT_GREEN, 18);drawString(0, 60, "20号:你好,世界!123abc", TFT_GREEN, 20);drawString(0, 80, "22号:你好,世界!123abc", TFT_GREEN, 22);drawString(0, 102, "24号:你好,世界!123abc", TFT_GREEN, 24);drawString(0, 126, "26号:你好,世界!123abc", TFT_GREEN, 26);drawString(0, 180, "CSDN关注:雨季余静", TFT_GREEN, 26);
}void loop() {}

最终效果如下

在这里插入图片描述

总结

虽然源码没多少行,但是真的折腾了我一整天。

主要是这模块是gb2312的字库,然而程序代码中的汉字是UTF-8汉字。显示出来就是乱码,开始我还以为是我弄错了,后来才发现代码中的文字是UTF-8编码。引入了UTF8ToGB2312.h 问题就迎刃而解了。

如果解决了你的问题希望给个关注,谢谢。

相关文章:

esp32驱动带字库芯片TFT屏幕

前言 学习esp32单片机开发&#xff0c;前段时间在网上买了一块2.0寸TFT屏幕。 长这个样子&#xff0c;这个屏幕带汉字字库的硬件模块。我仔细看了一下这个字库模块上面写的字是25Q32FVSIG 1336 文档 卖家也发来了开发文档&#xff0c;是个doc文档&#xff0c;张这个样子。 开…...

为AI聊天工具添加一个知识系统 之138 设计重审 之2 文章学 引言之2 附加符号学附属诠释学附随工程学(联系)

本文要点 要点 符号学大局观&#xff1a; 诠释学&#xff08;当代 加成[0]&#xff1a;“预期”和“预设” 两者的 不期而遇 。“邂逅”&#xff09; 我们在文章学工具设计中 以全局观考虑&#xff1a;嵌入编程工具的逻辑性底&#xff08; 哲学诠释 下确界&#xff09; 并…...

java环境部署

java环境部署 一、准备工作 jrejdkeclipse jdk下载&#xff1a;21和1.8-----官网&#xff1a;Oracle&#xff1a;Java 下载 |神谕 该处选择要依据自身的系统类型选择下载 idea的下载安装&#xff1a;IntelliJ IDEA | Other Versions 二、安装 三、环境配置 四、使用 五、i…...

正点原子[第三期]Arm(iMX6U)Linux移植学习笔记-2.1 uboot简介

前言&#xff1a; 本文是根据哔哩哔哩网站上“Arm(iMX6U)Linux系统移植和根文件系统构键篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。 引用&#xff1a; …...

CentOS 7.9 安装 ClickHouse 文档

1. 环境准备 确保系统为 CentOS 7.9&#xff0c;并已安装 Docker。如果未安装 Docker&#xff0c;请先安装 Docker。 安装 Docker # 卸载旧版本 Docker&#xff08;如果有&#xff09; sudo yum remove -y docker docker-client docker-client-latest docker-common docker-…...

高考數學。。。

2024上 具体来说&#xff0c;直线的参数方程可以写为&#xff1a; x1t y−t z1t 二、简答题(本大题共5小题&#xff0c;每小题7分&#xff0c;共35分。) 12.数学学习评价不仅要关注结果评价&#xff0c;也要关注过程评价。简要说明过程评价应关注哪几个方面。…...

使用GitLink个人建站服务部署Allure在线测试报告

更多技术文章&#xff0c;访问软件测试社区 文章目录 &#x1f680;前言&#x1f511;开通GitLink个人建站服务1. 前提条件2. 登录GitLink平台&#xff08;https://www.gitlink.org.cn/login&#xff09;3. 进入设置>个人建站>我的站点4. 新建站点5. 去仓部进行部署6. 安…...

Linux 上离线安装 python3

在Linux系统上进行离线安装 Python3&#xff0c;通常是因为目标机器没有网络连接。以下是一个通用的步骤指南&#xff0c;帮助你在这种情况下成功安装Python 3&#xff1a; 下载安装包 选择一台有网络连接的机器&#xff1a;这台机器的操作系统应该尽可能与目标机器相同或相似…...

js操作字符串的常用方法

1. 查找和截取​​​​​​​ 1.1 indexOf 作用&#xff1a;查找子字符串在字符串中首次出现的位置。 是否改变原字符串&#xff1a;不会改变原字符串。 返回值&#xff1a;如果找到子字符串&#xff0c;返回其起始索引&#xff08;从 0 开始&#xff09;&#xff1b;如果未…...

自动化学习-使用git进行版本管理

目录 一、为什么要学习git 二、git是什么 三、git如何使用 1、git的下载安装和配置 2、git常用的命令 3、gitee远程仓库的使用 &#xff08;1&#xff09;注册 &#xff08;2&#xff09;创建仓库 &#xff08;3&#xff09;配置公钥&#xff08;建立电脑和git…...

GCC RISCV 后端 -- GCC Passes 注释

在前面文章提到&#xff0c;当GCC 前端完成对C源代码解析完成后&#xff0c;就会使用 处理过程&#xff08;Passes&#xff09;机制&#xff0c;通过一系列的处理过程&#xff0c;将 GENERIC IR 表示的C程序 转步转换成 目标机器的汇编语言。过程描述如下图所示&#xff1a; 此…...

Ollama存在安全风险的情况通报及解决方案

据清华大学网络空间测绘联合研究中心分析&#xff0c;开源跨平台大模型工具Ollama默认配置存在未授权访问与模型窃取等安全隐患。鉴于目前DeepSeek等大模型的研究部署和应用非常广泛&#xff0c;多数用户使用Ollama私有化部署且未修改默认配置&#xff0c;存在数据泄露、算力盗…...

IDEA Generate POJOs.groovy 踩坑小计 | 生成实体 |groovy报错

一、无法生成注释或生成的注释是null 问题可能的原因&#xff1a; 1.没有从表里提取注释信息&#xff0c;修改def calcFields(table)方法即可 def calcFields(table) {DasUtil.getColumns(table).reduce([]) { fields, col ->def spec Case.LOWER.apply(col.getDataType().…...

阿里云云监控资源告警常用模板

阿里云云监控资源告警常用模板 {"HostAvailabilityTemplate": [],"Description": "","SystemEventTemplates": [],"AlertTemplatesJson": {"kvstore_standard": [{"displayName": "Connection usa…...

Tailwind CSS 问题:npm error could not determine executable to run

问题与处理策略 问题描述 npx tailwindcss init -p在使用 Tailwind CSS 的前端项目中&#xff0c;执行上述指令&#xff0c;即初始化 Tailwind CSS 时&#xff0c;报如下错误 npm error could not determine executable to run# 报错npm 错误无法确定要运行的可执行文件问题…...

vue基本功

watchEffect和watch watchEffect默认 immdiate 是 true,而且自动收集依赖 watch需要手动写依赖,immdiate 默认是 false toRef和toRefs toRef: 复制 reactive 里的单个属性并转成 ref toRefs: 复制 reactive 里的所有属性并转成 ref vue3中使用vuex import { useStore } f…...

.NET10 - 预览版1新功能体验(一)

.NET 10 首个预览版已经在前两天发布&#xff0c;该版本在 .NET Runtime、SDK、libraries、C#、ASP.NET Core、Blazor 和 .NET MAUI 等多个方面都有重大改进和增强。其中C# 14 预览版也伴随着.NET 10预览版一起发布了&#xff0c;今天就和大家一起体验一下.NET 10 和 C# 14 。 …...

java下载多个网络文件并压缩成压缩包保存到本地

背景 开发票的时候远程会返回发票的url&#xff0c;现在客户端需要下载发票&#xff1b;因为一个订单可能不止一张发票&#xff0c;因此需要通过网络把远程的文件下载回来并压缩成压缩文件进行返回。 实现 本文的例子直接基于java.net包下面的类实现。&#xff08;因为是基于…...

23种设计模式之单例模式(Singleton Pattern)【设计模式】

文章目录 一、简介二、关键点三、实现单例模式的步骤四、C#示例4.1 简单的单例模式4.2 线程安全的单例模式&#xff08;双重检查锁定&#xff09;4.3 静态初始化单例模式 五、单例模式优缺点5.1 优点5.2 缺点 六、适用场景七、示例的现实应用 一、简介 单例模式&#xff08;Si…...

[项目]基于FreeRTOS的STM32四轴飞行器: 四.LED控制

基于FreeRTOS的STM32四轴飞行器: 四.LED控制 一.配置Com层二.编写驱动 一.配置Com层 先在Com_Config.h中定义灯位置的枚举类型&#xff1a; 之后定义Led的结构体&#xff1a; 定义飞行器状态&#xff1a; 在Com_Config.c中初始化四个灯&#xff1a; 在Com_Config.h外部声明…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

2023赣州旅游投资集团

单选题 1.“不登高山&#xff0c;不知天之高也&#xff1b;不临深溪&#xff0c;不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...

基于鸿蒙(HarmonyOS5)的打车小程序

1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...

Axure 下拉框联动

实现选省、选完省之后选对应省份下的市区...