第 3 篇:GPIO + 传感器驱动——让 ESP32 感知世界


1. GPIO 输入输出

#include "driver/gpio.h"

// 输出:LED
gpio_set_direction(GPIO_NUM_8, GPIO_MODE_OUTPUT);
gpio_set_level(GPIO_NUM_8, 1);  // 亮
gpio_set_level(GPIO_NUM_8, 0);  // 灭

// 输入:按键(带内部上拉)
gpio_set_direction(GPIO_NUM_9, GPIO_MODE_INPUT);
gpio_set_pull_mode(GPIO_NUM_9, GPIO_PULLUP_ONLY);
int level = gpio_get_level(GPIO_NUM_9);  // 0=按下

// 中断:按键中断
gpio_set_intr_type(GPIO_NUM_9, GPIO_INTR_NEGEDGE);  // 下降沿触发
gpio_install_isr_service(0);
gpio_isr_handler_add(GPIO_NUM_9, button_isr_handler, NULL);

2. I2C 读取 SHT30 温湿度传感器

#include "driver/i2c.h"

#define I2C_MASTER_SCL_IO   GPIO_NUM_6
#define I2C_MASTER_SDA_IO   GPIO_NUM_7
#define SHT30_ADDR          0x44

void sht30_init(void) {
    i2c_config_t conf = {
        .mode = I2C_MODE_MASTER,
        .sda_io_num = I2C_MASTER_SDA_IO,
        .scl_io_num = I2C_MASTER_SCL_IO,
        .sda_pullup_en = GPIO_PULLUP_ENABLE,
        .scl_pullup_en = GPIO_PULLUP_ENABLE,
        .master.clk_speed = 100000,
    };
    i2c_param_config(I2C_NUM_0, &conf);
    i2c_driver_install(I2C_NUM_0, I2C_MODE_MASTER, 0, 0, 0);
}

esp_err_t sht30_read(float *temp, float *humidity) {
    uint8_t cmd[2] = {0x2C, 0x06};  // 高精度测量命令
    uint8_t data[6];

    i2c_master_write_to_device(I2C_NUM_0, SHT30_ADDR, cmd, 2, pdMS_TO_TICKS(100));
    vTaskDelay(pdMS_TO_TICKS(20));  // 等待测量完成
    i2c_master_read_from_device(I2C_NUM_0, SHT30_ADDR, data, 6, pdMS_TO_TICKS(100));

    uint16_t raw_temp = (data[0] << 8) | data[1];
    uint16_t raw_humi = (data[3] << 8) | data[4];

    *temp = -45.0f + 175.0f * raw_temp / 65535.0f;
    *humidity = 100.0f * raw_humi / 65535.0f;
    return ESP_OK;
}

3. SPI 读取 BMP280 大气压传感器

spi_bus_config_t bus_cfg = {
    .mosi_io_num = GPIO_NUM_11,
    .miso_io_num = GPIO_NUM_13,
    .sclk_io_num = GPIO_NUM_12,
    .quadwp_io_num = -1,
    .quadhd_io_num = -1,
};
spi_bus_initialize(SPI2_HOST, &bus_cfg, SPI_DMA_CH_AUTO);

spi_device_interface_config_t dev_cfg = {
    .clock_speed_hz = 1 * 1000 * 1000,  // 1 MHz
    .mode = 0,
    .spics_io_num = GPIO_NUM_10,
    .queue_size = 1,
};
spi_bus_add_device(SPI2_HOST, &dev_cfg, &spi_handle);

// 读寄存器
uint8_t tx[2] = {0xFA | 0x80, 0};  // 0xFA = 温度寄存器, 0x80 = 读标志
uint8_t rx[3];
spi_transaction_t trans = {
    .length = 24,
    .tx_buffer = tx,
    .rx_buffer = rx,
};
spi_device_transmit(spi_handle, &trans);

int32_t raw_temp = (rx[1] << 12) | (rx[2] << 4);
// BMP280 数据手册的补偿公式...

4. 三个传感器同时采集的完整任务

void sensor_task(void *pv) {
    float temp, humi, pressure;
    TickType_t last = xTaskGetTickCount();

    for (;;) {
        sht30_read(&temp, &humi);
        bmp280_read(&pressure);
        printf("T:%.1fC H:%.1f%% P:%.1fhPa\n", temp, humi, pressure);
        vTaskDelayUntil(&last, pdMS_TO_TICKS(5000));  // 每 5 秒
    }
}

下一篇:WiFi 连接——让 ESP32 上网

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐