ESP-WROOM-32连接WiFi后ST7789显示屏停止工作问题排查
故障排查:ESP32连接WiFi后ST7789显示屏冻结问题
核心分析
你的问题核心是WiFi启动后抢占了SPI总线资源或导致时钟/通信参数不匹配,虽然ESP32的WiFi模块不直接使用G18/G23等SPI引脚,但默认SPI总线的控制权、时钟频率在WiFi启动后会发生变化,导致Adafruit_ST7789库无法正常与屏幕通信,最终表现为屏幕冻结。
具体解决方案
1. 显式指定SPI总线实例
Adafruit_ST7789默认使用系统默认SPI总线,WiFi启动后可能会干扰该总线的控制权。通过显式创建HSPI/VSPI总线对象,指定引脚绑定,可避免冲突:
#include <SPI.h> #include <Adafruit_GFX.h> #include <Adafruit_ST7789.h> // 创建HSPI总线对象,独立于默认SPI SPIClass hspi(HSPI); // 绑定屏幕引脚:CS(G5)、DC(G2)、RES(G4),并传入自定义SPI对象 Adafruit_ST7789 tft = Adafruit_ST7789(&hspi, G5, G2, G4); void setup() { Serial.begin(115200); // 初始化HSPI总线,明确指定引脚:SCK(G18)、MISO(-1,未使用)、MOSI(G23)、CS(G5) hspi.begin(G18, -1, G23, G5); // 初始化屏幕,指定尺寸 tft.init(240, 280); tft.fillScreen(ST77XX_BLACK); tft.setCursor(0, 0); tft.print("Screen Init OK"); // WiFi连接逻辑 WiFi.begin("你的SSID", "你的密码"); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); // 测试屏幕更新 tft.setCursor(0, 20); tft.print("Connecting WiFi..."); } Serial.println("\nWiFi Connected"); tft.fillScreen(ST77XX_BLACK); tft.setCursor(0, 0); tft.print("WiFi Connected!"); } void loop() { // 持续更新屏幕,验证功能 tft.setCursor(0, 40); tft.print("Millis: "); tft.print(millis()); delay(1000); }
2. 固定SPI通信速率
WiFi启动后,ESP32的系统时钟会从默认的40MHz切换到80MHz/160MHz,导致SPI总线速率超出屏幕兼容范围。初始化屏幕时可手动指定较低的SPI速率:
// 初始化屏幕时指定SPI模式和速率(20MHz,可根据屏幕手册调整) tft.init(240, 280, SPI_MODE3, 20000000);
3. 排查引脚复用冲突
如果上述方法无效,可通过代码检查WiFi启动前后引脚的功能状态,确认是否被意外复用:
#include <esp_gpio.h> void checkPinStatus(uint8_t pin) { gpio_num_t gpio = (gpio_num_t)pin; Serial.printf("Pin %d: ", pin); // 获取引脚功能 uint32_t func = gpio_get_function(gpio); Serial.printf("Function = %d | Direction = %s\n", func, gpio_get_direction(gpio) ? "OUTPUT" : "INPUT"); } void setup() { Serial.begin(115200); Serial.println("Before WiFi Begin:"); checkPinStatus(18); checkPinStatus(23); checkPinStatus(4); checkPinStatus(2); checkPinStatus(5); WiFi.begin("你的SSID", "你的密码"); delay(2000); Serial.println("\nAfter WiFi Begin:"); checkPinStatus(18); checkPinStatus(23); checkPinStatus(4); checkPinStatus(2); checkPinStatus(5); }
若WiFi启动后引脚功能发生变化,可通过gpio_set_function()强制指定引脚为SPI功能:
gpio_set_function(G18, GPIO_FUNC_SPI); gpio_set_function(G23, GPIO_FUNC_SPI);
4. 禁用WiFi电源管理
部分场景下,WiFi的自动睡眠模式会导致总线通信暂停,可禁用该功能:
WiFi.setSleep(false);
总结
最常见的解决方式是显式指定独立SPI总线,这能彻底避免WiFi对默认SPI总线的干扰。如果仍有问题,可结合固定SPI速率、检查引脚复用进一步排查。
内容的提问来源于stack exchange,提问作者RANGO
相关产品推荐
相关产品推荐

