本文实现的功能是基于GitHub上readguy开源代码的二次开发与精简,项目原始作者是friendshipender,项目地址:https://github.com/fsender/readguy



|
ESP8266 GPIO |
|
|
|
GPIO16 |
CS |
|
|
GPIO13 |
MOSI(DI) |
与墨水屏共享 HSPI MOSI |
|
GPIO12 |
MISO(DO) |
HSPI MISO |
|
GPIO14 |
CLK(SCK) |
与墨水屏共享 HSPI SCK |
|
|
|
|
|
|
|
|

需要ctg_u8g2_wqy12.c和ctg_u8g2_wqy12.h两个文件,在readguy库的示例文件中。【代码中使用的16号字体wqy16_gb2312a,需要从u8g2库中导出】u8g2_font_wqy16_chinese、gb2312 字符集详细介绍以及在Readguy中的使用(墨水屏)
readsd001.ino
//显示中文extern const uint8_t ctg_u8g2_font_wqy16_gb2312a[]; //声明中文字体文件const lgfx::U8g2font cn_font16(ctg_u8g2_font_wqy16_gb2312a); //U8G2格式中文字体转化为LGFX格式字体// TF卡配置(硬件SPI,CS引脚为GPIO2)ReadguyDriver myDisplay; //新建一个readguy对象, 用于显示驱动.// IO0按键定义 (ESP8266的Flash按钮)unsigned long lastDebounceTime = 0; // 上次抖动时间int lastButtonState = HIGH; // 上次按键状态void __printMemoryInfo(const char* tag) {Serial.printf("[%s] 可用内存=%u, 可分配内存=%u, 碎片=%.1f%%\n",tag,ESP.getFreeHeap(),ESP.getMaxFreeBlockSize(),100.0 * (1 - ESP.getMaxFreeBlockSize() / (float)ESP.getFreeHeap()));}bool isTxtFile(const char *filename) {const char *dot = strrchr(filename, '.');if (!dot) return false;return strcasecmp(dot + 1, "txt") == 0; // 不区分大小写比较}void listRootFiles() {File root = SD.open("/");while (File entry = root.openNextFile()) {String fileName = entry.name();if (entry.isDirectory()){myDisplay.print("[DIR]");}else{if(isTxtFile(entry.name())){myDisplay.print("[TXT]");}}Serial.println(fileName.c_str());myDisplay.println(fileName.c_str());myDisplay.display();entry.close();delay(50);}}void setup() {// put your setup code here, to run once:Serial.begin(115200); //初始化串口Serial.println("");__printMemoryInfo("setup start");myDisplay.init(1);myDisplay.setEpdDriver(true, true);myDisplay.fillScreen(TFT_WHITE); // 全屏填充颜色myDisplay.setTextColor(0, 1); //设置显示的颜色. 0代表黑色, 1代表白色myDisplay.setFont(&cn_font16);myDisplay.setTextSize(1);myDisplay.setCursor(0, 10);myDisplay.println("Initializing SD...");myDisplay.display();if (SD.begin(TF_CS)) {myDisplay.println("TF Card OK!");myDisplay.display();// 显示TF卡文件列表listRootFiles();} else {myDisplay.print("TF Card Failed!");myDisplay.display();}delay(100);myDisplay.powerOffEPD();// 初始化IO0按键 (内部上拉,低电平有效)pinMode(BUTTON_PIN, INPUT_PULLUP);__printMemoryInfo("setup end");}void loop() {// IO0按键检测 - 刷白屏幕int currentButtonState = digitalRead(BUTTON_PIN);// 检测按键按下 (下降沿触发 + 防抖)if (currentButtonState == LOW && lastButtonState == HIGH) {if (millis() - lastDebounceTime > DEBOUNCE_DELAY) {lastDebounceTime = millis();Serial.println("IO0按下 - 刷白屏幕");delay(50);myDisplay.fillScreen(TFT_WHITE); // 全屏刷白myDisplay.display(); // 刷新显示// myDisplay.display(READGUY_SLOW); // 刷新显示Serial.println("屏幕已刷白");delay(200); // 简单消抖myDisplay.sleepEPD(); //进入睡眠模式, 屏幕不再刷新.// myDisplay.powerOffEPD();}}lastButtonState = currentButtonState;delay(10); // 降低CPU占用}

连接屏幕和SD卡模块后,只剩GPIO0(D3)引脚,无法满足阅读器按键要求(上一页、下一页、确认、返回),后续将通过ADC引脚搭配不同电阻实现多按键输入。