05 - GPIO 外设
通用输入输出与PWM控制
GPIO 基础
初始化与配置
#include "driver/gpio.h"
// 复位指定GPIO
gpio_reset_pin (GPIO_NUM_2);
// 设置方向
gpio_set_direction (GPIO_NUM_2, GPIO_MODE_OUTPUT);
// 设置方向 (输入)
gpio_set_direction (GPIO_NUM_4, GPIO_MODE_INPUT);
// 设置上拉/下拉
gpio_set_pull_mode (GPIO_NUM_4, GPIO_PULLUP_ONLY); // 上拉
gpio_set_pull_mode (GPIO_NUM_4, GPIO_PULLDOWN_ONLY); // 下拉
gpio_set_pull_mode (GPIO_NUM_4, GPIO_FLOATING); // 浮空
读写操作
// 输出电平
gpio_set_level (GPIO_NUM_2, 1 ); // 高电平
gpio_set_level (GPIO_NUM_2, 0 ); // 低电平
// 读取电平
int level = gpio_get_level (GPIO_NUM_4);
// 读取模式
gpio_mode_t mode = gpio_get_mode (GPIO_NUM_4);
中断处理
中断配置
#include "driver/gpio.h"
#include "esp_intr_alloc.h"
static IRAM_ATTR void gpio_isr_handler ( void * arg )
{
uint32_t gpio_num = ( uint32_t ) arg;
printf ( "GPIO %d interrupted! \n " , gpio_num);
}
void setup_gpio_interrupt ( void )
{
gpio_config_t io_conf = {
.pin_bit_mask = ( 1 ULL << GPIO_NUM_4),
.mode = GPIO_MODE_INPUT,
.pull_up_en = GPIO_PULLUP_ENABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_POSEDGE // 上升沿触发
};
gpio_config ( & io_conf);
gpio_install_isr_service ( 0 );
gpio_isr_handler_add (GPIO_NUM_4, gpio_isr_handler, ( void * ) GPIO_NUM_4);
}
中断触发类型
模式 说明 GPIO_INTR_DISABLE 禁用中断 GPIO_INTR_POSEDGE 上升沿触发 GPIO_INTR_NEGEDGE 下降沿触发 GPIO_INTR_ANYEDGE 任意边沿触发 GPIO_INTR_LOW_LEVEL 低电平触发 GPIO_INTR_HIGH_LEVEL 高电平触发
LEDC (PWM)
PWM 输出配置
#include "driver/ledc.h"
void ledc_pwm_init ( void )
{
// 配置定时器
ledc_timer_config_t timer_conf = {
.speed_mode = LEDC_LOW_SPEED_MODE,
.timer_num = LEDC_TIMER_0,
.duty_resolution = LEDC_TIMER_8_BIT, // 8位分辨率 (0-255)
.freq_hz = 1000 , // 1kHz
.clk_cfg = LEDC_AUTO_CLK
};
ledc_timer_config ( & timer_conf);
// 配置通道
ledc_channel_config_t channel_conf = {
.gpio_num = GPIO_NUM_2,
.speed_mode = LEDC_LOW_SPEED_MODE,
.channel = LEDC_CHANNEL_0,
.timer_sel = LEDC_TIMER_0,
.duty = 0 ,
.hpoint = 0
};
ledc_channel_config ( & channel_conf);
}
// 设置占空比
void ledc_set_duty ( uint8_t duty )
{
ledc_set_duty (LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, duty);
ledc_update_duty (LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0);
}
呼吸灯效果
void breathe_ledc ( void )
{
int direction = 1 ;
int duty = 0 ;
while ( 1 ) {
duty += direction * 5 ;
if (duty >= 255 ) direction = - 1 ;
if (duty <= 0 ) direction = 1 ;
ledc_set_duty (LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, duty);
ledc_update_duty (LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0);
vTaskDelay ( pdMS_TO_TICKS ( 20 ));
}
}
DAC 输出
数模转换
#include "driver/dac.h"
// 初始化 DAC1 (GPIO25)
void dac_init ( void )
{
dac_output_enable (DAC_CHANNEL_1);
}
// 输出电压 (0-255 对应 0-3.3V)
void dac_output ( uint8_t value )
{
dac_output_voltage (DAC_CHANNEL_1, value);
}
// 输出正弦波示例
void dac_sine_wave ( void )
{
int i = 0 ;
while ( 1 ) {
uint8_t value = ( sin (i * 0.1 ) + 1 ) * 127 ; // 0-254
dac_output_voltage (DAC_CHANNEL_1, value);
vTaskDelay ( pdMS_TO_TICKS ( 10 ));
i ++ ;
}
}
DAC 参数
通道 GPIO 分辨率 DAC1 GPIO25 8-bit DAC2 GPIO26 8-bit
ADC 采样
模数转换
#include "driver/adc.h"
#include "esp_adc_cal.h"
#define ADC_PIN ADC1_CHANNEL_7 // GPIO35
void adc_init ( void )
{
adc1_config_width (ADC_WIDTH_BIT_12); // 12位分辨率
adc1_config_channel_atten (ADC_PIN, ADC_ATTEN_DB_11); // 0-3.3V
}
uint32_t adc_read ( void )
{
return adc1_get_raw (ADC_PIN);
}
// 带校准读取
void adc_read_calibrated ( void )
{
esp_adc_cal_characteristics_t chars;
esp_adc_cal_characterize (ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12, 1100 , & chars);
uint32_t voltage = esp_adc_cal_raw_to_voltage ( adc1_get_raw (ADC_PIN), & chars);
printf ( "Voltage: %u mV \n " , voltage);
}
ADC 参数
参数 值 分辨率 9/10/11/12 位 衰减 0-3.3V / 0-2.6V / 0-1.7V / 0-1.1V 采样率 ~ 6kHz
ADC1 通道映射
通道 GPIO 用途 ADC1_CH0 GPIO36 外部输入 ADC1_CH1 GPIO37 外部输入 ADC1_CH2 GPIO38 外部输入 ADC1_CH3 GPIO39 外部输入 ADC1_CH4 GPIO32 外部输入 ADC1_CH5 GPIO33 外部输入 ADC1_CH6 GPIO34 外部输入 ADC1_CH7 GPIO35 外部输入
触摸传感器
#include "driver/touch_pad.h"
void touch_init ( void )
{
touch_pad_init ();
touch_pad_config (TOUCH_PAD_NUM4, 0 ); // GPIO4
}
void touch_read ( void )
{
uint16_t touch_value;
touch_pad_read_filtered (TOUCH_PAD_NUM4, & touch_value);
printf ( "Touch value: %d\n " , touch_value);
}
参考资料
官方文档
技术参考
图片参考
相关链接
反向链接
进阶学习
下一步