在Arduino环境下对ESP32进行寄存器操作和区别比较
在Arduino环境下对ESP32进行寄存器操作和区别比较
前言
这篇文章主要是对在Arduino环境下如何对ESP32进行寄存器操作进行了相关的说明。并且比较了在不同编程方式下GPIO口的电平翻转速度,这可以更加直观的不同编程方式下的代码运行效率。(平台是VScode,使用Platformio下的Arduino固件对ESP32进行编程)
寄存器操作
如果你在VScode上安装了ESP32的Arduino固件,你将会在下面的所示的文件路径中找到寄存器相关的头文件:
C:\Users\用户名\.platformio\packages\framework-arduinoespressif32\tools\sdk\esp32\include\soc\esp32\include\soc
(将用户名修改为自己电脑的用户)
以GPIO相关的寄存器为例:
通过查看ESP32的参考手册,可以得到GPIO的相关寄存器,每个寄存器都对应有不同的地址:
而在文件夹中有两个比较重要的头文件:
gpio_reg.h
:将GPIO相关的寄存器地址通过宏定义定义了出来,可以对寄存器直接进行操作。
gpio_struct.h
:将GPIO相关的寄存器通过结构体的方式定义了出来,可以通过结构体进行访问。
GPIO的寄存器操作
通过3种不同编程方式下GPIO口的电平翻转速度进行了测量:
方式一:通过库函数对GPIO进行操作
#include <Arduino.h>
const int gpio_pin = 14;
void setup() {
pinMode(gpio_pin, OUTPUT);
digitalWrite(gpio_pin, HIGH);
delay(500);
}
void loop() {
//1 通过库函数对GPIO进行操作
digitalWrite(gpio_pin, LOW); //set 0
digitalWrite(gpio_pin, HIGH); //set 1
}
通过逻辑分析仪测量引脚电平波形,可以看到低电平约为325ns
,高电平约为439ns
。
方式二:通过定义的寄存器结构体对GPIO进行操作
#include <Arduino.h>
const int gpio_pin = 14;
void setup() {
pinMode(gpio_pin, OUTPUT);
digitalWrite(gpio_pin, HIGH);
delay(500);
}
void loop() {
//2 通过定义的寄存器结构体对GPIO进行操作
GPIO.out_w1tc |= (1<<14); //set 0
GPIO.out_w1ts |= (1<<14); //set 1
}
通过逻辑分析仪测量引脚电平波形,可以看到低电平约为125ns
,高电平约为201ns
。
方式三:直接通过寄存器地址对GPIO进行操作
#include <Arduino.h>
const int gpio_pin = 14;
void setup() {
pinMode(gpio_pin, OUTPUT);
digitalWrite(gpio_pin, HIGH);
delay(500);
}
void loop() {
//3 直接通过寄存器地址对GPIO进行操作
*(volatile unsigned int*)GPIO_OUT_W1TC_REG |= (1<<14);
*(volatile unsigned int*)GPIO_OUT_W1TS_REG |= (1<<14);
}
1、
GPIO_OUT_W1TC_REG
和GPIO_OUT_W1TS_REG
是地址的宏定义,在程序中只是一个字面常量,需要将其转换为无符号整型的指针,再对该指针进行解引用,取出该地址存放的数据,并将该数据的14bit位置一,代表的是将GPIO14清零/置一。2、
volatile
关键字是为了该变量随时可能发生变化,提醒编译器与该变量有关的运算,不要进行编译优化,以免出错。
通过逻辑分析仪测量引脚电平波形,可以看到低电平约为113ns
,高电平约为199ns
。
通过对比发现,直接通过寄存器地址对GPIO进行操作的方式是最快的,但是和对寄存器结构体对GPIO进行操作的方式相差不大,库函数操作的方式效率最低。