esp开发与应用(spi屏幕操作)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

很多mcu都会都有一个小的屏幕,用于数据的显示。但是这些屏幕不可能很大,因为mcu的处理能力是有限的。并且,很多时候也不会用rgb屏幕,那样会占用很多的pin脚,这样spi就成为一个很好的选择。而且,spi不仅可以用来操作屏幕,还可以用来访问tf卡、可以用作ad和da转换芯片,这都是可以的,所以今天就来看看esp32如何开发spi屏幕的。

1、弄清spi屏幕的驱动芯片

常用的驱动芯片,都可以从网上找到的。我们一般拿到spi屏幕之后,先看一下驱动芯片是啥,比如我们这次用的芯片是st7789。知道了这个,后续的ai编程就有方向了。

2、了解spi屏幕的引脚

一般来说,spi屏幕的引脚会稍微复杂点。通常来说,有这么8个引脚。首先是电源和地,电源3.3v,或者是5v,这个由实际情况决定。其次是3个spi引脚,即cs、clk、mosi,因为屏幕没有输出,所以只有3个spi引脚。剩下来还有3个,一个是reset复位,一个是c/d转换,一个是blk背光。

3、分配好esp32的引脚

spi的引脚,一般都是由指定的pin约定好的,比如这里我们用了15、14、13,分别接cs、clk、mosi。剩下来的3个,其实随便找3个gpio即可,这边挑选了4、2、12。

4、连接好杜邦线

本身spi屏幕的引脚就是裸露在外面的,所以我们只需要用杜邦线直接连接即可。注意连接的时候,选用那种母对母的杜邦线。

5、开始ai编程

引脚连接没有问题之后,就可以考虑ai编程。这个时候,我们得告诉ai,当前是用esp32对st7789进行编程、spi接口、分辨率是240*240、使用的spi是SPI2_HOST、对应的reset/cmd/bl口是哪几个、准备显示什么界面等等,这些都告诉ai之后,一般就可以得到一份基础的spi屏幕驱动代码。

复制代码
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/spi_master.h"
#include "driver/gpio.h"

// ST7789 Configuration
#define ST7789_SPI_HOST    SPI2_HOST
#define ST7789_SCLK_PIN    14
#define ST7789_MOSI_PIN    13
#define ST7789_CS_PIN      15
#define ST7789_DC_PIN      2
#define ST7789_RST_PIN     4
#define ST7789_BL_PIN      12

#define ST7789_WIDTH       240
#define ST7789_HEIGHT      240

// Commands
#define ST7789_SWRESET     0x01
#define ST7789_SLPOUT      0x11
#define ST7789_NORON       0x13
#define ST7789_INVON       0x21
#define ST7789_DISPON      0x29
#define ST7789_CASET       0x2A
#define ST7789_RASET       0x2B
#define ST7789_RAMWR       0x2C
#define ST7789_COLMOD      0x3A
#define ST7789_MADCTL      0x36

spi_device_handle_t st7789_spi;

static void st7789_send_cmd(uint8_t cmd)
{
    gpio_set_level(ST7789_DC_PIN, 0);
    spi_transaction_t t = {0};
    t.length = 8;
    t.tx_buffer = &cmd;
    spi_device_transmit(st7789_spi, &t);
}

static void st7789_send_data(const uint8_t *data, size_t len)
{
    gpio_set_level(ST7789_DC_PIN, 1);
    spi_transaction_t t = {0};
    t.length = len * 8;
    t.tx_buffer = data;
    spi_device_transmit(st7789_spi, &t);
}

static void st7789_send_byte(uint8_t data)
{
    gpio_set_level(ST7789_DC_PIN, 1);
    spi_transaction_t t = {0};
    t.length = 8;
    t.tx_buffer = &data;
    spi_device_transmit(st7789_spi, &t);
}

void st7789_backlight_on(void)
{
    gpio_set_level(ST7789_BL_PIN, 1);
}

void st7789_init(void)
{
    gpio_set_level(ST7789_RST_PIN, 0);
    vTaskDelay(100 / portTICK_PERIOD_MS);
    gpio_set_level(ST7789_RST_PIN, 1);
    vTaskDelay(100 / portTICK_PERIOD_MS);

    st7789_send_cmd(ST7789_SWRESET);
    vTaskDelay(150 / portTICK_PERIOD_MS);

    st7789_send_cmd(ST7789_SLPOUT);
    vTaskDelay(150 / portTICK_PERIOD_MS);

    // Color mode 16-bit
    st7789_send_cmd(ST7789_COLMOD);
    st7789_send_byte(0x55);
    vTaskDelay(10 / portTICK_PERIOD_MS);

    // Memory access control
    st7789_send_cmd(ST7789_MADCTL);
    st7789_send_byte(0x08);  // BGR mode
    vTaskDelay(10 / portTICK_PERIOD_MS);

    // Inversion on
    st7789_send_cmd(ST7789_INVON);
    vTaskDelay(10 / portTICK_PERIOD_MS);

    // Normal display on
    st7789_send_cmd(ST7789_NORON);
    vTaskDelay(10 / portTICK_PERIOD_MS);

    // Display on
    st7789_send_cmd(ST7789_DISPON);
    vTaskDelay(100 / portTICK_PERIOD_MS);

    st7789_backlight_on();
}

void st7789_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
{
    st7789_send_cmd(ST7789_CASET);
    uint8_t ca[4] = {x0 >> 8, x0 & 0xFF, x1 >> 8, x1 & 0xFF};
    st7789_send_data(ca, 4);

    st7789_send_cmd(ST7789_RASET);
    uint8_t ra[4] = {y0 >> 8, y0 & 0xFF, y1 >> 8, y1 & 0xFF};
    st7789_send_data(ra, 4);

    st7789_send_cmd(ST7789_RAMWR);
}

void st7789_fill(uint16_t color)
{
    st7789_set_window(0, 0, ST7789_WIDTH-1, ST7789_HEIGHT-1);
    uint8_t data[2] = {color >> 8, color & 0xFF};
    for (int i = 0; i < ST7789_WIDTH * ST7789_HEIGHT; i++) {
        st7789_send_data(data, 2);
    }
}

void st7789_spi_init(void)
{
    gpio_config_t io_conf = {
        .pin_bit_mask = (1ULL << ST7789_CS_PIN) | (1ULL << ST7789_DC_PIN) | 
                        (1ULL << ST7789_RST_PIN) | (1ULL << ST7789_BL_PIN),
        .mode = GPIO_MODE_OUTPUT,
        .pull_up_en = 0,
        .pull_down_en = 0,
        .intr_type = GPIO_INTR_DISABLE
    };
    gpio_config(&io_conf);

    spi_bus_config_t buscfg = {
        .miso_io_num = -1,
        .mosi_io_num = ST7789_MOSI_PIN,
        .sclk_io_num = ST7789_SCLK_PIN,
        .quadwp_io_num = -1,
        .quadhd_io_num = -1,
        .max_transfer_sz = ST7789_WIDTH * ST7789_HEIGHT * 2,
    };

    spi_device_interface_config_t devcfg = {
        .clock_speed_hz = 10000000,
        .mode = 0,
        .spics_io_num = ST7789_CS_PIN,
        .queue_size = 7,
    };

    spi_bus_initialize(ST7789_SPI_HOST, &buscfg, SPI_DMA_DISABLED);
    spi_bus_add_device(ST7789_SPI_HOST, &devcfg, &st7789_spi);
}

void app_main(void)
{
    printf("ST7789 Demo\n");
    
    st7789_spi_init();
    st7789_init();

    // Color test
    uint16_t colors[] = {0xFFFF, 0xF800, 0x07E0, 0x001F, 0x0000};  // White, Red, Green, Blue, Black
    char *names[] = {"White", "Red", "Green", "Blue", "Black"};

    while (1) {
        for (int i = 0; i < 5; i++) {
            printf("Color: %s\n", names[i]);
            st7789_fill(colors[i]);
            vTaskDelay(1000 / portTICK_PERIOD_MS);
        }
    }
}

6、编译和测试

**生成后的代码,首先保证能编译、能烧入。**如果烧入之后,没有画面,也不用着急,先看看是不是硬件问题、线有没有连好、排针有有错、电源是否上电等等。不是硬件问题的话,就可以告诉ai,目前遇到了什么样的情况。实际沟通的时候,直接描述情况即可,尽量言简意赅。

当然,生成的代码,也有可能一半是对的,一半是错的。比如,有可能显示位置不对,有可能颜色不对,有可能颜色没有交替改变。我们要做的,就是如实沟通、慢慢交互,只要硬件没问题,最终肯定可以得到自己想要的出图效果。

相关推荐
崇山峻岭之间2 小时前
单片机LCD实验
单片机·嵌入式硬件
m0_377108142 小时前
STM32-adc
stm32·单片机·嵌入式硬件
【云轩】4 小时前
如何设计一台能模拟电机的电子负载:一个硬件工程师的实战笔记
笔记·嵌入式硬件
SmartRadio4 小时前
STM32WLE5 LoRa Smart TDMA 完整协议栈实现(工程级可直接编译)-【1】
javascript·stm32·单片机·嵌入式硬件·lora·自组网·smart tdma
Jason_zhao_MR6 小时前
纳秒级抖动×24小时零丢帧:RK3576工业级EtherCAT主站全拆解
大数据·人工智能·单片机·嵌入式
Deitymoon8 小时前
FreeRTOS——中断实验
stm32·单片机
嵌入式×边缘AI:打怪升级日志8 小时前
# 超声波测距 — HC-SR04 + 定时器输入捕获
单片机·定时器·超声波
yugi9878389 小时前
STM32 串口计算器实现
stm32·单片机·嵌入式硬件
狂奔v蜗牛9 小时前
压敏电阻的使用
嵌入式硬件
科芯创展9 小时前
XZ4115B工作电压6-40V 输出电流1.2A 降压恒流LED驱动芯片
stm32·单片机·嵌入式硬件