瑞芯微RK3568適配1.8英寸ST7735S SPI屏幕教程
在工業(yè) HMI、便攜檢測等場景中,“小屏大作”已成為剛需。傳統(tǒng)方案往往存在性能不足或擴(kuò)展復(fù)雜的問題,而飛凌嵌入式 OK3568-C 開發(fā)板(搭載 RK3568 四核 A55 2.0GHz 處理器)憑借原生 3 路 SPI、84 路 GPIO 及開源 Linux 5.10 SDK,讓“點(diǎn)亮一塊 SPI 屏幕”如同“喝杯咖啡般輕松便捷”。本文以 1.8 英寸 ST7735S 彩屏為例,手把手帶您從 0 到 1 完成適配,全程僅需 15 分鐘。
一、OK3568-C 開發(fā)板亮點(diǎn)速覽
二、硬件基礎(chǔ)信息
1、屏幕參數(shù)
- 驅(qū)動芯片:ST7735S
- 分辨率:128×160,支持 26 萬色、65K 色(16-bit RGB565 格式)
- 接口類型:4 線 SPI(包含 CS/DC/RES/SCL/SDA 引腳),背光 BL 獨(dú)立控制
- 工作電壓:3.3V(VCC引腳,不可接5V)
- 通信速率:最高支持 50MHz SPI 時(shí)鐘
圖1:1.8英寸ST7735S RGB TFT LCD屏幕接口引腳定義
2、硬件連接方案
屏幕引腳與 OK3568 的連接關(guān)系需嚴(yán)格對應(yīng),確保 SPI 通信與 GPIO 控制正常,連接表如下:
| 屏幕引腳 | 連接目標(biāo)(OK3568) | 功能說明 | 注意事項(xiàng) |
|---|---|---|---|
| VCC | 3.3V 電源 | 為屏幕提供工作電壓 | 必須接3.3V,不可接5V,避免燒毀屏幕 |
| GND | GND | 電源共地,確保電壓穩(wěn)定性 | 必須可靠接地,否則可能出現(xiàn)顯示異常 |
| BL | 3.3V 電源 | 屏幕背光控制 | 軟件未配置時(shí)直接接3.3V實(shí)現(xiàn)背光常亮 |
| CS | spi0_cs0 | SPI0 片選0引腳 | 低電平時(shí)選中當(dāng)前SPI從設(shè)備 |
| DC | GPIO3_A2 | 數(shù)據(jù)/命令控制引腳 | 高電平傳輸數(shù)據(jù),低電平傳輸命令 |
| RES | GPIO3_B3 | 屏幕復(fù)位引腳 | 上電后需拉低復(fù)位,復(fù)位完成后拉高 |
| SCL | spi0_clk | SPI0 時(shí)鐘引腳 | 提供SPI同步通信時(shí)鐘,最高50MHz |
| SDA | spi0_mosi | SPI0 主發(fā)從收引腳 | 傳輸SPI命令與顯示數(shù)據(jù) |
- 接線前必須斷開 OK3568 開發(fā)板電源,嚴(yán)禁帶電接線!
- 接線完成后需反復(fù)核對引腳對應(yīng)關(guān)系,確認(rèn)無誤后再上電
- VCC引腳務(wù)必接3.3V,接5V會直接燒毀ST7735S芯片
- 所有GND引腳需可靠連接,避免出現(xiàn)供電不穩(wěn)導(dǎo)致的顯示異常
三、設(shè)備樹配置
設(shè)備樹用于向內(nèi)核描述 SPI0 與屏幕的硬件資源,需在 OK3568 設(shè)備樹中添加以下配置:
pinctrl-names = "default", "high_speed";
pinctrl-0 = <&spi0m1_cs0 &spi0m1_pins>;
pinctrl-1 = <&spi0m1_cs0 &spi0m1_pins_hs>;
status = "okay";
spi@0 {
compatible = "sitronix,st7735r";
reg = <0>;
dc-gpios = <&gpio3 RK_PA2 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_HIGH>;
spi-max-frequency = <50000000>;
rotation = <0>;
};
}
- compatible:必須設(shè)置為 "sitronix,st7735r",與內(nèi)核驅(qū)動的兼容性字段匹配,ST7735S兼容ST7735R驅(qū)動
- dc-gpios/reset-gpios:RK_PA2對應(yīng)硬件連接的GPIO3_A2,RK_PB3對應(yīng)GPIO3_B3,需與實(shí)際接線一致
- spi-max-frequency:設(shè)置為50000000(50MHz),不可超過ST7735S支持的最大速率
- rotation:可根據(jù)實(shí)際需求設(shè)置旋轉(zhuǎn)角度,支持0°、90°、180°、270°四個(gè)方向
- bgr:若屏幕顯示顏色異常(如紅色變藍(lán)色),可添加或刪除該屬性調(diào)整顏色格式
四、內(nèi)核驅(qū)動配置與開發(fā)
需開啟內(nèi)核 Framebuffer 相關(guān)配置,并添加 ST7735S 驅(qū)動代碼,實(shí)現(xiàn)屏幕初始化與顯示控制。推薦使用內(nèi)核自帶的 FB_TFT 框架,無需從零開發(fā)驅(qū)動。
1、內(nèi)核配置使能
通過make menuconfig進(jìn)入內(nèi)核配置界面,開啟以下選項(xiàng)(路徑:Device Drivers → Graphics support → Frame buffer Devices):
- CONFIG_FB_TFT=y:使能 FB_TFT 框架(基礎(chǔ)顯示框架,必須開啟)
- CONFIG_FB_TFT_ST7735R=y:使能 ST7735R 驅(qū)動(兼容 ST7735S,必須開啟)
- CONFIG_DRM_TINYDRM=y:使能 TinyDRM 框架(可選,用于DRM顯示架構(gòu))
- CONFIG_TINYDRM_ST7735R=y:使能 TinyDRM 下的 ST7735R 驅(qū)動(可選)
- 配置完成后需保存配置文件(.config),避免下次編譯丟失配置
- 重新編譯內(nèi)核與設(shè)備樹:make -j$(nproc) zImage dtbs modules(根據(jù)CPU核心數(shù)調(diào)整-j參數(shù))
- 編譯完成后生成的內(nèi)核鏡像在arch/arm64/boot/zImage,設(shè)備樹在arch/arm64/boot/dts/rockchip/目錄下
- 需將新編譯的內(nèi)核鏡像、設(shè)備樹文件燒錄到開發(fā)板,確保配置生效
2、完整驅(qū)動代碼(fb_st7735r.c)
以下是基于 Framebuffer 框架的 ST7735S 完整驅(qū)動代碼,可直接放入內(nèi)核源碼目錄drivers/video/fbdev/fbtft/下,或使用內(nèi)核自帶驅(qū)動(Linux 5.10 已內(nèi)置該驅(qū)動):
/*
* FB driver for the ST7735R LCD Controller
*
* Copyright (C) 2013 Noralf Tronnes
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <video/mipi_display.h>
#include "fbtft.h"
#define DRVNAME "fb_st7735r"
#define DEFAULT_GAMMA "0F 1A 0F 18 2F 28 20 22 1F 1B 23 37 00 07 02 10\n" \
"0F 1B 0F 17 33 2C 29 2E 30 30 39 3F 00 07 03 10"
static const s16 default_init_sequence[] = {
-1, MIPI_DCS_SOFT_RESET, // 發(fā)送軟復(fù)位命令
-2, 10, // 延遲 10 毫秒
-1, MIPI_DCS_EXIT_SLEEP_MODE, // 退出睡眠模式
-2, 120, // 延遲 120 毫秒
-1, 0x11, // 發(fā)送命令 0x11
-2, 120, // 延遲 120 毫秒
-1, 0xB1, 0x01, 0x2C, 0x2D, // 設(shè)置幀率控制參數(shù)
-1, 0xB2, 0x01, 0x2C, 0x2D, // 設(shè)置空閑模式幀率控制參數(shù)
-1, 0xB3, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D, // 設(shè)置部分模式幀率控制
-1, 0xB4, 0x07, // 設(shè)置反轉(zhuǎn)模式為“無反轉(zhuǎn)”
-1, 0xC0, 0xA2, 0x02, 0x84, // 設(shè)置電源控制參數(shù)
-1, 0xC1, 0xC5, // 設(shè)置 VGH25、VGSEL 等電源控制參數(shù)
-1, 0xC2, 0x0A, 0x00, // 設(shè)置電源控制參數(shù)
-1, 0xC3, 0x8A, 0x2A, // 設(shè)置電源控制參數(shù)
-1, 0xC4, 0x8A, 0xEE, // 設(shè)置電源控制參數(shù)
-1, 0xC5, 0x0E, // 設(shè)置電源控制參數(shù)
-1, 0x36, 0xC0, // 設(shè)置顯示方向
-1, 0xE0, 0x0F, 0x1A, 0x0F, 0x18, 0x2F, 0x28, 0x20, 0x22, 0x1F, 0x1B, 0x23, 0x37, 0x00, 0x07, 0x02, 0x10, // 設(shè)置 Gamma 調(diào)整
-1, 0xE1, 0x0F, 0x1B, 0x0F, 0x17, 0x33, 0x2C, 0x29, 0x2E, 0x30, 0x30, 0x39, 0x3F, 0x00, 0x07, 0x03, 0x10, // 設(shè)置 Gamma 調(diào)整
-1, 0x2A, 0x00, 0x02, 0x00, 0x82, // 設(shè)置列地址范圍
-1, 0x2B, 0x00, 0x03, 0x00, 0x83, // 設(shè)置行地址范圍
-1, 0xF0, 0x01, // 設(shè)置一些特殊參數(shù)
-1, 0xF6, 0x00, // 設(shè)置一些特殊參數(shù)
-1, 0x2A, 0x00, 0x02, 0x00, 0x82, // 設(shè)置列地址范圍
-1, 0x2B, 0x00, 0x01, 0x00, 0xa1, // 設(shè)置行地址范圍
-1, 0x3A, 0x05, // 設(shè)置像素格式
-1, 0x29, // 打開顯示
-3 // 結(jié)束標(biāo)記
};
static void set_addr_win(struct fbtft_par *par, int xs, int ys, int xe, int ye)
{
printk("set_addr_win:%d,%d,%d,%d\r\n",xs,ys,xe,ye);
xs=2;xe=127+2;ys=1;ye=159+1;
write_reg(par, MIPI_DCS_SET_COLUMN_ADDRESS,
xs >> 8, xs & 0xFF, xe >> 8, xe & 0xFF);
write_reg(par, MIPI_DCS_SET_PAGE_ADDRESS,
ys >> 8, ys & 0xFF, ye >> 8, ye & 0xFF);
write_reg(par, MIPI_DCS_WRITE_MEMORY_START);
}
#define MY BIT(7)
#define MX BIT(6)
#define MV BIT(5)
static int set_var(struct fbtft_par *par)
{
/* MADCTL - Memory data access control
* RGB/BGR:
* 1. Mode selection pin SRGB
* RGB H/W pin for color filter setting: 0=RGB, 1=BGR
* 2. MADCTL RGB bit
* RGB-BGR ORDER color filter panel: 0=RGB, 1=BGR
*/
switch (par->info->var.rotate) {
case 0:
write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
MX | MY | (par->bgr << 3));
break;
case 270:
write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
MY | MV | (par->bgr << 3));
break;
case 180:
write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
par->bgr << 3);
break;
case 90:
write_reg(par, MIPI_DCS_SET_ADDRESS_MODE,
MX | MV | (par->bgr << 3));
break;
}
return 0;
}
/*
* Gamma string format:
* VRF0P VOS0P PK0P PK1P PK2P PK3P PK4P PK5P PK6P PK7P PK8P PK9P SELV0P SELV1P SELV62P SELV63P
* VRF0N VOS0N PK0N PK1N PK2N PK3N PK4N PK5N PK6N PK7N PK8N PK9N SELV0N SELV1N SELV62N SELV63N
*/
#define CURVE(num, idx) curves[(num) * par->gamma.num_values + (idx)]
static int set_gamma(struct fbtft_par *par, u32 *curves)
{
int i, j;
/* apply mask */
for (i = 0; i < par->gamma.num_curves; i++)
for (j = 0; j < par->gamma.num_values; j++)
CURVE(i, j) &= 0x3f;
for (i = 0; i < par->gamma.num_curves; i++)
write_reg(par, 0xE0 + i,
CURVE(i, 0), CURVE(i, 1),
CURVE(i, 2), CURVE(i, 3),
CURVE(i, 4), CURVE(i, 5),
CURVE(i, 6), CURVE(i, 7),
CURVE(i, 8), CURVE(i, 9),
CURVE(i, 10), CURVE(i, 11),
CURVE(i, 12), CURVE(i, 13),
CURVE(i, 14), CURVE(i, 15));
return 0;
}
#undef CURVE
static struct fbtft_display display = {
.regwidth = 8,
.buswidth = 8,
.width = 128,
.height = 160,
.bpp = 16,
.init_sequence = default_init_sequence,
.gamma_num = 2,
.gamma_len = 16,
.gamma = DEFAULT_GAMMA,
.fbtftops = {
.set_addr_win = set_addr_win,
.set_var = set_var,
.set_gamma = set_gamma,
},
};
FBTFT_REGISTER_DRIVER(DRVNAME, "sitronix,st7735r", &display);
MODULE_ALIAS("spi:" DRVNAME);
MODULE_ALIAS("platform:" DRVNAME);
MODULE_ALIAS("spi:st7735r");
MODULE_ALIAS("platform:st7735r");
MODULE_DESCRIPTION("FB driver for the ST7735R LCD Controller");
MODULE_AUTHOR("Noralf Tronnes");
MODULE_LICENSE("GPL");
- 該驅(qū)動基于內(nèi)核 FB_TFT 框架開發(fā),無需修改內(nèi)核核心代碼,只需編譯進(jìn)內(nèi)核即可
- 默認(rèn)支持 128×160 分辨率,16-bit RGB565 顏色格式,最高 50MHz SPI 速率
- 包含完整的屏幕初始化命令序列,針對 ST7735S 進(jìn)行了優(yōu)化適配
- 支持 0°/90°/180°/270° 屏幕旋轉(zhuǎn),可通過設(shè)備樹 rotation 屬性配置
- 包含 Gamma 校準(zhǔn)功能,可通過內(nèi)核參數(shù)調(diào)整顯示色彩效果
- 自動處理 ST7735S 的像素偏移問題,確保顯示區(qū)域準(zhǔn)確
3、應(yīng)用層測試程序(test2.c)
用于驗(yàn)證屏幕顯示功能,通過操作 Framebuffer 設(shè)備填充指定顏色。
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <string.h>
#include <stdint.h>
int main(int argc, char *argv[]) {
char *endptr;
uint16_t color = 0xFFFF; // Default color (white)
long int num = strtol(argv[1], &endptr, 10); // Number of rows to fill
// Check if arguments are passed correctly
if (argc < 3) {
printf("Usage: %s <num_rows> <color>\n", argv[0]);
return 1;
}
// Parse color based on argv[2]
if (strcmp(argv[2], "red") == 0) {
color = 0xF800; // Red: 11111 000000 00000
} else if (strcmp(argv[2], "green") == 0) {
color = 0x07E0; // Green: 00000 111111 00000
} else if (strcmp(argv[2], "blue") == 0) {
color = 0x001F; // Blue: 00000 000000 11111
} else if (strcmp(argv[2], "white") == 0) {
color = 0xFFFF; // White: 111111 111111 11111
} else if (strcmp(argv[2], "black") == 0) {
color = 0x0000; // Black: 00000 000000 00000
} else {
printf("Unknown color: %s. Defaulting to white.\n", argv[2]);
}
int fb = open("/dev/fb0", O_RDWR);
if (fb == -1) {
perror("Error opening framebuffer device");
return 1;
}
// 獲取屏幕的屬性
struct fb_var_screeninfo vinfo;
if (ioctl(fb, FBIOGET_VSCREENINFO, &vinfo)) {
perror("Error reading variable information");
close(fb);
return 1;
}
int width = vinfo.xres;
int height = vinfo.yres;
int bpp = vinfo.bits_per_pixel; // 每像素的字節(jié)數(shù)
printf("Screen resolution: %dx%d\n", width, height);
printf("Color depth: %d bpp\n", bpp);
// 映射幀緩沖內(nèi)存
size_t framebuffer_size = width * height * 2;
uint16_t *framebuffer = mmap(NULL, framebuffer_size, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0);
if (framebuffer == MAP_FAILED) {
perror("Error mapping framebuffer memory");
close(fb);
return 1;
}
// 填充背景顏色
for (int y = 0; y < num; y++) {
framebuffer[y] = color;
}
// 取消映射并關(guān)閉文件
munmap(framebuffer, framebuffer_size);
close(fb);
return 0;
}
五、編譯與燒錄
完成設(shè)備樹配置和驅(qū)動開發(fā)后,需要編譯內(nèi)核、設(shè)備樹,并燒錄到 OK3568 開發(fā)板中。
1、編譯步驟
-
設(shè)置交叉編譯工具鏈:
export ARCH=arm64 export CROSS_COMPILE=aarch64-linux-gnu- export PATH=$PATH:/path/to/toolchain/bin
-
編譯內(nèi)核鏡像:
make -j$(nproc) zImage
-
編譯設(shè)備樹:
make -j$(nproc) dtbs
-
編譯內(nèi)核模塊(若驅(qū)動配置為模塊):
make -j$(nproc) modules
-
安裝模塊(可選):
make modules_install INSTALL_MOD_PATH=./modules
2、燒錄方法
推薦使用 TF 卡燒錄或 USB 燒錄工具(如 RKDevTool),以下以 TF 卡燒錄為例:
- 將編譯生成的 zImage(內(nèi)核鏡像)拷貝到 TF 卡的 boot 分區(qū)
- 將編譯生成的設(shè)備樹文件(如 ok3568.dtb)拷貝到 TF 卡的 boot 分區(qū)
- 將開發(fā)板設(shè)置為 TF 卡啟動模式,插入 TF 卡后上電
- 系統(tǒng)啟動后,內(nèi)核會自動加載 ST7735S 驅(qū)動,識別屏幕設(shè)備
- 燒錄前請備份開發(fā)板原有系統(tǒng),避免數(shù)據(jù)丟失
- 確保交叉編譯工具鏈版本與內(nèi)核版本匹配(推薦使用 Linaro 2021.07 及以上版本)
- 設(shè)備樹文件名需與開發(fā)板啟動腳本中指定的文件名一致
- 若使用模塊方式加載驅(qū)動,需在系統(tǒng)啟動后執(zhí)行insmod fb_st7735r.ko加載驅(qū)動
六、測試驗(yàn)證
系統(tǒng)啟動后,可通過以下方法驗(yàn)證屏幕是否正常工作:
1、基礎(chǔ)驗(yàn)證
- 查看 Framebuffer 設(shè)備:ls /dev/fb*,若出現(xiàn)/dev/fb1(或其他fb設(shè)備號),說明驅(qū)動加載成功
- 查看設(shè)備樹匹配信息:dmesg | grep st7735,若輸出 "st7735r spi0.0: registered" 等信息,說明設(shè)備樹匹配成功
- 查看 SPI 總線信息:dmesg | grep spi,確認(rèn) SPI0 總線已正常初始化
2、顯示測試
使用以下命令測試屏幕顯示功能:
-
填充純色顯示(紅色):
[root@ok3568:/]# /root/test2 10240 red //填充的像素總數(shù)
-
執(zhí)行命令后,終端將顯示:
Screen resolution:128x160
Color depth:16 bpp
- 屏幕將顯示一半像素為紅色,驗(yàn)證顯示功能正常。
七、常見問題排查
- 檢查 VCC 引腳是否接 3.3V,GND 是否可靠接地
- 檢查 BL 引腳是否接 3.3V,或軟件是否配置了背光控制
- 檢查 SPI0 總線是否正常初始化(dmesg | grep spi0)
- 檢查設(shè)備樹中 spi0 的 status 是否設(shè)置為 "okay"
- 檢查 SPI 引腳接線是否正確(SCL、SDA、CS 引腳)
- 降低 SPI 通信速率(將 spi-max-frequency 改為 10MHz 測試)
- 檢查 DC 引腳和 RES 引腳接線是否正確
- 確認(rèn)驅(qū)動中的像素偏移配置是否正確
- 檢查設(shè)備樹中是否添加了 bgr 屬性(根據(jù)屏幕實(shí)際需求調(diào)整)
- 調(diào)整 Gamma 校準(zhǔn)參數(shù),優(yōu)化顯示色彩
- 確認(rèn)像素格式配置是否為 RGB565(0x3A 命令參數(shù)為 0x05)
- 檢查電源電壓是否穩(wěn)定,是否存在紋波干擾
- 檢查設(shè)備樹 compatible 屬性是否為 "sitronix,st7735r"
- 確認(rèn)內(nèi)核已開啟 CONFIG_FB_TFT 和 CONFIG_FB_TFT_ST7735R 配置
- 查看 dmesg 日志,分析驅(qū)動加載失敗原因(dmesg | grep -i error)
- 檢查 GPIO 引腳是否被其他設(shè)備占用
八、總結(jié)
本文詳細(xì)介紹了 OK3568 開發(fā)板適配 1.8 英寸 ST7735S SPI 屏幕的完整流程,包括硬件連接、設(shè)備樹配置、內(nèi)核驅(qū)動開發(fā)、編譯燒錄和測試驗(yàn)證等環(huán)節(jié)。通過本文的教程,您可以快速實(shí)現(xiàn) ST7735S 屏幕的點(diǎn)亮與顯示控制。
關(guān)鍵要點(diǎn)總結(jié):
- 硬件連接需嚴(yán)格按照引腳對應(yīng)關(guān)系,特別注意 VCC 接 3.3V,避免燒毀屏幕
- 設(shè)備樹配置需確保 compatible 屬性、GPIO 引腳定義、SPI 速率等參數(shù)正確
- 驅(qū)動基于 FB_TFT 框架開發(fā),無需從零開發(fā),可直接使用內(nèi)核自帶驅(qū)動或本文提供的優(yōu)化版本
- 測試驗(yàn)證時(shí),先通過基礎(chǔ)命令確認(rèn)驅(qū)動加載和設(shè)備識別,再進(jìn)行顯示功能測試
- 遇到問題時(shí),善用 dmesg 日志定位問題,提高排查效率
通過本教程的適配方案,您可以在 OK3568 開發(fā)板上快速集成 ST7735S 屏幕,為工業(yè)控制、便攜設(shè)備等場景提供低成本的顯示解決方案。如需進(jìn)一步擴(kuò)展功能(如觸摸控制、背光調(diào)節(jié)等),可在此基礎(chǔ)上進(jìn)行二次開發(fā)。
相關(guān)產(chǎn)品 >
-
FET3568-C核心板
RK3568性能強(qiáng)而穩(wěn) 國產(chǎn)芯|飛凌嵌入式RK3568系列核心板,采用瑞芯微國產(chǎn)高性能AI處理器RK3568設(shè)計(jì)生產(chǎn),RK3568兼具CPU、GPU、NPU、VPU于一身,RK3568 性能、性價(jià)比在同類產(chǎn)品中具有較高優(yōu)勢,RK3568處理器是一款定位中高端的通用型SoC, 飛凌RK3568核心板主要面向工業(yè)互聯(lián)網(wǎng)、HMI、NVR存儲、車載中控、工業(yè)網(wǎng)關(guān)等領(lǐng)域。目前RK3568系列已經(jīng)批量穩(wěn)定出貨
了解詳情
-
OK3568-C開發(fā)板
強(qiáng)而穩(wěn),國產(chǎn)芯,1Tops算力,多路高速接口|飛凌RK3568系列RK3568開發(fā)板基于國產(chǎn)工業(yè)級AI處理器RK3568四核64位Cortex-A55 處理器設(shè)計(jì)。RK3568作為國產(chǎn)化高性能處理器,瑞芯微RK3568芯片是一款定位中高端的通用型SoC,瑞芯微RK3568芯片是一款定位中高端的通用型SoC,NPU達(dá)到1Tops,飛凌RK3568系列核心板提供瑞芯微RK3568規(guī)格書_datasheet_數(shù)據(jù)手冊_原理圖等,
了解詳情


