使用买来的 st7789LCD 显示器背面就带着一个 tf 卡槽,可以直接连接 tf 卡。使用 Sdfat 库就可以实现对 sd 卡的读写操作。这里尝试测试 sd 卡的读写功能。
LCD 显示器的初始化
//定义LCD的对象
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
tft.init(240, 320); // 初始化ST7789 240x320
tft.fillScreen(ST77XX_BLACK); // 用黑色填充屏幕
tft.setTextColor(ST77XX_WHITE); // 设置文本颜色为白色
tft.setTextSize(2); // 设置文本大小
tft.setCursor(0, 0); // 设置文本起始位置
tft.println("SD read and write test");
SD 卡初始化
//定义SD卡对象
SdFat sd;
if (!sd.begin(SD_CS, SD_SCK_MHZ(10))) {
Serial.println("SD卡初始化失败!");
tft.setTextColor(ST77XX_RED);
tft.println("SDcard init failed");
tft.println("Please check the connection and card");
while (1); // 失败时停止
}
SD 卡写
SdFile writeFile;
if (!writeFile.open(FILENAME, O_WRITE | O_CREAT | O_TRUNC)) {
Serial.println("无法创建文件");
tft.println("Cannot create file");
while (1);
}
writeFile.println(message);
writeFile.close();
SD 卡读
这里预留的 buffer
已经假设读取的数据不会超过 99 个字符!
SdFile readFile;
if (!readFile.open(FILENAME, O_READ)) {
Serial.println("无法打开文件进行读取");
tft.println("Cannot open file for reading");
while (1);
}
char buffer[100]; // 足够大的缓冲区,以容纳消息
int bytesRead = readFile.read(buffer, sizeof(buffer) - 1);
if (bytesRead > 0) {
buffer[bytesRead] = 0; // 添加字符串结束符
Serial.println(buffer);
// 在LCD上显示读取的消息
tft.setTextColor(ST77XX_GREEN);
tft.println(buffer);
} else {
Serial.println("读取失败!");
tft.println("Read failed!");
}
readFile.close();
完整程序
尝试向 sd 卡写入文件,读取文件,并在 lcd 卡上打印。示例程序如下:
#include <SdFat.h>
#include <Adafruit_GFX.h> // 核心图形库
#include <Adafruit_ST7789.h> // ST7789硬件特定库
// 定义引脚
#define SD_CS 7 // SD卡片选引脚
#define TFT_CS 10 // TFT片选引脚
#define TFT_DC 9 // TFT数据/命令引脚
#define TFT_RST 8 // TFT复位引脚
// 创建SD卡和LCD对象
SdFat sd;
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
// 文件名定义
#define FILENAME "message.txt"
// 要写入的消息
const char* message = "Hello from SD card! hello world!";
void setup() {
// 初始化串口
Serial.begin(115200);
delay(1000);
Serial.println("初始化SD卡和LCD...");
// 初始化LCD
tft.init(240, 320); // 初始化ST7789 240x320
tft.fillScreen(ST77XX_BLACK); // 用黑色填充屏幕
tft.setTextColor(ST77XX_WHITE); // 设置文本颜色为白色
tft.setTextSize(2); // 设置文本大小
tft.setCursor(0, 0); // 设置文本起始位置
tft.println("SD read and write test");
delay(1000);
// 初始化SD卡
if (!sd.begin(SD_CS, SD_SCK_MHZ(10))) {
Serial.println("SD卡初始化失败!");
tft.setTextColor(ST77XX_RED);
tft.println("SDcard init failed");
tft.println("Please check the connection and card");
while (1); // 失败时停止
}
Serial.println("SDcard init success!");
tft.println("SDcard init success!");
delay(1000);
// 打开文件进行写入
SdFile writeFile;
if (!writeFile.open(FILENAME, O_WRITE | O_CREAT | O_TRUNC)) {
Serial.println("无法创建文件");
tft.println("Cannot create file");
while (1);
}
// 写入消息
Serial.print("写入消息: ");
Serial.println(message);
tft.println("Writing message...");
delay(1000);
writeFile.println(message);
writeFile.close();
Serial.println("消息写入成功!");
tft.println("Message written successfully!");
// 打开文件进行读取
SdFile readFile;
if (!readFile.open(FILENAME, O_READ)) {
Serial.println("无法打开文件进行读取");
tft.println("Cannot open file for reading");
while (1);
}
// 读取消息
Serial.println("读取消息:");
tft.println("Reading message...");
delay(1000);
char buffer[100]; // 足够大的缓冲区,以容纳消息
int bytesRead = readFile.read(buffer, sizeof(buffer) - 1);
if (bytesRead > 0) {
buffer[bytesRead] = 0; // 添加字符串结束符
Serial.println(buffer);
// 在LCD上显示读取的消息
tft.setTextColor(ST77XX_GREEN);
tft.println(buffer);
} else {
Serial.println("读取失败!");
tft.println("Read failed!");
}
readFile.close();
Serial.println("操作完成!");
tft.println("Operation completed!");
}
void loop() {
// 主循环为空
}
当前显示字号为 2,对于Adafruit GFX 默认字体使用的是5x7像素的字体,但行和字符间又会有 1 个像素的间距,因此可以认为默认情况下一个字符占据 6×8 像素的空间。因此对于一个 240×320 的 LCD 来说,字号为 2 的显示方式(12 ×16),一个屏幕最多显示 400 个字符。
并且 adafruit 库对于中文字符支持不友好,当前只能显示英文。
adafruit 的 GFX 库中提供获取光标 XY 坐标的 API:
**getCursorX**
**:**获取光标X坐标**getCursorY**
**:**获取光标Y坐标
参考链接:
Adafruit GFX Library: Adafruit_GFX Class Reference
参考讨论:
例如,可以在上面的程序中加入以下代码:
tft.print("Operation completed");
int cursorX = tft.getCursorX();
int cursorY = tft.getCursorY();
tft.println("(X: " + String(cursorX) + ", Y: " + String(cursorY) + ")");
就可以打印出Operation completed
结束时的光标位置。
注意,这里使用 print
打印,而不是 println
,因为 prtinln
会默认另起一行。