# Phần 3: Màn hình

Ok, đầu tiên mình muốn chọn lắp màn hình trước.

<span style="white-space: pre-wrap;">Màn hình là phần giúp hiển thị trực quan nhất. Mình có thể thấy được thành quả của mình hiển thị ngay trên màn hình chứ không phải chỉ ở mỗi </span>`<span class="editor-theme-code">Serial.print</span>`

<span style="white-space: pre-wrap;">Màn hình cũng giúp mình kiểm tra được những lỗi phần cứng mà chỉ dùng </span>`<span class="editor-theme-code">Serial.print</span>`<span style="white-space: pre-wrap;"> thì không thể tìm ra hết được.</span>

### Lắp đặt

<table id="bkmrk-m%C3%A0n-h%C3%ACnhesp32-c3ch%E1%BA%AFc"><colgroup><col></col><col style="width: 88px;"></col><col></col><col></col><col></col></colgroup><tbody><tr><td>**Màn hình**

</td><td>**ESP32-C3**

</td><td>**Chắc năng**

</td><td>**Lý do**

</td><td>**Ghi Chú**

</td></tr><tr><td>VCC

</td><td>**3.3V** hoặc 5V

</td><td>Cấp nguồn cho màn hình.

</td><td>Nguồn vào từ USB qua ESP32 có thể đẩy ra thành 2 nguồn 3.3V hoặc 5V.

</td><td>Với những thiết bị nhẹ điện. Có thể sử dụng nguồn từ ESP32.

Chọn nguồn phù hợp với thiết bị

</td></tr><tr><td>GND

</td><td>GND

</td><td>Nối đất

</td><td>Tạo một điểm tham chiếu chung cho toàn bộ thiết bị trên hệ thống

</td><td>Toàn bộ thiết bị đều cần kết nối GND

</td></tr><tr><td>SCK

</td><td>GPIO4

</td><td>Clock (SPI)

</td><td>Màn hình sử dụng giao thức SPI nên cần sử dụng chân clock  
GPIO4 là chân clock của mạch ESP32-C3 này

</td><td><span style="white-space: pre-wrap;">Chân </span>**clock** có thể thay đổi với những board mạch khác nhau. Kiểm tra datasheet để biết thêm chi tiết.

</td></tr><tr><td>SDA

</td><td>GPIO6

</td><td>Data out (MOSI)

</td><td>Màn hình nhận dữ liệu từ cổng ra của ESP32

</td><td>MOSI cũng là một chân đặc biệt trên ESP32. Chú ý kiểm tra datasheet

</td></tr><tr><td>RES

</td><td>GPIO1

</td><td>Reset

</td><td>Là chân điều khiển không yêu cầu tốc độ cao. Chọn bất kỳ chân GPIO còn trống thuận tiện cho đi dây

</td><td>Tránh chọn các chân đặc biệt  
Cần chú ý khai báo chính xác trong code

</td></tr><tr><td>DC

</td><td>GPIO2

</td><td>Data/Command

</td><td>Tương tự như RES. Có thể chọn chân GPIO thuận tiện

</td><td></td></tr><tr><td>BLK

</td><td>GPIO3

</td><td>Điều khiển nền của màn hình

</td><td>Tương tự như RES và DC. Có thể chọn chân thuận tiện cho việc đi dây

</td><td></td></tr></tbody></table>

### Kiểm tra

#### Cài đặt thư viện TFT\_eSPI

> Arduino and PlatformIO IDE compatible TFT library optimised for the Raspberry Pi Pico (RP2040), STM32, ESP8266 and ESP32 that supports different driver chips

Để thêm thư viện chúng ta có thể thực hiện 1 trong 2 cách sau:

- <span style="white-space: pre-wrap;"> Truy cập PIO Home → Library → Search TFT\_eSPI và cài đặt library TFT\_eSPI của Bodmer</span>
- Hoặc thêm`<span class="editor-theme-code"> bodmer/TFT_eSPI</span>`<span style="white-space: pre-wrap;"> vào phần </span>`<span class="editor-theme-code">lib_deps</span>`<span style="white-space: pre-wrap;"> trong file </span>`<span class="editor-theme-code">platformio.ini</span>`

<span style="white-space: pre-wrap;">Khi đó file </span>`<span class="editor-theme-code">platformio.ini</span>`<span style="white-space: pre-wrap;"> sẽ trông như thế này</span>

```c++
[env:esp32-c3-devkitm-1]
platform = platformio/espressif32 @ 6.6.0
board = esp32-c3-devkitm-1
framework = arduino
platform_packages =
  framework-arduinoespressif32 @ ~3.20014.0
lib_deps = 
	SPI
	bodmer/TFT_eSPI@^2.5.43
monitor_speed = 115200
build_flags = 
	-D ARDUINO_USB_MODE=1
	-D ARDUINO_USB_CDC_ON_BOOT=1
```

Tiếp theo cần cấu hình thư viện để nó tương thích với đúng phần cứng.

<span style="white-space: pre-wrap;">Truy cập </span>`<span class="editor-theme-code">.pio → libdeps → esp32-c3-devkitm-1 → TFT_eSPI → User_Setup.h</span>`<span style="white-space: pre-wrap;"> và thực hiện config tương ứng với cấu hình phần cứng.</span>

```c#
// Driver của màn hình
#define ST7789_DRIVER
#define ESP32_C3_DMA_ERROR_WORKAROUND
#define TFT_RGB_ORDER TFT_RGB // Nếu màu in ra bị sai Blue và Red thì đổi lại thành TFT_BGR

// Kích thước của màn hình
#define TFT_WIDTH 240
#define TFT_HEIGHT 240

// Các chân kết nối đang được sử dụng
#define TFT_MOSI 6
#define TFT_SCLK 4
#define TFT_CS   -1

#define TFT_DC   2
#define TFT_RST  1
#define TFT_BL   3

// Tín hiệu bật/tắt đèn nền
#define TFT_BACKLIGHT_ON HIGH

// Các font sẽ được compile
#define LOAD_GLCD    // Font 1 (built-in), required for basic text
#define LOAD_FONT2   // Small 16 px font
#define LOAD_FONT4   // Medium 26 px font
#define LOAD_FONT6
#define LOAD_FONT7
#define LOAD_FONT8
#define LOAD_GFXFF  // FreeFonts (optional)
#define SMOOTH_FONT // Anti-aliased fonts (needs FS)

// Tốc độ SPI
#define SPI_FREQUENCY       40000000
#define SPI_READ_FREQUENCY  20000000
```

<p class="callout warning"><span style="white-space: pre-wrap;">Cách này có điểm yếu là sẽ bị </span>**reset** <span style="white-space: pre-wrap;">khi </span>`<span class="editor-theme-code">Full Clean</span>`<span style="white-space: pre-wrap;"> hoặc </span>`<span class="editor-theme-code">Update/Re-install</span>`<span style="white-space: pre-wrap;"> thư viện. Nhưng trong quá trình test các các setup khác đều gặp lỗi bootloop do config sai. Nên hiện tại vẫn sử dụng cách này để setup.</span></p>

#### "Hello World!"

Tiếp theo để test xem màn hình đã được setup đúng và phần cứng còn hoạt động tốt hay không. Chúng ta sẽ thử với đoạn code hiển thị "Hello world!" trên màn hình.

Truy cập`<span class="editor-theme-code"> src → main.cpp</span>`<span style="white-space: pre-wrap;"> và sử dụng đoạn code dưới đây:</span>

```c++
#include <Arduino.h>
#include <TFT_eSPI.h>

// Tạo đối tượng tft từ thư viện
TFT_eSPI tft = TFT_eSPI();

void setup() {
  tft.init(); // Khởi tại tft controller

  tft.setRotation(0); // Set hướng xoay màn hình // Sử dụng các tham số 0, 1, 2, 3
  tft.fillScreen(TFT_BLACK); // Fill toàn bộ màn hình bằng màu đen
  tft.setTextColor(TFT_GREEN); // Set màu chữ
  tft.setTextSize(2); // Set cỡ chữ
  tft.setCursor(0, 0); // Set tọa độ điểm bắt đầu viết chữ
  tft.println("Hello World!"); // Hiển thị chữ
}

void loop() {}
```

Sau đó thực hiện Upload. Quá trình Upload có thể có warning (console màu vàng) nhưng không ảnh hưởng gì.

<span style="white-space: pre-wrap;">Sau khi upload xong kiểm tra màn hình nếu hiển thị như hình dưới là đã chạy </span>**thành công** sẵn sàng cho bước tiếp theo thôi.[![1000048881.jpg](https://knowledge.thanhdv.com/uploads/images/gallery/2025-10/scaled-1680-/1000048881.jpg)](https://knowledge.thanhdv.com/uploads/images/gallery/2025-10/scaled-1680-/1000048881.jpg)<span style="white-space: pre-wrap;"> </span>

Trong trường hợp chưa hiển thị được "Hello World!" trên màn hình hãy kiểm tra cửa sổ terminal trên VSCode:

- <span style="white-space: pre-wrap;">Nếu </span>**có** log chạy liên tục thì rất có thể bạn bị bootloop.
- <span style="white-space: pre-wrap;">Nếu </span>**không** <span style="white-space: pre-wrap;">có hãy nhần nút </span>**Reset** trên ESP32 để ép ESP32 khởi động lại.

Nếu vẫn không được thực hiện check list sau:

- Kiểm tra các chân kết nối đảm bảo không chân nào bị lỏng.
- <span style="white-space: pre-wrap;">Kiểm tra lại file </span>`<span class="editor-theme-code">User_Setup.h</span>`<span style="white-space: pre-wrap;"> đảm bảo đã config đúng file, đúng tham số.</span>
- <span style="white-space: pre-wrap;">Đảm bảo đã khai báo đúng và đủ file </span>`<span class="editor-theme-code">platformio.ini</span>`
- Thực hiện Clean và Upload lại.

Nếu vẫn không được nữa. Thì nên thử với một cái màn hình khác để đảm bảo phần cứng không bị hỏng.