GT20L16S1Y字库芯片在Arduino平台上的中文显示实现(U8G2库应用)

2026-05-09
关注

GT20L16S1Y字库芯片在Arduino平台上的中文显示实现(U8G2库应用)

在实际项目中,开发者手中拥有一块内置GT20L16S1Y字库芯片的LCD显示屏。借助该芯片,可以高效地实现中文字符的显示。为了验证其功能,开发人员对芯片进行了测试。

GT20L16S1Y是一款广泛应用于嵌入式系统的16×16点阵汉字库芯片,支持GB2312简体中文字符集,点阵排列为竖向排列、横向连续的方式。

为提高开发效率,建议使用U8G2库来调用该字库芯片。U8G2库简化了图形和中文字体的处理流程,使调试过程更加高效。以下代码展示了在Arduino平台上的实现方式,并使用SPI接口连接字库芯片与LCD显示屏,通过片选信号(CS)实现数据的同步传输。

#include#include#include// 硬件定义#define PIN_LCD_CS   7#define PIN_LCD_DC   6#define PIN_LCD_RST  11#define PIN_FONT_CS  5// U8G2 屏幕初始化U8G2_ST7565_NHD_C12864_1_4W_HW_SPI u8g2(U8G2_R0, PIN_LCD_CS, PIN_LCD_DC, PIN_LCD_RST);// 汉字点阵缓冲区(16x16 点阵 = 32 字节)uint8_t fontBuffer[32];// 英文字符点阵缓冲区(8x16 点阵 = 16 字节)uint8_t asciiBuffer[16];void setup() {  // 初始化串口(用于调试)  Serial.begin(115200);    // 初始化字库芯片引脚  pinMode(PIN_FONT_CS, OUTPUT);  digitalWrite(PIN_FONT_CS, HIGH); // 默认非选中状态  // 初始化 SPI  SPI.begin();  // 初始化显示屏  u8g2.begin();}// 从 GT20L16S1Y 读取 16x16 汉字点阵void readFontData(uint8_t msb, uint8_t lsb, uint8_t *buffer) {  unsigned long address;  // 根据 GB2312 编码计算字符地址  if (msb >= 0xA1 && msb <= 0xA3 && lsb >= 0xA1) {    address = ((unsigned long)(msb - 0xA1) * 94 + (lsb - 0xA1)) * 32;  } else if (msb >= 0xB0 && msb <= 0xF7 && lsb >= 0xA1) {    address = ((unsigned long)(msb - 0xB0) * 94 + (lsb - 0xA1) + 846) * 32;  } else if (msb == 0xA9 && lsb >= 0xA1) {    address = (282 + (lsb - 0xA1)) * 32;  } else {    address = 0; // 无效字符  }  // 开始 SPI 事务  SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));  digitalWrite(PIN_FONT_CS, LOW); // 选中字库芯片  // 发送读取命令  SPI.transfer(0x03);  // 发送地址(24 位,高位在前)  SPI.transfer((address >> 16) & 0xFF);  SPI.transfer((address >> 8) & 0xFF);  SPI.transfer(address & 0xFF);  // 读取 32 字节点阵数据  for (int i = 0; i < 32; i++) {    buffer[i] = SPI.transfer(0x00);  }  digitalWrite(PIN_FONT_CS, HIGH); // 取消选中  SPI.endTransaction();}// 从 GT20L16S1Y 读取 ASCII 8x16 点阵void readASCIIData(uint8_t asciichar, uint8_t *buffer) {  unsigned long address = (asciichar - 0x20) * 16 + 0x3CF80;  SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));  digitalWrite(PIN_FONT_CS, LOW);  SPI.transfer(0x03);  // 发送地址  SPI.transfer((address >> 16) & 0xFF);  SPI.transfer((address >> 8) & 0xFF);  SPI.transfer(address & 0xFF);  // 读取 16 字节点阵  for (int i = 0; i < 16; i++) {    buffer[i] = SPI.transfer(0x00);  }  digitalWrite(PIN_FONT_CS, HIGH);  SPI.endTransaction();}// 绘制中文字符void drawChineseChar(int x, int y, uint8_t msb, uint8_t lsb) {  readFontData(msb, lsb, fontBuffer);  for (int i = 0; i < 32; i++) {    uint8_t byteData = fontBuffer[i];    for (int bit = 0; bit < 8; bit++) {      if (byteData & (0x01 << bit)) {        u8g2.drawPixel(x + (i % 16), y + (i / 16) * 8 + bit);      }    }  }}// 绘制 ASCII 字符void drawASCIIChar(int x, int y, uint8_t asciichar) {  readASCIIData(asciichar, asciiBuffer);  for (int i = 0; i < 16; i++) {    uint8_t byteData = asciiBuffer[i];    for (int bit = 0; bit < 8; bit++) {      if (byteData & (0x01 << bit)) {        u8g2.drawPixel(x + (i % 8), y + (i / 8) * 8 + bit);      }    }  }}// 显示中英文混合字符串void drawExternalFontString(int x, int y, const uint8_t *str) {  int cursorX = x;  while (*str) {    if (*str < 128) {      // ASCII 字符      drawASCIIChar(cursorX, y + 2, *str);      cursorX += 8;      str++;    } else {      // 中文字符      uint8_t msb = *str;      uint8_t lsb = *(str + 1);      if (lsb == 0) break;      drawChineseChar(cursorX, y, msb, lsb);      cursorX += 16;      str += 2;    }  }}void loop() {  u8g2.firstPage();  do {    const uint8_t textCN[] = {0xB5, 0xB7, 0xB9, 0xC4, 0xD2, 0xD7, 0xD7, 0xE5, 0x00}; // 捣鼓易族    const uint8_t textMix[] = {'H', 'e', 'l', 'l', 'o', 0xCA, 0xC0, 0xBD, 0xE7, 0xA1, 0xA3, 0x00}; // Hello 世界    drawExternalFontString(0, 0, textCN);    drawExternalFontString(0, 20, textMix);  } while (u8g2.nextPage());  delay(1000);}

运行效果如下图所示,成功实现了中英文字符在同一屏幕上的混合显示。

您觉得本篇内容如何
评分

评论

您需要登录才可以回复|注册

提交评论

广告
广告
提取码
复制提取码
点击跳转至百度网盘