根据上一篇博客,成功搭建好ESP8266在Linux下的开发环境后,正式开始入坑8266的学习和使用;本文基于NodeMCU进行学习,NodeMCU是一款开源的物联网平台,底层使用ESP8266 sdk 0.9.5版本。该平台使用了很多开源项目, 例如 lua-cjson, spiffs. NodeMCU包含了可以运行在 esp8266 Wi-Fi SoC芯片之上的固件,以及基于ESP-12模组的硬件。
Label | GPIO | Input | Output | Notes |
---|---|---|---|---|
D0 | GPIO16 | no interrupt | no PWM or I2C support | HIGH at boot used to wake up from deep sleep |
D1 | GPIO5 | OK | OK | often used as SCL (I2C) |
D2 | GPIO4 | OK | OK | often used as SDA (I2C) |
D3 | GPIO0 | pulled up | OK | connected to FLASH button, boot fails if pulled LOW |
D4 | GPIO2 | pulled up | OK | HIGH at boot connected to on-board LED, boot fails if pulled LOW |
D5 | GPIO14 | OK | OK | SPI (SCLK) |
D6 | GPIO12 | OK | OK | SPI (MISO) |
D7 | GPIO13 | OK | OK | SPI (MOSI) |
D8 | GPIO15 | pulled to GND | OK | SPI (CS) Boot fails if pulled HIGH |
RX | GPIO3 | OK | RX pin | HIGH at boot |
TX | GPIO1 | TX pin | OK | HIGH at boot debug output at boot, boot fails if pulled LOW |
A0 | ADC0 | Analog Input | X |
GPIO6至GPIO11通常连接到ESP8266板上的flash芯片。因此,不建议使用这些引脚。
使用ESP8266的GPIO最起码得包含相关引脚的头文件吧
#include "driver/gpio.h"
GPIO的初始化设置与STM32提供的标准库大同小异,都是通过一个结构体来进行配置,如下:
typedef struct {
uint32_t pin_bit_mask; /*!< GPIO pin: 配置某一号管脚 */
gpio_mode_t mode; /*!< GPIO mode: 设置输入输出模式de */
gpio_pullup_t pull_up_en; /*!< GPIO pull-up:使能上拉 */
gpio_pulldown_t pull_down_en; /*!< GPIO pull-down:使能下拉 */
gpio_int_type_t intr_type; /*!< GPIO interrupt type:是否使能中断,并配置中断模式 */
} gpio_config_t;
中断模式:
typedef enum {
GPIO_INTR_DISABLE = 0, /*!< Disable GPIO interrupt 失能中断*/
GPIO_INTR_POSEDGE = 1, /*!< GPIO interrupt type : 上升沿触发 */
GPIO_INTR_NEGEDGE = 2, /*!< GPIO interrupt type : 下降沿触发 */
GPIO_INTR_ANYEDGE = 3, /*!< GPIO interrupt type : 双边沿触发 */
GPIO_INTR_LOW_LEVEL = 4, /*!< GPIO interrupt type : 输入低电平触发 */
GPIO_INTR_HIGH_LEVEL = 5, /*!< GPIO interrupt type : 输入高电平触发 */
GPIO_INTR_MAX,
} gpio_int_type_t;c
用例1(不开启中断)
#define GPIO_OUTPUT_IO_0 15
#define GPIO_OUTPUT_IO_1 16
#define GPIO_OUTPUT_PIN_SEL ((1ULL<
//1ULL-->unsigned long long
void app_main(void)
{
gpio_config_t io_conf; //创建一个GPIO结构体
io_conf.intr_type = GPIO_INTR_DISABLE; //失能中断服务
io_conf.mode = GPIO_MODE_OUTPUT; //设置成输出模式
io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL; //指定要配置的GPIO
io_conf.pull_down_en = 0; //不使能下拉
io_conf.pull_up_en = 0; //不使能上拉
gpio_config(&io_conf); //配置GPIO
}
用例2(开启中断)
void app_main(void)
{
io_conf.intr_type = GPIO_INTR_POSEDGE; //设置中断类型为上升沿触发
io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL; //GPIO引脚
io_conf.mode = GPIO_MODE_INPUT; //设置GPIO模式
io_conf.pull_up_en = 1; //使能上拉
gpio_config(&io_conf); //配置GPIO
//改变指定的GPIO中断触发方式为双边沿触发,将GPIO_INPUT_IO_0的中断触发改为双边沿触发
gpio_set_intr_type(GPIO_INPUT_IO_0, GPIO_INTR_ANYEDGE);
gpio_install_isr_service(0); //安装GPIO中断服务程序,即使能中断
//配置某管脚中断事件触发的回调函数,参数:GPIO引脚,指定中断处理函数,传递给处理函数的参数
gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void *) GPIO_INPUT_IO_0);
gpio_isr_handler_add(GPIO_INPUT_IO_1, gpio_isr_handler, (void *) GPIO_INPUT_IO_1);
//移除对应的GPIO中断处理程序,此处移除GPIO_INPUT_IO_0中断触发的回调函数
gpio_isr_handler_remove(GPIO_INPUT_IO_0);
}
设置GPIO输出电平
//参数:GPIO编号,输出电平状态:0低电平,1高电平,返回的是成功与否状态码
esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level);
读取GPIO引脚电平
//参数:GPIO编号,返回的是电平状态
int gpio_get_level(gpio_num_t gpio_num);
gpio_isr_register 与 gpio_install_isr_service的区别
gpio_isr_register 函数是统一为所有的GPIO口注册一个全局的ISR,即任何的GPIO中断触发,都会调用该中断处理函数;
esp_err_t gpio_isr_register(void (*fn)(void *), void *arg, int no_use, gpio_isr_handle_t *handle_no_use);
参数 | 解析 |
---|---|
fn | 中断处理函数。 |
arg | 传递给中断处理函数的参数。 |
no_use | no_use为了与esp32兼容,这个参数没有实际意义,可以用0来填充。 |
handle_no_use | 指针返回句柄。为了与esp32兼容,这个参数没有实际意义,可以用NULL来填充。 |
gpio_install_isr_service函数与gpio_isr_register不兼容,gpio_install_isr_service主要是开启中断服务,不针对某一个GPIO,需要搭配gpio_isr_handler_add使用;
esp_err_t gpio_install_isr_service(int no_use);
此处的no_use为了与esp32兼容,这个参数没有实际意义,可以用0来填充。
esp_err_t gpio_isr_handler_add(gpio_num_t gpio_num, gpio_isr_t isr_handler, void *args);
参数 | 解析 |
---|---|
gpio_num | 指定GPIO口 |
isr_handler | 对应的中断处理函数 |
args | 传递给中断处理函数的参数 |
更多接口原型,可以查看SDK目录/include/driver/gpio.h
我的GITHUB
我的个人博客
CSDN