The Raspberry Pi A1 is implemented on the Dietpi system using ST7735 as the system screen

Arduino_related_projects/树莓派系列/树莓派A1用ST7735当系统的显示屏.txt at master · mzymcm/Arduino_related_projects

树莓派A1 用 ST7735 128*128屏 当系统的显示屏 创建用户空间SPI framebuffer驱动
我们使用SPI0引脚连接:
SCLK → GPIO11 (BCM)
MOSI → GPIO10 (BCM)
DC → GPIO25 (BCM) (数据/命令选择)
CS → GPIO8 (BCM) (片选,低电平有效)
RST → GPIO27 (BCM) (复位,低电平复位)
BL → GPIO24 (BCM) (背光,高电平点亮)

  1. 安装必要的依赖
    bash

安装bcm2835库

apt-get update
apt-get install -y libbcm2835-dev build-essential

如果bcm2835库不可用,可以使用wiringPi或pigpio 如果上面的安装正常,这里不用安装。

apt-get install -y wiringpi pigpio

安装framebuffer工具

apt-get install -y fbset fbterm con2fbmap

  1. 创建用户空间framebuffer驱动
    创建 st7735_fb.c:

####=========    st7735_fb.c  begin =========####

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <bcm2835.h>
#include <time.h>

// 屏幕尺寸
#define WIDTH 128
#define HEIGHT 128
#define BPP 16  // RGB565

// 颜色定义 (RGB565)
#define BLACK     0x0000
#define WHITE     0xFFFF
#define RED       0xF800
#define GREEN     0x07E0
#define BLUE      0x001F

// 引脚定义
#define DC_PIN      RPI_V2_GPIO_P1_22  // GPIO25
#define RST_PIN     RPI_V2_GPIO_P1_13  // GPIO27
#define BL_PIN      RPI_V2_GPIO_P1_18  // GPIO24
#define CS_PIN      RPI_V2_GPIO_P1_24  // GPIO8

// 全局变量
static int fb_fd = -1;
static struct fb_var_screeninfo vinfo;
static struct fb_fix_screeninfo finfo;
static char *fb_buffer = NULL;
static long screensize = 0;

// ST7735命令
#define ST7735_NOP     0x00
#define ST7735_SWRESET 0x01
#define ST7735_SLPOUT  0x11
#define ST7735_DISPON  0x29
#define ST7735_CASET   0x2A
#define ST7735_RASET   0x2B
#define ST7735_RAMWR   0x2C
#define ST7735_COLMOD  0x3A
#define ST7735_MADCTL  0x36

// 写命令到ST7735
void write_command(uint8_t cmd) {
bcm2835_gpio_write(DC_PIN, LOW);
bcm2835_spi_transfer(cmd);
}

// 写数据到ST7735
void write_data(uint8_t data) {
bcm2835_gpio_write(DC_PIN, HIGH);
bcm2835_spi_transfer(data);
}

// 写16位数据到ST7735
void write_data16(uint16_t data) {
bcm2835_gpio_write(DC_PIN, HIGH);
bcm2835_spi_transfer(data >> 8);
bcm2835_spi_transfer(data & 0xFF);
}

// 设置显示窗口
void set_address_window(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1) {
write_command(ST7735_CASET);
write_data(0x00);
write_data(x0 + 2);  // 列起始偏移
write_data(0x00);
write_data(x1 + 2);  // 列结束


write_command(ST7735_RASET);
write_data(0x00);
write_data(y0 + 3);  // 行起始偏移
write_data(0x00);
write_data(y1 + 3);  // 行结束

write_command(ST7735_RAMWR);

}

// 初始化ST7735
void st7735_init(void) {
printf(“Initializing ST7735…
Skip to last reply
Skip to top
Skip to main content
DietPi Community Forum
The Raspberry Pi A1 is implemented on the Dietpi system using ST7735 as the system screen
General Discussion

    DietPi.com
    Download
    Docs
    Blog
    GitHub
    Donate

The Raspberry Pi A1 is implemented on the Dietpi system using ST7735 as the system screen
General Discussion
16 Dec
11h
post by mzy 12 hours ago
wave

It’s been a while since we’ve seen mzy — their last post was 12 months ago.
mzy
12h

Arduino_related_projects/树莓派系列/树莓派A1用ST7735当系统的显示屏.txt at master · mzymcm/Arduino_related_projects

树莓派A1 用 ST7735 128*128屏 当系统的显示屏 创建用户空间SPI framebuffer驱动
我们使用SPI0引脚连接:
SCLK → GPIO11 (BCM)
MOSI → GPIO10 (BCM)
DC → GPIO25 (BCM) (数据/命令选择)
CS → GPIO8 (BCM) (片选,低电平有效)
RST → GPIO27 (BCM) (复位,低电平复位)
BL → GPIO24 (BCM) (背光,高电平点亮)

    安装必要的依赖
    bash

安装bcm2835库

apt-get update
apt-get install -y libbcm2835-dev build-essential
如果bcm2835库不可用,可以使用wiringPi或pigpio 如果上面的安装正常,这里不用安装。

apt-get install -y wiringpi pigpio
安装framebuffer工具

apt-get install -y fbset fbterm con2fbmap

    创建用户空间framebuffer驱动
    创建 st7735_fb.c:

####========= st7735_fb.c begin =========####

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <bcm2835.h>
#include <time.h>

// 屏幕尺寸
#define WIDTH 128
#define HEIGHT 128
#define BPP 16 // RGB565

// 颜色定义 (RGB565)
#define BLACK 0x0000
#define WHITE 0xFFFF
#define RED 0xF800
#define GREEN 0x07E0
#define BLUE 0x001F

// 引脚定义
#define DC_PIN RPI_V2_GPIO_P1_22 // GPIO25
#define RST_PIN RPI_V2_GPIO_P1_13 // GPIO27
#define BL_PIN RPI_V2_GPIO_P1_18 // GPIO24
#define CS_PIN RPI_V2_GPIO_P1_24 // GPIO8

// 全局变量
static int fb_fd = -1;
static struct fb_var_screeninfo vinfo;
static struct fb_fix_screeninfo finfo;
static char *fb_buffer = NULL;
static long screensize = 0;

// ST7735命令
#define ST7735_NOP 0x00
#define ST7735_SWRESET 0x01
#define ST7735_SLPOUT 0x11
#define ST7735_DISPON 0x29
#define ST7735_CASET 0x2A
#define ST7735_RASET 0x2B
#define ST7735_RAMWR 0x2C
#define ST7735_COLMOD 0x3A
#define ST7735_MADCTL 0x36

// 写命令到ST7735
void write_command(uint8_t cmd) {
bcm2835_gpio_write(DC_PIN, LOW);
bcm2835_spi_transfer(cmd);
}

// 写数据到ST7735
void write_data(uint8_t data) {
bcm2835_gpio_write(DC_PIN, HIGH);
bcm2835_spi_transfer(data);
}

// 写16位数据到ST7735
void write_data16(uint16_t data) {
bcm2835_gpio_write(DC_PIN, HIGH);
bcm2835_spi_transfer(data >> 8);
bcm2835_spi_transfer(data & 0xFF);
}

// 设置显示窗口
void set_address_window(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1) {
write_command(ST7735_CASET);
write_data(0x00);
write_data(x0 + 2); // 列起始偏移
write_data(0x00);
write_data(x1 + 2); // 列结束

write_command(ST7735_RASET);
write_data(0x00);
write_data(y0 + 3);  // 行起始偏移
write_data(0x00);
write_data(y1 + 3);  // 行结束

write_command(ST7735_RAMWR);

}

// 初始化ST7735
void st7735_init(void) {
printf(“Initializing ST7735…\n”);

// 初始化GPIO
bcm2835_gpio_fsel(DC_PIN, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel(RST_PIN, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel(BL_PIN, BCM2835_GPIO_FSEL_OUTP);

// 初始化SPI
bcm2835_spi_begin();
bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);
bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);
bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_64);
bcm2835_spi_chipSelect(BCM2835_SPI_CS0);
bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);

// 硬件复位
bcm2835_gpio_write(RST_PIN, HIGH);
usleep(100000);
bcm2835_gpio_write(RST_PIN, LOW);
usleep(100000);
bcm2835_gpio_write(RST_PIN, HIGH);
usleep(100000);

// 背光开启
bcm2835_gpio_write(BL_PIN, HIGH);

// 软件复位
write_command(ST7735_SWRESET);
usleep(150000);

// 退出睡眠模式
write_command(ST7735_SLPOUT);
usleep(150000);

// 颜色模式:RGB565
write_command(ST7735_COLMOD);
write_data(0x05);

// 内存访问控制
write_command(ST7735_MADCTL);
write_data(0xC0);  // 旋转设置

// 显示开启
write_command(ST7735_DISPON);
usleep(100000);

printf("ST7735 initialized.\n");

}

// 将framebuffer内容刷新到屏幕
void flush_framebuffer() {
set_address_window(0, 0, WIDTH-1, HEIGHT-1);

uint16_t *fb_ptr = (uint16_t*)fb_buffer;

for (int y = 0; y < HEIGHT; y++) {
    for (int x = 0; x < WIDTH; x++) {
        uint16_t color = fb_ptr[y * WIDTH + x];
        write_data16(color);
    }
}

}

// 创建虚拟framebuffer
int create_framebuffer() {
// 创建一个虚拟framebuffer设备
fb_fd = open(“/dev/fb0”, O_RDWR);
if (fb_fd < 0) {
// 尝试创建新的framebuffer
system(“mknod /dev/fb1 c 29 1”);
fb_fd = open(“/dev/fb1”, O_RDWR | O_CREAT, 0666);
if (fb_fd < 0) {
perror(“Failed to open framebuffer”);
return -1;
}
}

// 获取framebuffer信息
if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo)) {
    perror("Error reading fixed information");
    return -2;
}

if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo)) {
    perror("Error reading variable information");
    return -3;
}

// 设置framebuffer参数
vinfo.xres = WIDTH;
vinfo.yres = HEIGHT;
vinfo.xres_virtual = WIDTH;
vinfo.yres_virtual = HEIGHT;
vinfo.bits_per_pixel = BPP;
vinfo.red.offset = 11; vinfo.red.length = 5;
vinfo.green.offset = 5; vinfo.green.length = 6;
vinfo.blue.offset = 0; vinfo.blue.length = 5;

if (ioctl(fb_fd, FBIOPUT_VSCREENINFO, &vinfo)) {
    perror("Error setting variable information");
    return -4;
}

// 重新获取更新后的信息
ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo);

// 计算缓冲区大小
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;

// 映射framebuffer到内存
fb_buffer = (char*)mmap(0, screensize, PROT_READ | PROT_WRITE, 
                       MAP_SHARED, fb_fd, 0);

if ((long)fb_buffer == -1) {
    perror("Failed to mmap framebuffer");
    return -5;
}

printf("Framebuffer created: %dx%d, %d bpp\n", 
       vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);

return 0;

}

// 清理函数
void cleanup() {
if (fb_buffer) munmap(fb_buffer, screensize);
if (fb_fd >= 0) close(fb_fd);
bcm2835_gpio_write(BL_PIN, LOW);
bcm2835_spi_end();
bcm2835_close();
}

// 主函数
int main(int argc, char *argv) {
printf(“ST7735 User-space Framebuffer Driver\n”);

// 初始化bcm2835
if (!bcm2835_init()) {
    printf("Failed to initialize bcm2835\n");
    return 1;
}

// 初始化ST7735
st7735_init();

// 创建framebuffer
if (create_framebuffer() < 0) {
    printf("Failed to create framebuffer\n");
    cleanup();
    return 1;
}

// 清屏
memset(fb_buffer, 0, screensize);
flush_framebuffer();

printf("Driver ready. Press Ctrl+C to exit.\n");

// 主循环:定期刷新framebuffer到屏幕
while (1) {
    flush_framebuffer();
    usleep(16666);  // 约60Hz刷新率
}

cleanup();
return 0;

}

####========= st7735_fb.c end =========####

    编译驱动程序

cd /root/go_run/st7735
gcc -o st7735_fb st7735_fb.c -lbcm2835 -lm

    创建systemd服务
    创建 /etc/systemd/system/st7735-fb.service:

####========= st7735-fb.service begin =========####

[Unit]
Description=ST7735 User-space Framebuffer Driver
After=multi-user.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/root/go_run/st7735/st7735_fb
WorkingDirectory=/root/go_run/st7735
Restart=always
RestartSec=5
User=root
Environment=DISPLAY=:0

[Install]
WantedBy=multi-user.target

####========= st7735-fb.service end =========####

    创建控制台重定向脚本
    创建 /usr/local/bin/console-to-st7735.sh:

####========= console-to-st7735.sh begin =========####

#!/bin/bash
等待驱动程序启动

sleep 5
如果/dev/fb1不存在,创建一个

if [ ! -e “/dev/fb1” ]; then
mknod /dev/fb1 c 29 1
chmod 666 /dev/fb1
fi
设置控制台字体(小字体适合128x128分辨率)

if [ -f “/usr/share/consolefonts/Uni2-Terminus12x6.psf.gz” ]; then
setfont /usr/share/consolefonts/Uni2-Terminus12x6.psf.gz
elif [ -f “/usr/share/consolefonts/ter-112n.psf.gz” ]; then
setfont /usr/share/consolefonts/ter-112n.psf.gz
fi
重定向控制台输出

echo “Redirecting console to ST7735…”
尝试映射控制台到fb1

con2fbmap 1 1 2>/dev/null || true
设置环境变量

export FRAMEBUFFER=/dev/fb1

echo “Console redirected to ST7735”

####========= console-to-st7735.sh begin =========####

    配置系统启动

启用服务

systemctl enable st7735-fb.service
创建启动脚本

echo “/usr/local/bin/console-to-st7735.sh” >> /etc/rc.local
给脚本执行权限

chmod +x /usr/local/bin/console-to-st7735.sh
chmod +x /etc/rc.local

post by Joulinar 11 hours ago
This topic will close 6 months after the last reply.

You will be notified if someone mentions your @name or replies to you.

New & Unread Topics
Topic list, column headers with buttons are sortable.
Topic 	Replies 	Views 	Activity
RPI2 Model B V1.1 no automatic start of LXDE 1
General Discussion
	7 	23 	5h
Unable to clone OS to NVMe 5
Troubleshooting
	6 	13 	20m
Error installing app on Dietpi 
General Discussion
	2 	4 	23m
Radxa Zero 3W can’t boot after update to the latest DietPi 
Troubleshooting
	3 	11 	5h
Rock64 - Cannot Boot from USB After Updating SPI U-Boot (DietPi v9.19.2 Trixie) 
Troubleshooting
	1 	7 	5h
There are 2 unread and 3 new topics remaining, or browse other topics in General Discussion
Powered by Discourse
\n”);


// 初始化GPIO
bcm2835_gpio_fsel(DC_PIN, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel(RST_PIN, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel(BL_PIN, BCM2835_GPIO_FSEL_OUTP);

// 初始化SPI
bcm2835_spi_begin();
bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);
bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);
bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_64);
bcm2835_spi_chipSelect(BCM2835_SPI_CS0);
bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);

// 硬件复位
bcm2835_gpio_write(RST_PIN, HIGH);
usleep(100000);
bcm2835_gpio_write(RST_PIN, LOW);
usleep(100000);
bcm2835_gpio_write(RST_PIN, HIGH);
usleep(100000);

// 背光开启
bcm2835_gpio_write(BL_PIN, HIGH);

// 软件复位
write_command(ST7735_SWRESET);
usleep(150000);

// 退出睡眠模式
write_command(ST7735_SLPOUT);
usleep(150000);

// 颜色模式:RGB565
write_command(ST7735_COLMOD);
write_data(0x05);

// 内存访问控制
write_command(ST7735_MADCTL);
write_data(0xC0);  // 旋转设置

// 显示开启
write_command(ST7735_DISPON);
usleep(100000);

printf("ST7735 initialized.\n");


}

// 将framebuffer内容刷新到屏幕
void flush_framebuffer() {
set_address_window(0, 0, WIDTH-1, HEIGHT-1);

uint16_t *fb_ptr = (uint16_t*)fb_buffer;

for (int y = 0; y < HEIGHT; y++) {
    for (int x = 0; x < WIDTH; x++) {
        uint16_t color = fb_ptr[y * WIDTH + x];
        write_data16(color);
    }
}


}

// 创建虚拟framebuffer
int create_framebuffer() {
// 创建一个虚拟framebuffer设备
fb_fd = open(“/dev/fb0”, O_RDWR);
if (fb_fd < 0) {
// 尝试创建新的framebuffer
system(“mknod /dev/fb1 c 29 1”);
fb_fd = open(“/dev/fb1”, O_RDWR | O_CREAT, 0666);
if (fb_fd < 0) {
perror(“Failed to open framebuffer”);
return -1;
}
}


// 获取framebuffer信息
if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo)) {
    perror("Error reading fixed information");
    return -2;
}

if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo)) {
    perror("Error reading variable information");
    return -3;
}

// 设置framebuffer参数
vinfo.xres = WIDTH;
vinfo.yres = HEIGHT;
vinfo.xres_virtual = WIDTH;
vinfo.yres_virtual = HEIGHT;
vinfo.bits_per_pixel = BPP;
vinfo.red.offset = 11; vinfo.red.length = 5;
vinfo.green.offset = 5; vinfo.green.length = 6;
vinfo.blue.offset = 0; vinfo.blue.length = 5;

if (ioctl(fb_fd, FBIOPUT_VSCREENINFO, &vinfo)) {
    perror("Error setting variable information");
    return -4;
}

// 重新获取更新后的信息
ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo);

// 计算缓冲区大小
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;

// 映射framebuffer到内存
fb_buffer = (char*)mmap(0, screensize, PROT_READ | PROT_WRITE, 
                       MAP_SHARED, fb_fd, 0);

if ((long)fb_buffer == -1) {
    perror("Failed to mmap framebuffer");
    return -5;
}

printf("Framebuffer created: %dx%d, %d bpp\n", 
       vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);

return 0;


}

// 清理函数
void cleanup() {
if (fb_buffer) munmap(fb_buffer, screensize);
if (fb_fd >= 0) close(fb_fd);
bcm2835_gpio_write(BL_PIN, LOW);
bcm2835_spi_end();
bcm2835_close();
}

// 主函数
int main(int argc, char *argv[ ]) {
printf(“ST7735 User-space Framebuffer Driver\n”);


// 初始化bcm2835
if (!bcm2835_init()) {
    printf("Failed to initialize bcm2835\n");
    return 1;
}

// 初始化ST7735
st7735_init();

// 创建framebuffer
if (create_framebuffer() < 0) {
    printf("Failed to create framebuffer\n");
    cleanup();
    return 1;
}

// 清屏
memset(fb_buffer, 0, screensize);
flush_framebuffer();

printf("Driver ready. Press Ctrl+C to exit.\n");

// 主循环:定期刷新framebuffer到屏幕
while (1) {
    flush_framebuffer();
    usleep(16666);  // 约60Hz刷新率
}

cleanup();
return 0;


}

####=========    st7735_fb.c  end =========####
  1. 编译驱动程序
cd /root/go_run/st7735
gcc -o st7735_fb st7735_fb.c -lbcm2835 -lm
  1. 创建systemd服务
    创建 /etc/systemd/system/st7735-fb.service:

####=========    st7735-fb.service  begin =========####

[Unit]
Description=ST7735 User-space Framebuffer Driver
After=multi-user.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/root/go_run/st7735/st7735_fb
WorkingDirectory=/root/go_run/st7735
Restart=always
RestartSec=5
User=root
Environment=DISPLAY=:0

[Install]
WantedBy=multi-user.target

####=========    st7735-fb.service  end =========####
  1. 创建控制台重定向脚本
    创建 /usr/local/bin/console-to-st7735.sh:

####=========    console-to-st7735.sh  begin =========####

#!/bin/bash

# 等待驱动程序启动

sleep 5

# 如果/dev/fb1不存在,创建一个

if [ ! -e “/dev/fb1” ]; then
mknod /dev/fb1 c 29 1
chmod 666 /dev/fb1
fi

# 设置控制台字体(小字体适合128x128分辨率)

if [ -f “/usr/share/consolefonts/Uni2-Terminus12x6.psf.gz” ]; then
setfont /usr/share/consolefonts/Uni2-Terminus12x6.psf.gz
elif [ -f “/usr/share/consolefonts/ter-112n.psf.gz” ]; then
setfont /usr/share/consolefonts/ter-112n.psf.gz
fi

# 重定向控制台输出

echo “Redirecting console to ST7735…”

# 尝试映射控制台到fb1

con2fbmap 1 1 2>/dev/null || true

# 设置环境变量

export FRAMEBUFFER=/dev/fb1

echo “Console redirected to ST7735”

####=========    console-to-st7735.sh  begin =========####
  1. 配置系统启动

启用服务

systemctl enable st7735-fb.service

创建启动脚本

echo “/usr/local/bin/console-to-st7735.sh” >> /etc/rc.local

给脚本执行权限


chmod +x /usr/local/bin/console-to-st7735.sh
chmod +x /etc/rc.local

I strongly recommend to use English as language.

I think this is a community tutorial about ST7735 screen? I will move the topic to the community tutorial category