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,目前遇到了什么样的情况。实际沟通的时候,直接描述情况即可,尽量言简意赅。

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

相关推荐
芯片人0071 小时前
纯硬件一键开关机ASIC芯片,为什么比 MCU 方案更适合更可靠
人工智能·单片机·嵌入式硬件·物联网·芯片
染予3 小时前
Ka 阵面星历下发与执行逻辑说明
stm32·嵌入式硬件
芯片人0073 小时前
武汉广昇科技的GMUX1308A模拟开关芯片成功导入中国台湾上市企业联昌电子,助力汽车电子供应链自主可控
科技·嵌入式硬件·物联网·汽车·芯片
恒锐丰科技林技术员6 小时前
EG2181D 半桥栅极驱动芯片详解:高压 MOS/IGBT 驱动实用器件
经验分享·嵌入式硬件·硬件工程
国科安芯6 小时前
面向卫星测控应答机的抗辐射MCU信号采集与定时控制研究
单片机·嵌入式硬件·mcu·架构·卫星·商业航天·抗辐射
CC城子7 小时前
EtherNet/IP I/O 丢包排查(linux系统)
linux·单片机·tcp/ip·ethernetip
新晨单片机设计7 小时前
S010A-基于STM32单片机水温控制系统(数码管显示)【Proteus仿真+Keil程序+原理图】
stm32·单片机·嵌入式硬件
事界见闻7 小时前
高性能电机控制MCU选型对比:精度、功耗与实时性如何兼得?
单片机·嵌入式硬件
Brilliantwxx8 小时前
【STM32】 初认识USART串口
linux·stm32·单片机·嵌入式硬件·架构
分享资料9 小时前
用小电容消除高频信号的原因
嵌入式硬件·硬件工程