From fb653cb5450ee1b86bc3f6cedca8fc6a675fc982 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E6=96=87=E5=B3=B0?= Date: Wed, 31 Dec 2025 02:04:09 +0800 Subject: [PATCH] =?UTF-8?q?idf=E7=9A=84spi=E8=BF=98=E6=9C=89=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- espidfcode/main/lcd.c | 155 ++++++++++++++++++++++++++++++++ espidfcode/main/lcd.h | 18 ++++ espidfcode/main/spi.c | 102 ++++++++++++++++++--- espidfcode/main/spi.h | 26 ++++++ espidfcode/main/the_main.c | 6 ++ lichuang_pcb/debug.log | 1 + lichuang_pcb/lichuang_eda.eprj2 | Bin 2715648 -> 2715648 bytes 7 files changed, 297 insertions(+), 11 deletions(-) create mode 100644 espidfcode/main/lcd.c create mode 100644 espidfcode/main/lcd.h diff --git a/espidfcode/main/lcd.c b/espidfcode/main/lcd.c new file mode 100644 index 0000000..06fba14 --- /dev/null +++ b/espidfcode/main/lcd.c @@ -0,0 +1,155 @@ +#include "lcd.h" + + +static const char *TAG = "LCD"; + +/****************************************************************************** + 函数说明:设置起始和结束地址 + 入口数据:x1,x2 设置列的起始和结束地址 + y1,y2 设置行的起始和结束地址 + 返回值: 无 +******************************************************************************/ +void LCD_Address_Set(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2) +{ + +#if USE_HORIZONTAL==0 + lcd_spi_reg(0x2a);//列地址设置 + lcd_spi_write8(x1); + lcd_spi_write8(x2); + lcd_spi_reg(0x2b);//行地址设置 + lcd_spi_write8(y1); + lcd_spi_write8(y2); + lcd_spi_reg(0x2c);//储存器写 + #elif USE_HORIZONTAL==1 + lcd_spi_reg(0x2a);//列地址设置 + lcd_spi_write8(x1); + lcd_spi_write8(x2); + lcd_spi_reg(0x2b);//行地址设置 + lcd_spi_write8(y1+80); + lcd_spi_write8(y2+80); + lcd_spi_reg(0x2c);//储存器写 + #elif USE_HORIZONTAL==2 + lcd_spi_reg(0x2a);//列地址设置 + lcd_spi_write8(x1); + lcd_spi_write8(x2); + lcd_spi_reg(0x2b);//行地址设置 + lcd_spi_write8(y1); + lcd_spi_write8(y2); + lcd_spi_reg(0x2c);//储存器写 + #elif USE_HORIZONTAL==3 + lcd_spi_reg(0x2a);//列地址设置 + lcd_spi_write8(x1+80); + lcd_spi_write8(x2+80); + lcd_spi_reg(0x2b);//行地址设置 + lcd_spi_write8(y1); + lcd_spi_write8(y2); + lcd_spi_reg(0x2c);//储存器写 + +#endif + + +} + + +void lcd_init(){ +ESP_LOGI(TAG,"等待初始化LCD"); +vTaskDelay(25); // +ESP_LOGI(TAG,"初始化LCD"); +lcd_spi_reg(0x36); +if(USE_HORIZONTAL==0)lcd_spi_write8(0x00); +else if(USE_HORIZONTAL==1)lcd_spi_write8(0xC0); +else if(USE_HORIZONTAL==2)lcd_spi_write8(0x70); +else lcd_spi_write8(0xA0); + +lcd_spi_reg(0x3A); +lcd_spi_write8(0x05); + +lcd_spi_reg(0xB2); +lcd_spi_write8(0x0C); +lcd_spi_write8(0x0C); +lcd_spi_write8(0x00); +lcd_spi_write8(0x33); +lcd_spi_write8(0x33); + +lcd_spi_reg(0xB7); +lcd_spi_write8(0x35); + +lcd_spi_reg(0xBB); +lcd_spi_write8(0x19); + +lcd_spi_reg(0xC0); +lcd_spi_write8(0x2C); + +lcd_spi_reg(0xC2); +lcd_spi_write8(0x01); + +lcd_spi_reg(0xC3); +lcd_spi_write8(0x12); + +lcd_spi_reg(0xC4); +lcd_spi_write8(0x20); + +lcd_spi_reg(0xC6); +lcd_spi_write8(0x0F); + +lcd_spi_reg(0xD0); +lcd_spi_write8(0xA4); +lcd_spi_write8(0xA1); + +lcd_spi_reg(0xE0); +lcd_spi_write8(0xD0); +lcd_spi_write8(0x04); +lcd_spi_write8(0x0D); +lcd_spi_write8(0x11); +lcd_spi_write8(0x13); +lcd_spi_write8(0x2B); +lcd_spi_write8(0x3F); +lcd_spi_write8(0x54); +lcd_spi_write8(0x4C); +lcd_spi_write8(0x18); +lcd_spi_write8(0x0D); +lcd_spi_write8(0x0B); +lcd_spi_write8(0x1F); +lcd_spi_write8(0x23); + +lcd_spi_reg(0xE1); +lcd_spi_write8(0xD0); +lcd_spi_write8(0x04); +lcd_spi_write8(0x0C); +lcd_spi_write8(0x11); +lcd_spi_write8(0x13); +lcd_spi_write8(0x2C); +lcd_spi_write8(0x3F); +lcd_spi_write8(0x44); +lcd_spi_write8(0x51); +lcd_spi_write8(0x2F); +lcd_spi_write8(0x1F); +lcd_spi_write8(0x1F); +lcd_spi_write8(0x20); +lcd_spi_write8(0x23); + +lcd_spi_reg(0x21); + +lcd_spi_reg(0x11); +vTaskDelay(12); + +lcd_spi_reg(0x29); + +ESP_LOGI(TAG,"初始化LCD完成"); + +} + + +void LCD_Clear(uint16_t Color) +{ + uint16_t i,j; + LCD_Address_Set(0,0,LCD_WW-1,LCD_HH-1); + for(i=0;i +#include +#include "esp_log.h" +#include "spi.h" + +#define USE_HORIZONTAL 0 //设置横屏或者竖屏显示 0或1为竖屏 2或3为横屏 +#define LCD_WW 240 +#define LCD_HH 320 + +void LCD_Address_Set(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2); +void lcd_init(); + +void LCD_Clear(uint16_t Color); + +#endif \ No newline at end of file diff --git a/espidfcode/main/spi.c b/espidfcode/main/spi.c index 023c5de..4de0573 100644 --- a/espidfcode/main/spi.c +++ b/espidfcode/main/spi.c @@ -1,15 +1,8 @@ #include "spi.h" -#include "driver/spi_master.h" -#include "esp_log.h" -#define VSPI_MISO -1 //接收引脚不使用,仅发送 -#define VSPI_MOSI 3 -#define VSPI_SCLK 2 -#define LCD_CS 7 -#define LCD_DS 6 static const char *TAG = "SPI_2"; @@ -17,6 +10,39 @@ spi_device_handle_t lcd_spi; void spi_init() { + + ESP_LOGI(TAG, "配置GPIO"); + + // 1. 配置GPIO + gpio_config_t io_conf = { + .pin_bit_mask = (1ULL << LCD_DS), // LCD_DS + .mode = GPIO_MODE_OUTPUT, // 输出模式 + .pull_up_en = GPIO_PULLUP_DISABLE, // + .pull_down_en = GPIO_PULLDOWN_DISABLE, // + .intr_type = GPIO_INTR_DISABLE // 禁用中断 + }; + + // 2. 应用配置 + gpio_config(&io_conf); + + // io_conf.pin_bit_mask=LCD_CS; + // gpio_config(&io_conf); + + // io_conf.pin_bit_mask=VSPI_SCLK; + // gpio_config(&io_conf); + + // io_conf.pin_bit_mask=VSPI_MOSI; + // gpio_config(&io_conf); + + // 3. 设置初始电平 + gpio_set_level(LCD_DS, 0); // 输出低电平 + // gpio_set_level(LCD_CS,0); + // gpio_set_level(VSPI_SCLK,0); + // gpio_set_level(VSPI_MOSI,0); + + + ESP_LOGI(TAG, "配置GPIO完成"); + ESP_LOGI(TAG,"初始化SPI IO总线"); esp_err_t ret; @@ -31,7 +57,7 @@ void spi_init() }; // 2. 初始化 SPI 总线 - ret = spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO); + ret = spi_bus_initialize(SPI2_HOST, &buscfg,SPI_DMA_DISABLED ); if (ret != ESP_OK) { ESP_LOGE(TAG, "SPI2 IO总线初始化失败"); return; @@ -43,11 +69,11 @@ void spi_init() spi_device_interface_config_t devcfg = { .mode = 0, // SPI 模式 0 - .clock_speed_hz = 80 * 1000 * 1000, // + .clock_speed_hz = 40 * 1000 * 1000, // .spics_io_num = LCD_CS, .queue_size = 7, // 队列深度 - .command_bits = 8, // 命令 8 位 - .address_bits = 8, + .flags = 0, // 可选标志 + }; ret = spi_bus_add_device(SPI2_HOST, &devcfg, &lcd_spi); @@ -56,7 +82,61 @@ void spi_init() return; } + + } +// SPI 写数据 +esp_err_t lcd_spi_write8(uint8_t data) { + spi_transaction_t trans = { + .length = 8, // 数据位数 + .tx_buffer = &data, // 发送缓冲区 + .rx_buffer = NULL, // 不接收 + }; + + return spi_device_transmit(lcd_spi, &trans); +} +// SPI 写数据 +esp_err_t lcd_spi_write16(uint16_t data) { + spi_transaction_t trans = { + .length = 16, // 数据位数 + .tx_buffer = &data, // 发送缓冲区 + .rx_buffer = NULL, // 不接收 + }; + + return spi_device_transmit(lcd_spi, &trans); +} +// SPI 写命令 +esp_err_t lcd_spi_reg(uint8_t data) { + esp_err_t err; + gpio_set_level(LCD_DS, 0); + err=lcd_spi_write8(data); + gpio_set_level(LCD_DS, 1); + + if (err != ESP_OK) { + ESP_LOGE(TAG, "命令发送失败"); + + } + return err; +} + +void lcd_ds_test() +{ + esp_err_t err; + static uint8_t this_flag=0; + if(this_flag) + { + this_flag=0; + err=gpio_set_level(LCD_DS, 0); + }else{ + this_flag=1; + err=gpio_set_level(LCD_DS, 1); + } + + if (err != ESP_OK) { + ESP_LOGE(TAG, "GPIO失败"); + + } +} \ No newline at end of file diff --git a/espidfcode/main/spi.h b/espidfcode/main/spi.h index c01e258..c939704 100644 --- a/espidfcode/main/spi.h +++ b/espidfcode/main/spi.h @@ -1,6 +1,32 @@ #ifndef SPI_H #define SPI_H +#include +#include +#include "driver/gpio.h" +#include "driver/spi_master.h" +#include "esp_log.h" +#include "esp_system.h" + +#define VSPI_MISO -1 //接收引脚不使用,仅发送 +#define VSPI_MOSI 3 +#define VSPI_SCLK 2 + +#define LCD_CS 7 +#define LCD_DS 6 + void spi_init(); + +// SPI 写数据 +esp_err_t lcd_spi_write8(uint8_t data); + +// SPI 写数据 +esp_err_t lcd_spi_write16(uint16_t data); + +// SPI 写命令 +esp_err_t lcd_spi_reg(uint8_t data); + +void lcd_ds_test(); + #endif /* SPI_H */ \ No newline at end of file diff --git a/espidfcode/main/the_main.c b/espidfcode/main/the_main.c index 573950b..0a836c5 100644 --- a/espidfcode/main/the_main.c +++ b/espidfcode/main/the_main.c @@ -16,6 +16,8 @@ #include "spi.h" +#include "lcd.h" + static const char *TAG = "SYS"; void app_main(void) @@ -50,9 +52,13 @@ void app_main(void) ESP_LOGI(TAG,"复位原因: %d\n", esp_reset_reason()); spi_init(); + lcd_init(); + LCD_Clear(0x1234); while(1){ + //LCD_Clear(rand()); + // lcd_ds_test(); vTaskDelay(1); // 必须让出CPU } diff --git a/lichuang_pcb/debug.log b/lichuang_pcb/debug.log index b8695ad..fa3d26d 100644 --- a/lichuang_pcb/debug.log +++ b/lichuang_pcb/debug.log @@ -1,2 +1,3 @@ [1217/195831.250:ERROR:gpu\command_buffer\service\shared_image\shared_image_manager.cc:401] SharedImageManager::ProduceSkia: Trying to Produce a Skia representation from a non-existent mailbox. [1230/230046.279:ERROR:ui\gl\direct_composition_support.cc:615] AMD VideoProcessorGetOutputExtension failed: The parameter is incorrect. (0x80070057) +[1231/002815.642:ERROR:ui\gl\direct_composition_support.cc:615] AMD VideoProcessorGetOutputExtension failed: The parameter is incorrect. (0x80070057) diff --git a/lichuang_pcb/lichuang_eda.eprj2 b/lichuang_pcb/lichuang_eda.eprj2 index 307314af81df6736f7a8f7df9c8d5839303a8830..8e08f3a4e14722343007a8564f539370a7aa992f 100644 GIT binary patch delta 324 zcmXBOyG{Z@7zN<@XPMzPyA0kH(Ge9W7Ym7<2|cl$?Y-5ClE5mn&WztdT+saSol`tl_7>2p$vPlZ|7~(pqz_Mq!Ol*kK)CP tN)0+u*A7o)$9aCu%2);l4xj>ua0JItwKAyDNStE&AXdwoRm=L%(=RsSX#xNM delta 4409 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