1. GPIO引脚功能自检
任务目标
编写ESP32固件自检程序,依次将每个可用GPIO引脚配置为输入模式并读取电平,通过外部跳线将引脚连接至已知电平(GND或3.3V),从而检测引脚是否存在短路或断路故障,并在串口输出每个引脚的测试结果。
硬件准备
- ESP32开发板(如ESP32-WROOM-32)
- USB转串口线(用于烧录与查看日志)
- 杜邦线若干(用于将GPIO连接到GND或3.3V)
测试原理
将待测GPIO配置为输入模式并启用内部上拉电阻,读取电平应为高(1);随后启用内部下拉电阻,读取电平应为低(0)。若两种状态下读数均正确,说明引脚无短路、断路;若读数与预期不符,则判定引脚异常。此方法无需外部上拉/下拉电阻,仅依赖ESP32内部弱上拉/下拉,适合快速产线自检。
关键完整代码
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_log.h"
#define TEST_GPIO_MAX 40 // ESP32可用GPIO编号范围0~39
static const char *TAG = "GPIO_SELFTEST";
// 可测试的GPIO列表(排除电源、Flash、Strapping等不可用引脚)
static const gpio_num_t test_gpios[] = {
GPIO_NUM_0, GPIO_NUM_2, GPIO_NUM_4, GPIO_NUM_5,
GPIO_NUM_12, GPIO_NUM_13, GPIO_NUM_14, GPIO_NUM_15,
GPIO_NUM_16, GPIO_NUM_17, GPIO_NUM_18, GPIO_NUM_19,
GPIO_NUM_21, GPIO_NUM_22, GPIO_NUM_23, GPIO_NUM_25,
GPIO_NUM_26, GPIO_NUM_27, GPIO_NUM_32, GPIO_NUM_33,
GPIO_NUM_34, GPIO_NUM_35, GPIO_NUM_36, GPIO_NUM_39
};
#define TEST_GPIO_COUNT (sizeof(test_gpios) / sizeof(test_gpios[0]))
static bool test_single_gpio(gpio_num_t gpio) {
// 测试上拉:读高
gpio_set_direction(gpio, GPIO_MODE_INPUT);
gpio_set_pull_mode(gpio, GPIO_PULLUP_ONLY);
vTaskDelay(pdMS_TO_TICKS(10));
int level_pullup = gpio_get_level(gpio);
// 测试下拉:读低
gpio_set_pull_mode(gpio, GPIO_PULLDOWN_ONLY);
vTaskDelay(pdMS_TO_TICKS(10));
int level_pulldown = gpio_get_level(gpio);
// 恢复默认状态(无上下拉)
gpio_set_pull_mode(gpio, GPIO_FLOATING);
return (level_pullup == 1 && level_pulldown == 0);
}
void app_main(void) {
ESP_LOGI(TAG, "GPIO引脚功能自检开始");
int pass_count = 0;
int fail_count = 0;
for (int i = 0; i < TEST_GPIO_COUNT; i++) {
gpio_num_t gpio = test_gpios[i];
bool result = test_single_gpio(gpio);
if (result) {
pass_count++;
ESP_LOGI(TAG, "GPIO %d: PASS", gpio);
} else {
fail_count++;
ESP_LOGE(TAG, "GPIO %d: FAIL (上拉=%d, 下拉=%d)",
gpio,
gpio_get_level(gpio) == 1 ? 1 : 0, // 仅用于日志显示
gpio_get_level(gpio) == 0 ? 0 : 1);
}
}
ESP_LOGI(TAG, "测试完成: 通过 %d, 失败 %d", pass_count, fail_count);
if (fail_count == 0) {
ESP_LOGI(TAG, "结果: 全部通过");
} else {
ESP_LOGE(TAG, "结果: 存在失败引脚");
}
}
编译与烧录
idf.py set-target esp32
idf.py build
idf.py -p /dev/ttyUSB0 flash monitor
验证方法与判定标准
- 将ESP32开发板通过USB连接电脑,确保串口驱动已安装。
- 执行上述编译烧录命令,打开串口监视器(波特率默认115200)。
- 观察日志输出:每个GPIO引脚会打印PASS或FAIL状态。
- 通过标准:所有测试引脚均显示PASS,且最终汇总显示“通过 24, 失败 0”。
- 故障模拟验证:用杜邦线将某个被测引脚(如GPIO4)直接短接到GND,重新运行测试,该引脚应显示FAIL(因上拉读不到高电平),证明检测有效。
注意事项
- GPIO 6~11 连接外部Flash,GPIO 1、3 为UART0调试口,GPIO 34~39 仅支持输入模式(无内部上拉/下拉),因此上述列表已排除这些引脚。
- GPIO 0 为Strapping引脚,测试时需确保开发板未进入下载模式。
- 若某引脚FAIL,先检查是否因外部电路干扰(如开发板上的LED、按键等),必要时断开外设后重测。