在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寄存器

而在文件夹中有两个比较重要的头文件:
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_REGGPIO_OUT_W1TS_REG是地址的宏定义,在程序中只是一个字面常量,需要将其转换为无符号整型的指针,再对该指针进行解引用,取出该地址存放的数据,并将该数据的14bit位置一,代表的是将GPIO14清零/置一。

2、volatile关键字是为了该变量随时可能发生变化,提醒编译器与该变量有关的运算,不要进行编译优化,以免出错。

通过逻辑分析仪测量引脚电平波形,可以看到低电平约为113ns,高电平约为199ns
方式三

通过对比发现,直接通过寄存器地址对GPIO进行操作的方式是最快的,但是和对寄存器结构体对GPIO进行操作的方式相差不大,库函数操作的方式效率最低。

posted @ 2023-12-11 16:02  HAOstudio  阅读(1370)  评论(0编辑  收藏  举报