#include "lcd.h" static const char *TAG = "LCD"; // uint16_t dis_buff[LCD_WW][LCD_HH]; lcd_t lcd_main; // SPI 写数据 esp_err_t lcd_spi_send_data_8(uint8_t data) { spi_transaction_t trans = { .length = 8, // 数据位数 .flags = SPI_TRANS_USE_TXDATA, // 必须加这个标志 }; trans.tx_data[0] = (data); esp_err_t err = spi_device_transmit(lcd_spi, &trans); return err; } // SPI 写数据 esp_err_t lcd_spi_send_data_16(uint16_t data) { spi_transaction_t trans = { .length = 16, // 数据位数 .flags = SPI_TRANS_USE_TXDATA, // 必须加这个标志 }; trans.tx_data[0] = (data >> 8); trans.tx_data[1] = (data); esp_err_t err = spi_device_transmit(lcd_spi, &trans); return err; } esp_err_t lcd_spi_send_data_any(uint8_t *data, uint16_t len) { spi_transaction_t trans = { .length = len * 8, .tx_buffer = data, }; esp_err_t err = spi_device_transmit(lcd_spi, &trans); return err; } // SPI 写命令 void lcd_spi_send_cmd(uint8_t data) { esp_err_t err; gpio_set_level(LCD_DS, 0); err = lcd_spi_send_data_8(data); gpio_set_level(LCD_DS, 1); if (err != ESP_OK) { ESP_LOGE(TAG, "命令发送失败:%x", err); } } /****************************************************************************** 函数说明:设置起始和结束地址 入口数据:x1,x2 设置列的起始和结束地址 y1,y2 设置行的起始和结束地址 返回值: 无 ******************************************************************************/ void lcd_set_window(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { #if USE_HORIZONTAL == 0 lcd_spi_send_cmd(0x2a); // 列地址设置 lcd_spi_send_data_16(x1); lcd_spi_send_data_16(x2); lcd_spi_send_cmd(0x2b); // 行地址设置 lcd_spi_send_data_16(y1); lcd_spi_send_data_16(y2); lcd_spi_send_cmd(0x2c); // 储存器写 #elif USE_HORIZONTAL == 1 lcd_spi_send_cmd(0x2a); // 列地址设置 lcd_spi_send_data_16(x1); lcd_spi_send_data_16(x2); lcd_spi_send_cmd(0x2b); // 行地址设置 lcd_spi_send_data_16(y1 + 80); lcd_spi_send_data_16(y2 + 80); lcd_spi_send_cmd(0x2c); // 储存器写 #elif USE_HORIZONTAL == 2 lcd_spi_send_cmd(0x2a); // 列地址设置 lcd_spi_send_data_16(x1); lcd_spi_send_data_16(x2); lcd_spi_send_cmd(0x2b); // 行地址设置 lcd_spi_send_data_16(y1); lcd_spi_send_data_16(y2); lcd_spi_send_cmd(0x2c); // 储存器写 #elif USE_HORIZONTAL == 3 lcd_spi_send_cmd(0x2a); // 列地址设置 lcd_spi_send_data_16(x1 + 80); lcd_spi_send_data_16(x2 + 80); lcd_spi_send_cmd(0x2b); // 行地址设置 lcd_spi_send_data_16(y1); lcd_spi_send_data_16(y2); lcd_spi_send_cmd(0x2c); // 储存器写 #endif } void lcd_one_second_task() { lcd_main.fps=lcd_main.fps_count; lcd_main.fps_count=0; ESP_LOGI(TAG, "FPS:%d",lcd_main.fps); } void lcd_send_full_buf() { gpio_set_level(LCD_CS, 0); lcd_set_window(0, 0, LCD_WW - 1, LCD_HH - 1); // 分包发送 单次9600 分16次发送 spi_transaction_t trans = { .length = 9600 * 8, // 数据位数 }; uint8_t *d_buf = (uint8_t *)(lcd_main.buf); for (uint16_t i = 0; i < 16; i++) { // trans.length=9600*8; trans.tx_buffer = d_buf + (i * 9600); spi_device_transmit(lcd_spi, &trans); } gpio_set_level(LCD_CS, 1); //发送成功 帧计数+1 lcd_main.fps_count+=1; } void lcd_clear_buf(uint16_t color) { for (uint32_t i = 0; i < (LCD_WW * LCD_HH); i++) { lcd_main.buf[i] = color; } } void lcd_init() { ESP_LOGI(TAG, "配置GPIO"); // 初始化屏幕IO // 配置GPIO gpio_config_t io_conf = { .pin_bit_mask = (1ULL << LCD_DS) | (1ULL << LCD_CS), // LCD_DS LCD_CS .mode = GPIO_MODE_OUTPUT, // 输出模式 .pull_up_en = GPIO_PULLUP_DISABLE, // .pull_down_en = GPIO_PULLDOWN_DISABLE, // .intr_type = GPIO_INTR_DISABLE // 禁用中断 }; // 应用配置 gpio_config(&io_conf); // 配置 GPIO 驱动能力 (ESP32-C3 支持) // gpio_set_drive_capability(VSPI_MISO, GPIO_DRIVE_CAP_3); // 最大驱动 gpio_set_drive_capability(VSPI_MOSI, GPIO_DRIVE_CAP_3); gpio_set_drive_capability(VSPI_SCLK, GPIO_DRIVE_CAP_3); ESP_LOGI(TAG, "配置GPIO完成"); // 设置初始电平 gpio_set_level(LCD_DS, 0); // 输出低电平 gpio_set_level(LCD_CS, 0); ESP_LOGI(TAG, "等待初始化LCD"); vTaskDelay(25); // // uint8_t data_tmp[16];//数据缓存 ESP_LOGI(TAG, "初始化LCD"); lcd_spi_send_cmd(0x36); if (USE_HORIZONTAL == 0) lcd_spi_send_data_8(0x00); else if (USE_HORIZONTAL == 1) lcd_spi_send_data_8(0xC0); else if (USE_HORIZONTAL == 2) lcd_spi_send_data_8(0x70); else lcd_spi_send_data_8(0xA0); lcd_spi_send_cmd(0x3A); lcd_spi_send_data_8(0x05); lcd_spi_send_cmd(0xB2); lcd_spi_send_data_8(0x0C); lcd_spi_send_data_8(0x0C); lcd_spi_send_data_8(0x00); lcd_spi_send_data_8(0x33); lcd_spi_send_data_8(0x33); lcd_spi_send_cmd(0xB7); lcd_spi_send_data_8(0x35); lcd_spi_send_cmd(0xBB); lcd_spi_send_data_8(0x19); lcd_spi_send_cmd(0xC0); lcd_spi_send_data_8(0x2C); lcd_spi_send_cmd(0xC2); lcd_spi_send_data_8(0x01); lcd_spi_send_cmd(0xC3); lcd_spi_send_data_8(0x12); lcd_spi_send_cmd(0xC4); lcd_spi_send_data_8(0x20); lcd_spi_send_cmd(0xC6); lcd_spi_send_data_8(0x0F); lcd_spi_send_cmd(0xD0); lcd_spi_send_data_8(0xA4); lcd_spi_send_data_8(0xA1); lcd_spi_send_cmd(0xE0); lcd_spi_send_data_8(0xD0); lcd_spi_send_data_8(0x04); lcd_spi_send_data_8(0x0D); lcd_spi_send_data_8(0x11); lcd_spi_send_data_8(0x13); lcd_spi_send_data_8(0x2B); lcd_spi_send_data_8(0x3F); lcd_spi_send_data_8(0x54); lcd_spi_send_data_8(0x4C); lcd_spi_send_data_8(0x18); lcd_spi_send_data_8(0x0D); lcd_spi_send_data_8(0x0B); lcd_spi_send_data_8(0x1F); lcd_spi_send_data_8(0x23); lcd_spi_send_cmd(0xE1); lcd_spi_send_data_8(0xD0); lcd_spi_send_data_8(0x04); lcd_spi_send_data_8(0x0C); lcd_spi_send_data_8(0x11); lcd_spi_send_data_8(0x13); lcd_spi_send_data_8(0x2C); lcd_spi_send_data_8(0x3F); lcd_spi_send_data_8(0x44); lcd_spi_send_data_8(0x51); lcd_spi_send_data_8(0x2F); lcd_spi_send_data_8(0x1F); lcd_spi_send_data_8(0x1F); lcd_spi_send_data_8(0x20); lcd_spi_send_data_8(0x23); lcd_spi_send_cmd(0x21); lcd_spi_send_cmd(0x11); vTaskDelay(12); lcd_spi_send_cmd(0x29); lcd_clear_buf(0xffff); gpio_set_level(LCD_CS, 1); ESP_LOGI(TAG, "初始化LCD完成"); }