拾酒与少年 2023-02-21 22:54 采纳率: 0%
浏览 505
已结题

关于esp32使用qspi驱动ST77903遇到的问题!(关键词-时序图)

各位佬好 ! 目前在做毕业设计阶段,使用到了ST77903的这颗IC驱动,但目前根据您所发布的博客已经能够初始化出测试彩条,但一直无法进入写像素模式,所以无法进行刷屏以及后续操作,这个问题也卡了我很多天了,希望能够得到一些指导,而且由于刚开始接触使用ESP32,对PSRAM的操作不熟悉,无法将数组定义到psram,内部ram又不足以存储一帧图像,这里同样求指导 ,所以我缩减了一下数组大小,尝试先刷一部分但还是不行。
以下是我使用的平台:

ESP32S3-FH4R2     ESPIDF-v4.4.4

以下是时序图

img

img

img

//宏
#define LCD_BPP             (24)

#define LCD_X_SIZE          (400)                      /* available x pixel size */
#define LCD_Y_SIZE          (100)                        /* available y pixle size */

#define LCD_PBYTE           ((LCD_BPP + 7) / 8)         /* bytes in pixel unit */
#define LCD_HBYTE           (LCD_X_SIZE * LCD_PBYTE)    /* bytes in horizontal line */


#define LCD_VSW             (1U)
#define LCD_HFP             (8U)
#define LCD_HBP             (8U)

#define LCD_TE_OFT          (25U)

#define FRAME_BLANKING_TIME (10U)
#define FRAME_MEM_SIZE      (LCD_HBYTE * LCD_Y_SIZE)
#define FRAME_MEM_BASE      0x3D000000

#define SRAM_AXI_SIZE 10

//#if (FRAME_MEM_SIZE > SRAM_AXI_SIZE)
//    #error "lcdqspi frame cache size is not enough!"
//#endif

//初始化列表
static const init_line_t init_table[] = {
        {0xf0,  1, {0xc3}},
        {0xf0,  1, {0x96}},
        {0xf0,  1, {0xa5}},
        {0xe9,  1, {0x20}},
        {0xe7,  4, {0x80, 0x77, 0x1f, 0xcc}},
        {0xc1,  4, {0x77, 0x07, 0xc2, 0x07}},
        {0xc2,  4, {0x77, 0x07, 0xc2, 0x07}},
        {0xc3,  4, {0x22, 0x02, 0x22, 0x04}},
        {0xc4,  4, {0x22, 0x02, 0x22, 0x04}},
        {0xc5,  1, {0x71}},
        {0xe0, 14, {0x87, 0x09, 0x0c, 0x06, 0x05, 0x03, 0x29, 0x32, 0x49, 0x0f, 0x1b, 0x17, 0x2a, 0x2f}},
        {0xe1, 14, {0x87, 0x09, 0x0c, 0x06, 0x05, 0x03, 0x29, 0x32, 0x49, 0x0f, 0x1b, 0x17, 0x2a, 0x2f}},
        {0xe5, 14, {0xb2, 0xf5, 0xbd, 0x24, 0x22, 0x25, 0x10, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22}},
        {0xe6, 14, {0xb2, 0xf5, 0xbd, 0x24, 0x22, 0x25, 0x10, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22}},
        {0xec,  2, {0x40, 0x03}},
        {0x36,  1, {0x0c}},
        {0x3a,  1, {0x07}},//RGB显示格式初始化 101565 / 110666 / 111888
        {0xb2,  1, {0x00}},
        {0xb3,  1, {0x01}},
        {0xb4,  1, {0x00}},
        {0xb5,  4, {0x00, 0x08, 0x00, 0x08}},
        {0xb6,  2, {0xc7, 0x31}},
        {0xa5,  9, {0x00, 0x00, 0x00, 0x00, 0x20, 0x15, 0x2a, 0x8a, 0x02}},
        {0xa6,  9, {0x00, 0x00, 0x00, 0x00, 0x20, 0x15, 0x2a, 0x8a, 0x02}},
        {0xba,  7, {0x0a, 0x5a, 0x23, 0x10, 0x25, 0x02, 0x00}},
        {0xbb,  8, {0x00, 0x30, 0x00, 0x29, 0x88, 0x87, 0x18, 0x00}},
        {0xbc,  8, {0x00, 0x30, 0x00, 0x29, 0x88, 0x87, 0x18, 0x00}},
        {0xbd, 11, {0xa1, 0xb2, 0x2b, 0x1a, 0x56, 0x43, 0x34, 0x65, 0xff, 0xff, 0x0f}},
        {0x35,  1, {0x00}},
        {0x21,  1, {0x00}},
        {0x11,  1, {0x00}},
        {0xff,  1, {120}},
        {0x29,  1, {0x00}},  // DISPON-0X29 /DISPOFF-0X28
        {0xff,  1, {120}},
#ifdef BIST_MODE
        {0xb0,  1, {0xa5}},
        {0xcc,  9, {0x40, 0x00, 0x3f, 0x00, 0x14, 0x14, 0x20, 0x20, 0x03}},
#endif
};

//初始化函数

void lcd_qspi_bus_init(void)
{
    esp_err_t ret;
    spi_bus_config_t busConfig = {
            .sclk_io_num = LCD_QSPI_CLK,
//            .mosi_io_num = LCD_QSPI_100,
//            .miso_io_num = LCD_QSPI_101,
//            .quadwp_io_num = LCD_QSPI_102,
//            .quadhd_io_num = LCD_QSPI_103,
            .data0_io_num = LCD_QSPI_100,
            .data1_io_num = LCD_QSPI_101,
            .data2_io_num = LCD_QSPI_102,
            .data3_io_num = LCD_QSPI_103,
            .max_transfer_sz = 4092,
            //.intr_flags = ,
            .flags = SPICOMMON_BUSFLAG_MASTER | SPICOMMON_BUSFLAG_QUAD,
    };

    ret = spi_bus_initialize(LCD_SPI_HOST, &busConfig,SPI_DMA_CH_AUTO);

    ESP_ERROR_CHECK(ret);

    spi_device_interface_config_t ifConfig = {
            .clock_speed_hz = SPI_MASTER_FREQ_8M,
            .spics_io_num = LCD_SPI_CS,
            .mode = 3,
            .queue_size = 7,
            .address_bits = 8,
            .command_bits = 24,
            .flags = SPI_DEVICE_HALFDUPLEX,
    };
    ret = spi_bus_add_device(LCD_SPI_HOST, &ifConfig, &lcd_bus_handle);

    ESP_ERROR_CHECK(ret);
    ESP_LOGI("spi_bus_initialize","OK");
}

/* lcd transmit, write command, write display data */
static void lcd_transmit(uint32_t cmd, uint32_t len, uint8_t *dat)
{
    esp_err_t ret;
    spi_transaction_ext_t tr_ext_Config = {
            .command_bits = 8,
            .address_bits = 24,
            .dummy_bits = 0,
            .base.addr  = cmd << 8,
            .base.cmd   = 0XDE,
            .base.length= 8 * len,
            .base.tx_buffer = dat,
            .base.rx_buffer = NULL,
            .base.flags = SPI_TRANS_VARIABLE_CMD| SPI_TRANS_VARIABLE_ADDR,
    };
    ret = spi_device_polling_transmit(lcd_bus_handle, &tr_ext_Config.base);
    if (ret != ESP_OK)ESP_LOGW("lcd_transmit","ERROR 0x%x",cmd);
}

//写像素
static void lcd_transmit_pixel(uint32_t cmd, uint32_t len, uint8_t *dat)
{
    spi_transaction_ext_t tr_ext_Config = {
            .command_bits = 0,
            .address_bits = 0,
            .dummy_bits = 0,
            .base.addr  = 0,
            .base.cmd   = 0,
            .base.length= 8 * len,
            .base.tx_buffer = dat,
            .base.rx_buffer = NULL,
            .base.flags =   ( SPI_TRANS_MODE_QIO),
    };
    spi_device_polling_transmit(lcd_bus_handle, &tr_ext_Config.base);
}




//发送到lcd的函数
void lcdqspi_thread_entry(void)
{
    uint32_t i = 0;
        /* vs(0x61) packet */
        for (i = 0; i < LCD_VSW; i++)
        {
            lcd_transmit(0x61, 1, 0x00);
            //delay_us_timr(50);
            usleep(40);
        }
        /* hbp(0x60) packet */
        for (i = 0; i < LCD_HBP; i++)
        {
            lcd_transmit(0x60, 1, 0x00);
            //delay_us_timr(50);
            usleep(40);
        }
        /* transmit display cache data to lcd line by line */

        for (i = 0; i < LCD_Y_SIZE; i++)
        {
            lcd_transmit(0x60, 1, 0x00);
            //lcd_transmit_pixel(0x00, LCD_HBYTE, color_buf);
            lcd_transmit_pixel(0x00, LCD_HBYTE, &frame_cache[i][0]);
        }
        
        /* hfp(0x60) packet */
        for (i = 0; i < LCD_HFP; i++)
        {
            lcd_transmit(0x60, 1, 0x00);
            delay_us_timr(40);
        }
        /* transmit is complet, can update frame cache in blanking time */
        delay_ms(FRAME_BLANKING_TIME);
}

函数调用关系

img

img

img

img

  • 写回答

3条回答 默认 最新

  • GISer Liu 2023-02-22 01:20
    关注

    以下答案基于ChatGPT与GISer Liu编写:

    你好,根据你提供的代码和说明,我能看到你正在使用 ESP32S3 平台,使用 ST77903 驱动控制液晶显示。你已经成功初始化了液晶,并能够显示测试彩条。然而,你遇到了问题,无法进入像素写入模式,以刷屏和显示图像。此外,你还遇到了内存不足的问题,导致你无法存储一帧完整的图像到内存中。我将根据你提供的信息提供一些可能有用的建议。

    • 1.首先,我注意到你定义了LCD_X_SIZE和LCD_Y_SIZE宏,它们分别表示屏幕的宽度和高度。你也定义了LCD_BPP宏,表示每个像素的位深度。在这里,你将位深度设置为 24,这意味着你的每个像素将占用 24 位或 3 字节。此外,你定义了LCD_PBYTE宏,表示每个像素的字节数,以及LCD_HBYTE宏,表示每行的字节数。

    • 2.在写入像素数据之前,你需要确保 ST77903 进入了写入模式。在你提供的初始化列表中,我无法找到设置写入模式的命令。通常,这需要发送一些特定的命令序列,如清除屏幕或写入像素数据命令。因此,我建议你仔细阅读 ST77903 数据手册中关于写入模式的章节,并确保你的初始化列表包括正确的命令序列,以将 ST77903 切换到写入模式。

    • 3.关于内存问题,ESP32S3 平台提供了内置的 SRAM 和外部 PSRAM。你可以通过ps_malloc()和ps_calloc()等函数在 PSRAM 中分配内存。请注意,如果你要在 PSRAM 中分配内存,你需要在sdkconfig.h文件中将CONFIG_ESP32S3_PSRAM_USE_ENABLE宏设置为 1。在使用ps_malloc()或ps_calloc()分配内存之前,你需要调用psramFound()函数检查 PSRAM 是否存在。如果 PSRAM 存在,该函数将返回 true。如果不存在,则需要在硬件上进行修复或更换。如果你的液晶分辨率非常高,导致内存不足,你可能需要考虑使用内存映射文件或流数据,而不是将整个图像加载到内存中。

    希望这些建议能够帮助你解决问题。如果你仍然遇到问题,或者需要更多帮助,请告诉我。

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 2月22日
  • 创建了问题 2月21日

悬赏问题

  • ¥15 请问Ubuntu要怎么安装chrome呀?
  • ¥15 视频编码 十六进制问题
  • ¥15 Xsheii7我安装这个文件的时候跳出来另一个文件已锁定文件的无一部分进程无法访问。这个该怎么解决
  • ¥15 unity terrain打包后地形错位,跟建筑不在同一个位置,怎么办
  • ¥15 FileNotFoundError 解决方案
  • ¥15 uniapp实现如下图的图表功能
  • ¥15 u-subsection如何修改相邻两个节点样式
  • ¥30 vs2010开发 WFP(windows filtering platform)
  • ¥15 服务端控制goose报文控制块的发布问题
  • ¥15 学习指导与未来导向啊