参考

液晶资料

j2b描述彩屏字库的存储问题

pico-sdk-api文档

rp2040-datasheet.pdf

getting-started-with-pico.pdf

树莓派 Pico 之可编程 IO(PIO)

RP2040-Zero.wiki

目录结构

> tree /f
D:.
│  .gitignore
│  CMakeLists.txt
│  copy_uf2.bat
│  README.md
└─src
    font.h
    main.cpp
    st7735s_pico_80_160_lcd.cpp
    st7735s_pico_80_160_lcd.h

README.md


# 接线图
| 模块引脚 | Pico GPIO | 颜色建议 | 说明           |
|------|-----------|------|--------------|
| GND  | GND       | 黑色   | 电源地          |
| VCC  | 3.3V      | 红色   | 电源(只能 3.3V)  |
| SCL  | GPIO 18   | 蓝色   | SPI0 时钟 SCK  |
| SDA  | GPIO 19   | 绿色   | SPI0 数据 MOSI |
| RES  | GPIO 21   | 紫色   | 复位           |
| DC   | GPIO 20   | 粉色   | 数据/命令选择      |
| CS   | GPIO 17   | 橙色   | 片选           |
| BLK  | GPIO 22   | 灰色   | 背光控制         |

main.cpp

#include "pico/stdlib.h"
#include "st7735s_pico_80_160_lcd.h"
#include "stdio.h"
/* 颜色循环表(参考原 test.c 的 ColorTab) */
static const uint16_t colors[] = { RED, GREEN, BLUE, YELLOW, CYAN };

int main(void)
{
    stdio_init_all();
    lcd_init();

    /* ── 开机界面(对应 main_test)───────────────────── */
    lcd_clear(BLACK);
    lcd_show_string(2,  4,  "ST7735S on Pico",  WHITE,  BLACK);
    lcd_show_string(2,  16, "80x160 RGB565",   YELLOW, BLACK);
    lcd_show_string(2,  30, "Hello,World!",    GREEN,  BLACK);
    lcd_show_string(2,  42, "0123456789",       CYAN,   BLACK);
    lcd_show_string(2,  54, "ABCDEFGHIJKLMNO",  RED,    BLACK);
    lcd_show_string(2,  66,  "abcdefghijklmno",  MAGENTA,BLACK);
    lcd_show_string(2,  78, "!@#$%^&*()-=+",   WHITE,  BLACK);
    sleep_ms(2000);

    /* ── 纯色填充测试(对应 Test_Color)─────────────── */
    for (int i = 0; i < 5; i++) {
        lcd_clear(colors[i]);
        sleep_ms(600);
    }

    printf("test ok \r\n");

    /* ── 主循环:刷字符演示 ──────────────────────────── */
    uint32_t cnt = 0;
    lcd_clear(BLACK);
    while (true) {
       //

        lcd_show_string(2,  2,  "Pico ST7735S",    WHITE,  BLACK);
        lcd_show_string(2,  14, "----------------", GRAY,   BLACK);

        lcd_show_string(2,  26, "RED GREEN",     WHITE,  BLACK);
        lcd_show_string(2,  38, "BLUE YELLOW",    WHITE,  BLACK);
        lcd_show_string(2,  50, "CYAN MAGENTA",   WHITE,  BLACK);

        /* 彩色字 */
        lcd_show_string(2,  64, "Red text",    RED,     BLACK);
        lcd_show_string(2,  76, "Green text",  GREEN,   BLACK);
        lcd_show_string(2,  88, "Blue text",   BLUE,    BLACK);
        lcd_show_string(2,  100,"Yellow text", YELLOW,  BLACK);
        lcd_show_string(2,  112,"Cyan text",   CYAN,    BLACK);
        lcd_show_string(2,  124,"Mag text",    MAGENTA, BLACK);

        /* 计数器 */
        lcd_show_string(2,  138, "cnt:", WHITE, BLACK);
        lcd_show_num(34, 138, cnt++, 6, YELLOW, BLACK);

    }
}

st7735s_pico_80_160_lcd.h

#ifndef __st7735s_pico_80_160_lcd_H
#define __st7735s_pico_80_160_lcd_H

#include "pico/stdlib.h"
#include "hardware/spi.h"
#include <stdint.h>
#include <string.h>

/* ── 引脚(按需修改)─────────────────────────────── */
#define LCD_SPI      spi0
//#define PIN_SCK      18   /* SCL */
//#define PIN_MOSI     19   /* SDA */
//#define PIN_CS       17   /* CS  */
//#define PIN_DC       20   /* DC  */
//#define PIN_RST      21   /* RES */
//#define PIN_BLK      22   /* BLK */

//pico_zero
#define PIN_SCK      2   /* SCL */
#define PIN_MOSI     3   /* SDA */
#define PIN_CS       4   /* CS  */
#define PIN_DC       5   /* DC  */
#define PIN_RST      6   /* RES */
#define PIN_BLK      7   /* BLK */

/* ── 屏幕尺寸与偏移(80×160 竖屏)────────────────── */
#define LCD_W        80
#define LCD_H        160
#define LCD_XOFF     26
#define LCD_YOFF     1

/* ── RGB565 颜色 ─────────────────────────────────── */
#define WHITE        0xFFFF
#define BLACK        0x0000
#define RED          0xF800
#define GREEN        0x07E0
#define BLUE         0x001F
#define YELLOW       0xFFE0
#define CYAN         0x07FF
#define MAGENTA      0xF81F
#define GRAY         0x8430

/* ── API ─────────────────────────────────────────── */
void lcd_init(void);
void lcd_clear(uint16_t color);
void lcd_fill(uint16_t x0, uint16_t y0,
              uint16_t x1, uint16_t y1, uint16_t color);
void lcd_draw_point(uint16_t x, uint16_t y, uint16_t color);
void lcd_show_char(uint16_t x, uint16_t y,
                   char c, uint16_t fc, uint16_t bc);
void lcd_show_string(uint16_t x, uint16_t y,
                     const char *str, uint16_t fc, uint16_t bc);
void lcd_show_num(uint16_t x, uint16_t y,
                  uint32_t num, uint8_t len, uint16_t fc, uint16_t bc);

#endif

st7735s_pico_80_160_lcd.cpp

#include "st7735s_pico_80_160_lcd.h"
#include "font.h"

/* ═══════════════════════════════════════════════════════
   第一部分:底层 SPI 信号控制
   ST7735S 使用 4 线 SPI 协议:
     CS  - 片选,低电平时芯片响应命令/数据
     DC  - 数据/命令选择,低=命令,高=数据
     SCK - 时钟,上升沿采样
     SDA - 串行数据输入(MOSI)
═══════════════════════════════════════════════════════ */

/* 拉低片选,开始一次 SPI 传输 */
static inline void cs_lo(void) { gpio_put(PIN_CS, 0); }

/* 拉高片选,结束一次 SPI 传输 */
static inline void cs_hi(void) { gpio_put(PIN_CS, 1); }

/* DC 置低:接下来发送的是"命令"字节 */
static inline void dc_lo(void) { gpio_put(PIN_DC, 0); }

/* DC 置高:接下来发送的是"数据"字节 */
static inline void dc_hi(void) { gpio_put(PIN_DC, 1); }

/*
 * 向 LCD 写入 1 字节命令
 * 时序:CS↓ → DC↓(命令模式) → 发送字节 → CS↑
 */
static void wr_cmd(uint8_t cmd)
{
    cs_lo(); dc_lo();
    spi_write_blocking(LCD_SPI, &cmd, 1);
    cs_hi();
}

/*
 * 向 LCD 写入 1 字节数据(命令的参数)
 * 时序:CS↓ → DC↑(数据模式) → 发送字节 → CS↑
 */
static void wr_dat(uint8_t dat)
{
    cs_lo(); dc_hi();
    spi_write_blocking(LCD_SPI, &dat, 1);
    cs_hi();
}

/*
 * 向 LCD 写入 1 个像素颜色(RGB565 格式,2 字节)
 * RGB565:高 5 位=R,中 6 位=G,低 5 位=B
 * 先发高字节,再发低字节(大端序)
 */
static void wr_color(uint16_t color)
{
    uint8_t buf[2] = { color >> 8, color & 0xFF };
    cs_lo(); dc_hi();
    spi_write_blocking(LCD_SPI, buf, 2);
    cs_hi();
}

/* ═══════════════════════════════════════════════════════
   第二部分:显示窗口设置
   ST7735S 采用"先设窗口,再填像素"的工作方式:
   1. 用 CASET(0x2A) 设置列范围 [x0, x1]
   2. 用 RASET(0x2B) 设置行范围 [y0, y1]
   3. 发送 RAMWR(0x2C) 后连续写入像素颜色

   注意:此模块物理像素与逻辑坐标有偏移
     X 方向偏移 LCD_XOFF=26
     Y 方向偏移 LCD_YOFF=1
   这是由于 ST7735S 最大支持 132×162,
   而模块实际只用了 80×160,多余的像素需要偏移跳过。
═══════════════════════════════════════════════════════ */
static void set_win(uint16_t x0, uint16_t y0,
                    uint16_t x1, uint16_t y1)
{
    /* 设置列地址范围(X 轴),加上硬件偏移量 */
    wr_cmd(0x2A);                          /* CASET 命令 */
    wr_dat(0x00); wr_dat(x0 + LCD_XOFF);  /* 起始列高字节=0,低字节=x0+偏移 */
    wr_dat(0x00); wr_dat(x1 + LCD_XOFF);  /* 结束列高字节=0,低字节=x1+偏移 */

    /* 设置行地址范围(Y 轴),加上硬件偏移量 */
    wr_cmd(0x2B);                          /* RASET 命令 */
    wr_dat(0x00); wr_dat(y0 + LCD_YOFF);  /* 起始行 */
    wr_dat(0x00); wr_dat(y1 + LCD_YOFF);  /* 结束行 */

    /* 发送写 GRAM 命令,之后连续写入的数据都是像素颜色 */
    wr_cmd(0x2C);                          /* RAMWR 命令 */
}

/* ═══════════════════════════════════════════════════════
   第三部分:LCD 初始化
   上电后需要按顺序配置一系列寄存器:
   帧率 → 反色 → 电源 → Gamma → 像素格式 → 显示方向 → 开显示
═══════════════════════════════════════════════════════ */
void lcd_init(void)
{
    /* ── 1. 初始化硬件 SPI 外设 ──────────────────────
       使用 Pico 的 SPI0,速率 20MHz
       GPIO18=SCK(时钟),GPIO19=MOSI(数据输出) */
    spi_init(LCD_SPI, 20 * 1000 * 1000);
    gpio_set_function(PIN_SCK,  GPIO_FUNC_SPI);
    gpio_set_function(PIN_MOSI, GPIO_FUNC_SPI);

    /* ── 2. 初始化控制引脚(普通 GPIO 输出) ─────────*/
    gpio_init(PIN_CS);  gpio_set_dir(PIN_CS,  GPIO_OUT);
    cs_hi();                   /* CS 默认拉高,不选中 */

    gpio_init(PIN_DC);  gpio_set_dir(PIN_DC,  GPIO_OUT);
    dc_hi();                   /* DC 默认拉高(数据模式) */

    gpio_init(PIN_RST); gpio_set_dir(PIN_RST, GPIO_OUT);

    gpio_init(PIN_BLK); gpio_set_dir(PIN_BLK, GPIO_OUT);
    gpio_put(PIN_BLK, 1);      /* 背光常亮(高电平点亮) */

    /* ── 3. 硬件复位 ──────────────────────────────────
       RST 拉低至少 10ms 可完成复位,
       复位完成后需等待 120ms 再发初始化命令 */
    gpio_put(PIN_RST, 1); sleep_ms(20);   /* 初始高电平 */
    gpio_put(PIN_RST, 0); sleep_ms(20);   /* 拉低复位 */
    gpio_put(PIN_RST, 1); sleep_ms(120);  /* 释放复位,等待稳定 */

    /* ── 4. ST7735S 寄存器初始化序列 ─────────────────*/

    wr_cmd(0x11);       /* SLPOUT:退出睡眠模式 */
    sleep_ms(120);      /* 必须等待 120ms,振荡器稳定 */

    wr_cmd(0x21);       /* INVON:开启显示反色
                           IPS 屏幕必须开此项,否则颜色相反 */

    /* FRMCTR1/2/3:帧率控制(正常/空闲/局部模式)
       参数 0x05,0x3A,0x3A:帧率约 65Hz,前后沿各 58 个时钟 */
    wr_cmd(0xB1); wr_dat(0x05); wr_dat(0x3A); wr_dat(0x3A);
    wr_cmd(0xB2); wr_dat(0x05); wr_dat(0x3A); wr_dat(0x3A);
    wr_cmd(0xB3);              /* 局部模式帧率(正常+空闲各一组) */
    wr_dat(0x05); wr_dat(0x3A); wr_dat(0x3A);
    wr_dat(0x05); wr_dat(0x3A); wr_dat(0x3A);

    wr_cmd(0xB4); wr_dat(0x03); /* INVCTR:列反转模式 */

    /* PWCTR1~5:电源控制寄存器
       调节 AVDD/VGH/VGL/VCOMH 等内部电压 */
    wr_cmd(0xC0); wr_dat(0x62); wr_dat(0x02); wr_dat(0x04);
    wr_cmd(0xC1); wr_dat(0xC0);
    wr_cmd(0xC2); wr_dat(0x0D); wr_dat(0x00);
    wr_cmd(0xC3); wr_dat(0x8D); wr_dat(0x6A);
    wr_cmd(0xC4); wr_dat(0x8D); wr_dat(0xEE);

    wr_cmd(0xC5); wr_dat(0x0E); /* VMCTR1:VCOM 电压控制
                                   影响对比度和白平衡 */

    /* GMCTRP1:正极性 Gamma 校正曲线(16 个控制点)
       Gamma 校正使显示灰阶更线性,颜色更准确 */
    wr_cmd(0xE0);
    wr_dat(0x10); wr_dat(0x0E); wr_dat(0x02); wr_dat(0x03);
    wr_dat(0x0E); wr_dat(0x07); wr_dat(0x02); wr_dat(0x07);
    wr_dat(0x0A); wr_dat(0x12); wr_dat(0x27); wr_dat(0x37);
    wr_dat(0x00); wr_dat(0x0D); wr_dat(0x0E); wr_dat(0x10);

    /* GMCTRN1:负极性 Gamma 校正曲线(16 个控制点) */
    wr_cmd(0xE1);
    wr_dat(0x10); wr_dat(0x0E); wr_dat(0x03); wr_dat(0x03);
    wr_dat(0x0F); wr_dat(0x06); wr_dat(0x02); wr_dat(0x08);
    wr_dat(0x0A); wr_dat(0x13); wr_dat(0x26); wr_dat(0x36);
    wr_dat(0x00); wr_dat(0x0D); wr_dat(0x0E); wr_dat(0x10);

    wr_cmd(0x3A); wr_dat(0x05); /* COLMOD:像素格式
                                   0x05 = 16位 RGB565 */

    wr_cmd(0x36); wr_dat(0xC8); /* MADCTL:存储器访问控制
                                   0xC8 = MY|MX|BGR
                                   MY=1:Y轴镜像
                                   MX=1:X轴镜像
                                   BGR=1:颜色顺序 BGR(非 RGB)
                                   以上组合实现竖屏正向显示 */

    wr_cmd(0x29);               /* DISPON:开启显示输出 */
}

/* ═══════════════════════════════════════════════════════
   第四部分:绘图函数
═══════════════════════════════════════════════════════ */

/*
 * 全屏填充单色
 * 等价于把整个 80×160 区域刷成同一颜色
 * 常用于清屏(传入 BLACK)
 */
void lcd_clear(uint16_t color)
{
    lcd_fill(0, 0, LCD_W - 1, LCD_H - 1, color);
}

/*
 * 矩形区域填充单色
 * (x0,y0):左上角坐标
 * (x1,y1):右下角坐标
 * color  :RGB565 颜色值
 *
 * 原理:设置窗口后连续写入 n 个相同颜色像素
 * n = 宽度 × 高度 = (x1-x0+1) × (y1-y0+1)
 */
void lcd_fill(uint16_t x0, uint16_t y0,
              uint16_t x1, uint16_t y1, uint16_t color)
{
    uint8_t hi = color >> 8;   /* 颜色高字节 */
    uint8_t lo = color & 0xFF; /* 颜色低字节 */
    uint32_t n = (uint32_t)(x1 - x0 + 1) * (y1 - y0 + 1); /* 总像素数 */

    set_win(x0, y0, x1, y1);  /* 设置填充窗口 */
    cs_lo(); dc_hi();          /* 进入连续数据写入模式 */
    while (n--) {
        /* 每个像素写 2 字节(RGB565) */
        spi_write_blocking(LCD_SPI, &hi, 1);
        spi_write_blocking(LCD_SPI, &lo, 1);
    }
    cs_hi();
}

/*
 * 画单个像素点
 * 超出屏幕范围时直接忽略,防止越界写入
 */
void lcd_draw_point(uint16_t x, uint16_t y, uint16_t color)
{
    if (x >= LCD_W || y >= LCD_H) return; /* 坐标越界保护 */
    set_win(x, y, x, y);                  /* 窗口设为单像素 */
    wr_color(color);                       /* 写入颜色 */
}

/* ═══════════════════════════════════════════════════════
   第五部分:字符显示
   使用 font.h 中的 5×8 点阵字库(ASCII 0x20~0x7E)
   每个字符实际占 6×8 像素(5 列字形 + 1 列间距)
═══════════════════════════════════════════════════════ */

/*
 * 显示单个 ASCII 字符
 * x, y :字符左上角坐标
 * c    :ASCII 字符(0x20~0x7E),超出范围显示 '?'
 * fc   :前景色(字的颜色)
 * bc   :背景色
 *
 * 字库格式(ascii_5x8):
 *   每个字符 5 字节,每字节代表一列
 *   字节的 bit0 = 最上面一行,bit7 = 最下面一行
 *   例如字符 'A' 的第 0 列值 0x7E = 0111 1110
 *   表示第 0 列从上到下:0,1,1,1,1,1,1,0
 */
void lcd_show_char(uint16_t x, uint16_t y,
                   char c, uint16_t fc, uint16_t bc)
{
    if (c < 0x20 || c > 0x7E) c = '?';    /* 不支持的字符显示问号 */
    const uint8_t *g = ascii_5x8[c - 0x20]; /* 取字模数据(偏移 0x20) */

    /* 拆分前景色和背景色为高低字节,避免循环内重复计算 */
    uint8_t fh = fc >> 8, fl = fc & 0xFF;
    uint8_t bh = bc >> 8, bl = bc & 0xFF;

    /* 设置 6 列(5 字形 + 1 间距)× 8 行 的绘制窗口 */
    set_win(x, y, x + FONT_W, y + FONT_H - 1);

    cs_lo(); dc_hi(); /* 进入连续像素写入模式 */

    /* 按行扫描输出(row=0 为最上行,row=7 为最下行) */
    for (int row = 0; row < FONT_H; row++) {
        /* 按列输出 5 列字形数据 */
        for (int col = 0; col < FONT_W; col++) {
            /* 检查当前列字模的当前行 bit 是否为 1 */
            if (g[col] & (1 << row)) {
                /* bit=1:前景色(字的笔画) */
                spi_write_blocking(LCD_SPI, &fh, 1);
                spi_write_blocking(LCD_SPI, &fl, 1);
            } else {
                /* bit=0:背景色(空白部分) */
                spi_write_blocking(LCD_SPI, &bh, 1);
                spi_write_blocking(LCD_SPI, &bl, 1);
            }
        }
        /* 第 6 列:字符间距,固定填背景色
           防止相邻字符笔画粘连 */
        spi_write_blocking(LCD_SPI, &bh, 1);
        spi_write_blocking(LCD_SPI, &bl, 1);
    }
    cs_hi();
}

/*
 * 显示字符串
 * 从 (x,y) 开始逐字符输出,到屏幕右边界自动换行
 * 超出屏幕底部时停止显示(不循环)
 *
 * 字符步进:每字符占 (FONT_W+1) = 6 像素宽
 * 换行步进:每行占 (FONT_H+2) = 10 像素高(含行间距 2px)
 */
void lcd_show_string(uint16_t x, uint16_t y,
                     const char *str, uint16_t fc, uint16_t bc)
{
    uint16_t cx = x; /* 当前 X 光标位置 */
    while (*str) {
        /* 超出右边界:换行,X 回到 0 */
        if (cx + (FONT_W + 1) > LCD_W) {
            cx = 0;
            y += FONT_H + 2;
        }
        /* 超出底边界:停止显示 */
        if (y + FONT_H > LCD_H) break;

        lcd_show_char(cx, y, *str++, fc, bc);
        cx += FONT_W + 1; /* X 光标右移一个字符宽度 */
    }
}

/*
 * 显示无符号整数
 * num :要显示的数值
 * len :显示位数(不足时前面补 '0',如 len=6 显示 "000123")
 * fc  :前景色
 * bc  :背景色
 *
 * 原理:从低位到高位依次取余数转字符,
 *       存入 buf 数组(右对齐),再调用 lcd_show_string
 */
void lcd_show_num(uint16_t x, uint16_t y,
                  uint32_t num, uint8_t len,
                  uint16_t fc, uint16_t bc)
{
    char buf[12]; /* 最多显示 10 位十进制数 + 结束符 */
    int i;
    /* 从右到左填充数字字符 */
    for (i = len - 1; i >= 0; i--) {
        buf[i] = '0' + (num % 10); /* 取个位转字符 */
        num /= 10;                  /* 去掉个位 */
    }
    buf[len] = '\0'; /* 字符串结束符 */
    lcd_show_string(x, y, buf, fc, bc);
}

font.h

#ifndef FONT_H
#define FONT_H

#include <stdint.h>

/* 5 列 × 8 行点阵,覆盖 0x20(空格)~0x7E(~) */
#define FONT_W   5
#define FONT_H   8

static const uint8_t ascii_5x8[][5] = {
        {0x00,0x00,0x00,0x00,0x00}, /* 0x20   */
        {0x00,0x00,0x5F,0x00,0x00}, /* 0x21 ! */
        {0x00,0x07,0x00,0x07,0x00}, /* 0x22 " */
        {0x14,0x7F,0x14,0x7F,0x14}, /* 0x23 # */
        {0x24,0x2A,0x7F,0x2A,0x12}, /* 0x24 $ */
        {0x23,0x13,0x08,0x64,0x62}, /* 0x25 % */
        {0x36,0x49,0x55,0x22,0x50}, /* 0x26 & */
        {0x00,0x05,0x03,0x00,0x00}, /* 0x27 ' */
        {0x00,0x1C,0x22,0x41,0x00}, /* 0x28 ( */
        {0x00,0x41,0x22,0x1C,0x00}, /* 0x29 ) */
        {0x14,0x08,0x3E,0x08,0x14}, /* 0x2A * */
        {0x08,0x08,0x3E,0x08,0x08}, /* 0x2B + */
        {0x00,0x50,0x30,0x00,0x00}, /* 0x2C , */
        {0x08,0x08,0x08,0x08,0x08}, /* 0x2D - */
        {0x00,0x60,0x60,0x00,0x00}, /* 0x2E . */
        {0x20,0x10,0x08,0x04,0x02}, /* 0x2F / */
        {0x3E,0x51,0x49,0x45,0x3E}, /* 0x30 0 */
        {0x00,0x42,0x7F,0x40,0x00}, /* 0x31 1 */
        {0x42,0x61,0x51,0x49,0x46}, /* 0x32 2 */
        {0x21,0x41,0x45,0x4B,0x31}, /* 0x33 3 */
        {0x18,0x14,0x12,0x7F,0x10}, /* 0x34 4 */
        {0x27,0x45,0x45,0x45,0x39}, /* 0x35 5 */
        {0x3C,0x4A,0x49,0x49,0x30}, /* 0x36 6 */
        {0x01,0x71,0x09,0x05,0x03}, /* 0x37 7 */
        {0x36,0x49,0x49,0x49,0x36}, /* 0x38 8 */
        {0x06,0x49,0x49,0x29,0x1E}, /* 0x39 9 */
        {0x00,0x36,0x36,0x00,0x00}, /* 0x3A : */
        {0x00,0x56,0x36,0x00,0x00}, /* 0x3B ; */
        {0x08,0x14,0x22,0x41,0x00}, /* 0x3C < */
        {0x14,0x14,0x14,0x14,0x14}, /* 0x3D = */
        {0x00,0x41,0x22,0x14,0x08}, /* 0x3E > */
        {0x02,0x01,0x51,0x09,0x06}, /* 0x3F ? */
        {0x32,0x49,0x79,0x41,0x3E}, /* 0x40 @ */
        {0x7E,0x11,0x11,0x11,0x7E}, /* 0x41 A */
        {0x7F,0x49,0x49,0x49,0x36}, /* 0x42 B */
        {0x3E,0x41,0x41,0x41,0x22}, /* 0x43 C */
        {0x7F,0x41,0x41,0x22,0x1C}, /* 0x44 D */
        {0x7F,0x49,0x49,0x49,0x41}, /* 0x45 E */
        {0x7F,0x09,0x09,0x09,0x01}, /* 0x46 F */
        {0x3E,0x41,0x49,0x49,0x7A}, /* 0x47 G */
        {0x7F,0x08,0x08,0x08,0x7F}, /* 0x48 H */
        {0x00,0x41,0x7F,0x41,0x00}, /* 0x49 I */
        {0x20,0x40,0x41,0x3F,0x01}, /* 0x4A J */
        {0x7F,0x08,0x14,0x22,0x41}, /* 0x4B K */
        {0x7F,0x40,0x40,0x40,0x40}, /* 0x4C L */
        {0x7F,0x02,0x04,0x02,0x7F}, /* 0x4D M */
        {0x7F,0x04,0x08,0x10,0x7F}, /* 0x4E N */
        {0x3E,0x41,0x41,0x41,0x3E}, /* 0x4F O */
        {0x7F,0x09,0x09,0x09,0x06}, /* 0x50 P */
        {0x3E,0x41,0x51,0x21,0x5E}, /* 0x51 Q */
        {0x7F,0x09,0x19,0x29,0x46}, /* 0x52 R */
        {0x46,0x49,0x49,0x49,0x31}, /* 0x53 S */
        {0x01,0x01,0x7F,0x01,0x01}, /* 0x54 T */
        {0x3F,0x40,0x40,0x40,0x3F}, /* 0x55 U */
        {0x1F,0x20,0x40,0x20,0x1F}, /* 0x56 V */
        {0x3F,0x40,0x38,0x40,0x3F}, /* 0x57 W */
        {0x63,0x14,0x08,0x14,0x63}, /* 0x58 X */
        {0x07,0x08,0x70,0x08,0x07}, /* 0x59 Y */
        {0x61,0x51,0x49,0x45,0x43}, /* 0x5A Z */
        {0x00,0x7F,0x41,0x41,0x00}, /* 0x5B [ */
        {0x02,0x04,0x08,0x10,0x20}, /* 0x5C \ */
        {0x00,0x41,0x41,0x7F,0x00}, /* 0x5D ] */
        {0x04,0x02,0x01,0x02,0x04}, /* 0x5E ^ */
        {0x40,0x40,0x40,0x40,0x40}, /* 0x5F _ */
        {0x00,0x01,0x02,0x04,0x00}, /* 0x60 ` */
        {0x20,0x54,0x54,0x54,0x78}, /* 0x61 a */
        {0x7F,0x48,0x44,0x44,0x38}, /* 0x62 b */
        {0x38,0x44,0x44,0x44,0x20}, /* 0x63 c */
        {0x38,0x44,0x44,0x48,0x7F}, /* 0x64 d */
        {0x38,0x54,0x54,0x54,0x18}, /* 0x65 e */
        {0x08,0x7E,0x09,0x01,0x02}, /* 0x66 f */
        {0x0C,0x52,0x52,0x52,0x3E}, /* 0x67 g */
        {0x7F,0x08,0x04,0x04,0x78}, /* 0x68 h */
        {0x00,0x44,0x7D,0x40,0x00}, /* 0x69 i */
        {0x20,0x40,0x44,0x3D,0x00}, /* 0x6A j */
        {0x7F,0x10,0x28,0x44,0x00}, /* 0x6B k */
        {0x00,0x41,0x7F,0x40,0x00}, /* 0x6C l */
        {0x7C,0x04,0x18,0x04,0x78}, /* 0x6D m */
        {0x7C,0x08,0x04,0x04,0x78}, /* 0x6E n */
        {0x38,0x44,0x44,0x44,0x38}, /* 0x6F o */
        {0x7C,0x14,0x14,0x14,0x08}, /* 0x70 p */
        {0x08,0x14,0x14,0x18,0x7C}, /* 0x71 q */
        {0x7C,0x08,0x04,0x04,0x08}, /* 0x72 r */
        {0x48,0x54,0x54,0x54,0x20}, /* 0x73 s */
        {0x04,0x3F,0x44,0x40,0x20}, /* 0x74 t */
        {0x3C,0x40,0x40,0x20,0x7C}, /* 0x75 u */
        {0x1C,0x20,0x40,0x20,0x1C}, /* 0x76 v */
        {0x3C,0x40,0x30,0x40,0x3C}, /* 0x77 w */
        {0x44,0x28,0x10,0x28,0x44}, /* 0x78 x */
        {0x0C,0x50,0x50,0x50,0x3C}, /* 0x79 y */
        {0x44,0x64,0x54,0x4C,0x44}, /* 0x7A z */
        {0x00,0x08,0x36,0x41,0x00}, /* 0x7B { */
        {0x00,0x00,0x7F,0x00,0x00}, /* 0x7C | */
        {0x00,0x41,0x36,0x08,0x00}, /* 0x7D } */
        {0x10,0x08,0x08,0x10,0x08}, /* 0x7E ~ */
};

#endif

CMakeLists.txt

cmake_minimum_required(VERSION 3.13)
include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake)

project(pico_lcd C CXX ASM)
set(CMAKE_C_STANDARD 11)
pico_sdk_init()

add_executable(pico_lcd
        src/main.cpp
        src/st7735s_pico_80_160_lcd.cpp
)

target_link_libraries(pico_lcd
        pico_stdlib
        hardware_spi
        hardware_exception
)

pico_enable_stdio_usb(pico_lcd 1)
pico_enable_stdio_uart(pico_lcd 0)
pico_add_extra_outputs(pico_lcd)   # 生成 .uf2

.gitignore

cmake-build-debug
# 第一步:忽略 .idea 目录下的所有文件/子目录
.idea/*
!.idea/encodings.xml
!.idea/

copy_uf2.bat

@echo off
set "src=D:\workspace\gitee\0\ming_picoman\cmake-build-debug\pico_lcd.uf2"
set "dst=F:"

if not exist "%src%" (
    echo Error: UF2 file not found!
    pause
    exit 1
)
if not exist "%dst%" (
    echo Error: USB drive %dst% not found!
    pause
    exit 1
)

copy /Y "%src%" %dst%
if %errorlevel% equ 0 (
    echo Success! Pico is rebooting...
) else (
    echo Failed! Reconnect Pico and try again.
)
pause

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐