#include <stdio.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <driver/gpio.h>
#include <driver/spi_master.h>
#include <esp_log.h>
#include<string.h>
static const char *TAG = "LCD_TEST";
// Setup for the ESP32 S2 with ILI9341 display
// Note SPI DMA with ESP32 S2 is not currently supported
#define USER_SETUP_ID 70
// See SetupX_Template.h for all options available
#define ILI9341_DRIVER
// Typical board default pins
#define TFT_CS 10 // 10 or 34
#define TFT_MOSI 11 // 11 or 35
#define TFT_SCLK 12 // 12 or 36
#define TFT_MISO 13 // 13 or 37
#define TFT_DC 14
#define TFT_RST 15
//#define TOUCH_CS 16 // Optional for touch screen
#define LOAD_GLCD
#define LOAD_FONT2
#define LOAD_FONT4
#define LOAD_FONT6
#define LOAD_FONT7
#define LOAD_FONT8
#define LOAD_GFXFF
#define SMOOTH_FONT
// FSPI port will be used unless the following is defined
#define USE_HSPI_PORT
//#define SPI_FREQUENCY 27000000
#define SPI_FREQUENCY 40000000 // Maximum for ILI9341
#define SPI_READ_FREQUENCY 6000000 // 6 MHz is the maximum SPI read speed for the ST7789V
#define SPI_TOUCH_FREQUENCY 2500000
// LCD控制函數
void lcd_cmd(const uint8_t cmd)
{
esp_err_t ret;
spi_transaction_t t;
memset(&t, 0, sizeof(t));
t.length = 8;
t.tx_buffer = &cmd;
gpio_set_level(PIN_NUM_DC, 0); // 命令模式
ret = spi_device_polling_transmit(spi, &t);
assert(ret == ESP_OK);
}
void lcd_data(const uint8_t *data, int len)
{
esp_err_t ret;
spi_transaction_t t;
if (len == 0) return;
memset(&t, 0, sizeof(t));
t.length = len * 8;
t.tx_buffer = data;
gpio_set_level(PIN_NUM_DC, 1); // 資料模式
ret = spi_device_polling_transmit(spi, &t);
assert(ret == ESP_OK);
}
void lcd_init(void)
{
// 重置LCD
gpio_set_level(PIN_NUM_RST, 0);
vTaskDelay(pdMS_TO_TICKS(100));
gpio_set_level(PIN_NUM_RST, 1);
vTaskDelay(pdMS_TO_TICKS(100));
// 軟體重置
lcd_cmd(ILI9341_SWRESET);
vTaskDelay(pdMS_TO_TICKS(150));
// 退出睡眠模式
lcd_cmd(ILI9341_SLPOUT);
vTaskDelay(pdMS_TO_TICKS(500));
// 設定像素格式為16位
lcd_cmd(ILI9341_COLMOD);
uint8_t data = 0x55; // 16位RGB565
lcd_data(&data, 1);
// 開啟顯示
lcd_cmd(ILI9341_DISPON);
vTaskDelay(pdMS_TO_TICKS(100));
ESP_LOGI(TAG, "LCD初始化完成");
}
void lcd_set_addr_window(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
{
// 設定X座標範圍
lcd_cmd(ILI9341_CASET);
uint8_t data[4] = {x1 >> 8, x1 & 0xFF, x2 >> 8, x2 & 0xFF};
lcd_data(data, 4);
// 設定Y座標範圍
lcd_cmd(ILI9341_PASET);
data[0] = y1 >> 8; data[1] = y1 & 0xFF;
data[2] = y2 >> 8; data[3] = y2 & 0xFF;
lcd_data(data, 4);
// 開始寫入RAM
lcd_cmd(ILI9341_RAMWR);
}
void lcd_fill_color(uint16_t color)
{
lcd_set_addr_window(0, 0, LCD_WIDTH - 1, LCD_HEIGHT - 1);
// 準備顏色資料 (需要轉換為大端序)
uint8_t color_bytes[2] = {color >> 8, color & 0xFF};
// 逐點填充顏色
for (int i = 0; i < LCD_WIDTH * LCD_HEIGHT; i++) {
lcd_data(color_bytes, 2);
}
}
void app_main(void)
{
printf("=== 程式開始執行 ===\n");
ESP_LOGI(TAG, "ESP32-S2 ILI9341 LCD 測試開始");
// 初始化GPIO
printf("正在初始化GPIO...\n");
gpio_config_t io_conf = {
.intr_type = GPIO_INTR_DISABLE,
.mode = GPIO_MODE_OUTPUT,
.pin_bit_mask = (1ULL << PIN_NUM_DC) | (1ULL << PIN_NUM_RST),
.pull_down_en = 0,
.pull_up_en = 0,
};
esp_err_t ret = gpio_config(&io_conf);
printf("GPIO配置結果: %s\n", (ret == ESP_OK) ? "成功" : "失敗");
// 測試GPIO控制
printf("測試GPIO控制...\n");
gpio_set_level(PIN_NUM_RST, 1);
gpio_set_level(PIN_NUM_DC, 1);
vTaskDelay(pdMS_TO_TICKS(100));
// 初始化SPI bus
printf("正在初始化SPI...\n");
spi_bus_config_t buscfg = {
.miso_io_num = -1,
.mosi_io_num = PIN_NUM_MOSI,
.sclk_io_num = PIN_NUM_CLK,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = 4096,
};
ret = spi_bus_initialize(LCD_HOST, &buscfg, SPI_DMA_CH_AUTO);
printf("SPI初始化結果: %s\n", (ret == ESP_OK) ? "成功" : "失敗");
// 加入SPI設備
printf("正在加入SPI設備...\n");
spi_device_interface_config_t devcfg = {
.clock_speed_hz = 1000000, // 降低到1MHz測試
.mode = 0,
.spics_io_num = PIN_NUM_CS,
.queue_size = 7,
};
ret = spi_bus_add_device(LCD_HOST, &devcfg, &spi);
printf("SPI設備加入結果: %s\n", (ret == ESP_OK) ? "成功" : "失敗");
// 初始化LCD
printf("正在初始化LCD...\n");
lcd_init();
printf("開始顯示測試...\n");
// 簡化的測試循環
int counter = 0;
while (1) {
printf("測試循環 #%d\n", counter++);
printf("顯示紅色...\n");
lcd_fill_color(0xF800);
vTaskDelay(pdMS_TO_TICKS(3000));
printf("顯示綠色...\n");
lcd_fill_color(0x07E0);
vTaskDelay(pdMS_TO_TICKS(3000));
if (counter > 3) {
printf("測試完成,程式將重複執行\n");
counter = 0;
}
}
}Loading
ili9341-cap-touch
ili9341-cap-touch