一般情况下我们可以用过 digitalWrite() 在 Arduino 中设置 GPIO 的 HIGH/LOW, 但是这种方法非常耗时。这里给出一种可以一次性设置多个 GPIO 的方法:
在 C:\Users\USERNAME\AppData\Local\Arduino15\packages\esp32\tools\esp32-arduino-libs\idf-release_v5.4-858a988d-v1-cn\esp32p4\include\soc\esp32p4\register\soc\gpio_struct.h 有如下定义:
extern gpio_dev_t GPIO;
typedef struct gpio_dev_t {
volatile gpio_bt_select_reg_t bt_select;
volatile gpio_out_reg_t out;
volatile gpio_out_w1ts_reg_t out_w1ts;
volatile gpio_out_w1tc_reg_t out_w1tc;
volatile gpio_out1_reg_t out1;
volatile gpio_out1_w1ts_reg_t out1_w1ts;
volatile gpio_out1_w1tc_reg_t out1_w1tc;
uint32_t reserved_01c;
volatile gpio_enable_reg_t enable;
volatile gpio_enable_w1ts_reg_t enable_w1ts;
volatile gpio_enable_w1tc_reg_t enable_w1tc;
volatile gpio_enable1_reg_t enable1;
volatile gpio_enable1_w1ts_reg_t enable1_w1ts;
volatile gpio_enable1_w1tc_reg_t enable1_w1tc;
volatile gpio_strap_reg_t strap;
volatile gpio_in_reg_t in;
volatile gpio_in1_reg_t in1;
volatile gpio_status_reg_t status;
volatile gpio_status_w1ts_reg_t status_w1ts;
volatile gpio_status_w1tc_reg_t status_w1tc;
volatile gpio_status1_reg_t status1;
volatile gpio_status1_w1ts_reg_t status1_w1ts;
volatile gpio_status1_w1tc_reg_t status1_w1tc;
volatile gpio_intr_0_reg_t intr_0;
volatile gpio_intr1_0_reg_t intr1_0;
volatile gpio_intr_1_reg_t intr_1;
volatile gpio_intr1_1_reg_t intr1_1;
volatile gpio_status_next_reg_t status_next;
volatile gpio_status_next1_reg_t status_next1;
volatile gpio_pin_reg_t pin[57];
volatile gpio_func_in_sel_cfg_reg_t func_in_sel_cfg[256]; /* func0-func255: reserved for func0, 46, 67, 72, 73, 79, 81, 82, 84, 85, 87, 88, 115, 116, 119-125, 157, 204-213 */
volatile gpio_func_out_sel_cfg_reg_t func_out_sel_cfg[57];
volatile gpio_intr_2_reg_t intr_2;
volatile gpio_intr1_2_reg_t intr1_2;
volatile gpio_intr_3_reg_t intr_3;
volatile gpio_intr1_3_reg_t intr1_3;
volatile gpio_clock_gate_reg_t clock_gate;
uint32_t reserved_650[44];
volatile gpio_int_raw_reg_t int_raw;
volatile gpio_int_st_reg_t int_st;
volatile gpio_int_ena_reg_t int_ena;
volatile gpio_int_clr_reg_t int_clr;
volatile gpio_zero_det_filter_cnt_reg_t zero_det_filter_cnt[2];
volatile gpio_send_seq_reg_t send_seq;
volatile gpio_recive_seq_reg_t recive_seq;
volatile gpio_bistin_sel_reg_t bistin_sel;
volatile gpio_bist_ctrl_reg_t bist_ctrl;
uint32_t reserved_728[53];
volatile gpio_date_reg_t date;
} gpio_dev_t;
其中的out_w1ts 和 out_w1tc 可以用来一次性设置多个 GPIO 为高或者为低。
测试代码:
#include "soc/gpio_struct.h" // GPIO
void setup() {
pinMode(7,OUTPUT);pinMode(8,OUTPUT);
pinMode(30,OUTPUT);pinMode(32,OUTPUT);pinMode(33,OUTPUT);pinMode(49,OUTPUT);
pinMode(50,OUTPUT);pinMode(52,OUTPUT);
digitalWrite(7,LOW);digitalWrite(8,LOW);
digitalWrite(30,LOW);digitalWrite(32,LOW);digitalWrite(33,LOW);digitalWrite(49,LOW);
digitalWrite(50,LOW);digitalWrite(52,LOW);
}
void loop() {
GPIO.out_w1ts.val = (1<<30)|(1<<8)|(1<<7);
GPIO.out1_w1ts.val=(1<<(33-32))|(1<<(32-32))|(1<<(52-32))|(1<<(49-32))|(1<<(50-32));
GPIO.out_w1tc.val = (1<<30)|(1<<8)|(1<<7);
GPIO.out1_w1tc.val=(1<<(33-32))|(1<<(32-32))|(1<<(52-32))|(1<<(49-32))|(1<<(50-32));
delay(1000);
}
硬件上GPIO33, 32, 30, 8, 7, 52, 49, 50分别连接到逻辑分析的4-11通道。
其中的 GPIO 初始化使用 Arduino 代码来完成,GPIO 的设置直接使用位操作。超过31的GPIO要在out1_w1ts和out1_w1tc上设置。
最终抓到的结果可以从下面看到:

参考:
1.https://github.com/maarten-pennings/howto/blob/main/esp32-fast-gpio/esp32-fast-gpio.md