XIAO ESP32S3 — SSD1306 — Xiao Esp32 S3 simulation

An interactive Xiao Esp32 S3 circuit simulation you can run free in your browser on Velxio, by buduojun.

Components

Sketch code

// ESP-IDF SSD1306 倒计时 — XIAO ESP32-S3 + SPI
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/spi_master.h"
#include "driver/gpio.h"
#include "esp_timer.h"

/* ===== 引脚定义 (与接线一致) ===== */
#define PIN_SCK   8
#define PIN_MOSI  10
#define PIN_CS    2
#define PIN_DC    3
#define PIN_RST   4

/* ===== SSD1306 常量 ===== */
#define OLED_W     128
#define OLED_H     64
#define OLED_PAGES (OLED_H / 8)

static spi_device_handle_t spi;
static uint8_t fb[OLED_W * OLED_PAGES];  /* 1024 字节帧缓冲 */

/* ========== 底层 SPI / SSD1306 ========== */

static void oled_cmd(uint8_t cmd)
{
    gpio_set_level(PIN_DC, 0);
    spi_transaction_t t = { .length = 8, .tx_buffer = &cmd };
    spi_device_transmit(spi, &t);
}

static void oled_data(const uint8_t *data, size_t len)
{
    if (!len) return;
    gpio_set_level(PIN_DC, 1);
    spi_transaction_t t = { .length = len * 8, .tx_buffer = data };
    spi_device_transmit(spi, &t);
}

static void oled_init(void)
{
    /* 硬件复位 */
    gpio_set_level(PIN_RST, 0);
    vTaskDelay(pdMS_TO_TICKS(10));
    gpio_set_level(PIN_RST, 1);
    vTaskDelay(pdMS_TO_TICKS(10));

    /* 初始化命令序列 (128x64, SPI) */
    oled_cmd(0xAE);             /* 显示关 */
    oled_cmd(0xD5); oled_cmd(0x80); /* 时钟分频 */
    oled_cmd(0xA8); oled_cmd(0x3F); /* 多路复用 64 行 */
    oled_cmd(0xD3); oled_cmd(0x00); /* 显示偏移 0 */
    oled_cmd(0x40);              /* 起始行 0 */
    oled_cmd(0x8D); oled_cmd(0x14); /* 启用电荷泵 */
    oled_cmd(0x20); oled_cmd(0x00); /* 水平寻址模式 */
    oled_cmd(0xA1);              /* 段重映射 */
    oled_cmd(0xC8);              /* COM 扫描方向 */
    oled_cmd(0xDA); oled_cmd(0x12); /* COM 引脚配置 */
    oled_cmd(0x81); oled_cmd(0xCF); /* 对比度 */
    oled_cmd(0xD9); oled_cmd(0xF1); /* 预充电周期 */
    oled_cmd(0xDB); oled_cmd(0x40); /* VCOMH 电平 */
    oled_cmd(0xA4);              /* 全部显示 ON (从 RAM) */
    oled_cmd(0xA6);              /* 正常显示 */
    oled_cmd(0xAF);              /* 显示开 */
}

static void oled_flush(void)
{
    /* 设置全屏地址范围 */
    oled_cmd(0x21); oled_cmd(0); oled_cmd(127);  /* 列 0~127 */
    oled_cmd(0x22); oled_cmd(0); oled_cmd(7);    /* 页 0~7   */
    oled_data(fb, sizeof(fb));
}

/* ========== 绘图 ========== */

static void oled_clear(void)
{
    memset(fb, 0, sizeof(fb));
}

static void oled_pixel(int x, int y, int on)
{
    if (x < 0 || x >= OLED_W || y < 0 || y >= OLED_H) return;
    int p = y >> 3, b = y & 7;
    if (on) fb[p * OLED_W + x] |=  (1 << b);
    else    fb[p * OLED_W + x] &= ~(1 << b);
}

/* ========== 5x7 ASCII 字体 (0x20 ~ 0x7E) ========== */

static const uint8_t font5x7[][5] = {
    {0x00,0x00,0x00,0x00,0x00}, /*   (space) */
    {0x00,0x00,0x5F,0x00,0x00}, /* ! */
    {0x00,0x07,0x00,0x07,0x00}, /* " */
    {0x14,0x7F,0x14,0x7F,0x14}, /* # */
    {0x24,0x2A,0x7F,0x2A,0x12}, /* $ */
    {0x23,0x13,0x08,0x64,0x62}, /* % */
    {0x36,0x49,0x55,0x22,0x50}, /* & */
    {0x00,0x05,0x03,0x00,0x00}, /* ' */
    {0x00,0x1C,0x22,0x41,0x00}, /* ( */
    {0x00,0x41,0x22,0x1C,0x00}, /* ) */
 

More projects by buduojun