版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_15647227/article/details/52218286
前言
GPIO中断在进行脉宽测量、脉冲计数时能起到极为重要的作用,本文主要介绍GPIO中断的用法,使用一个开关打开或关闭一个LED灯。
GPIO寄存器介绍
一、GPIO输入寄存器
寄存器名称 |
功能说明 |
寄存器大小 |
寄存器属性 |
参数说明 |
GPIO_IN |
输入状态寄存器 |
16Bit |
读写 |
对应GPIO0-GPIO15 |
GPIO_PIN12 |
中断类型寄存器 |
16Bit |
读写 |
0:禁用该GPIO的中断 1:上升沿触发中断 2:下降沿触发中断 3:双边沿触发中断 4:低电平触发中断 5:高电平触发中断 |
GPIO_STATUS |
中断状态寄存器 |
16Bit |
读写 |
对应GPIO0-GPIO15 |
GPIO_STATUS_W1TC |
复位中断标志寄存器 |
16Bit |
读写 |
对应GPIO0-GPIO15 |
二、GPIO输出寄存器
寄存器名称 |
功能说明 |
寄存器大小 |
寄存器属性 |
参数说明 |
GPIO_ENABLE_W1TS |
使能输出寄存器 |
16Bit |
读写 |
对应GPIO0-GPIO15 |
GPIO_ENABLE_W1TC |
禁用输出寄存器 |
16Bit |
读写 |
对应GPIO0-GPIO15 |
GPIO_ENABLE |
输出使能状态寄存器 |
16Bit |
读写 |
对应GPIO0-GPIO15 |
GPIO_OUT_W1TC |
输出低电平寄存器 |
16Bit |
只读 |
对应GPIO0-GPIO15 |
GPIO_OUT_W1TS |
输出高电平寄存器 |
16Bit |
读写 |
对应GPIO0-GPIO15 |
GPIO_OUT |
输出状态寄存器 |
16Bit |
读写 |
对应GPIO0-GPIO15 |
注:GPIO16不支持触发IO中断。
相关API介绍
一、引脚复用功能切换函数
功能介绍 |
配置某引脚的其他功能 |
- |
函数原型 |
PIN_FUNC_SELECT(PIN_NAME, FUNC) |
宏函数 |
参数介绍 |
PIN_NAME |
该引脚的MUX寄存器 |
- |
FUNC |
引脚需要配置的功能 |
参数枚举 |
关于PIN_NAME的参数详见eagle_soc.h,关于FUNC的参数详见ESP8266 管脚清单.xlsx(在官网上可以找到当然页可以参考eagle_soc.h)。 |
- |
示例 |
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U,FUNC_GPIO4); |
配置MTDI引脚作为GPIO使用 |
二、输入模式配置
功能介绍 |
配置某引脚为输入模式 |
- |
函数原型 |
GPIO_DIS_OUTPUT(gpio_no) |
宏函数 |
参数介绍 |
gpio_no |
GPIO的引脚号(0-15) |
示例 |
GPIO_DIS_OUTPUT(0); |
配置GPIO0为输入模式 |
三、上拉模式配置
功能介绍 |
开启某引脚上拉模式 |
- |
函数原型 |
PIN_PULLUP_EN(PIN_NAME) |
宏函数 |
参数介绍 |
PIN_NAME |
该引脚的MUX寄存器的名称 |
示例 |
PIN_PULLUP_EN(PERIPHS_IO_MUX_GPIO4_U); |
开启GPIO4的上拉输入功能 |
- |
- |
- |
功能介绍 |
关闭某引脚上拉模式 |
- |
函数原型 |
PIN_PULLUP_DIS(PIN_NAME) |
宏函数 |
参数介绍 |
PIN_NAME |
该引脚的MUX寄存器的名称 |
示例 |
PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO4_U); |
关闭GPIO4的上拉输入功能 |
四、获取输入引脚状态
功能介绍 |
读取某引脚的高低电平状态 |
- |
函数原型 |
GPIO_INPUT_GET(gpio_no) |
宏函数 |
参数介绍 |
gpio_no |
GPIO的引脚号(0-15) |
示例 |
GPIO_INPUT_GET(0); |
读取GPIO0的输入引脚状态 |
五、GPIO中断状态配置
功能介绍 |
开启GPIO中断 |
- |
函数原型 |
ETS_GPIO_INTR_ENABLE() |
宏函数 |
- |
- |
- |
功能介绍 |
关闭GPIO中断 |
- |
函数原型 |
ETS_GPIO_INTR_DISABLE() |
宏函数 |
六、配置中断处理函数
功能介绍 |
配置中断处理函数 |
- |
函数原型 |
ETS_GPIO_INTR_ATTACH(GPIO_INTERRUPT,NULL) |
宏函数 |
参数介绍 |
GPIO_INTERRUPT |
GPIO的中断处理函数 |
参数介绍 |
NULL |
GPIO的中断服务函数的参数 |
示例
void GPIO_ISR_Handler( void )
{
/** GPIO中断处理函数 */
}
void GPIO_ISR_Handler_Config( void )
{
ETS_GPIO_INTR_ATTACH(&GPIO_ISR_Handler,NULL);
}
七、配置GPIO中断触发方式
功能介绍 |
配置GPIO中断触发方式 |
- |
函数原型 |
void gpio_pin_intr_state_set(uint32 i, GPIO_INT_TYPE intr_state); |
- |
参数介绍 |
i(GPIO_ID_PIN(n)) |
GPIO的引脚ID(n为GPIO引脚号,范围为0-15) |
- |
intr_state |
GPIO中断触发方式 |
参数枚举 |
GPIO_PIN_INTR_DISABLE(0) |
禁用该引脚的中断 |
- |
GPIO_PIN_INTR_POSEDGE(1) |
使能该引脚的上升沿中断 |
- |
GPIO_PIN_INTR_NEGEDGE(2) |
使能该引脚的下降沿中断 |
- |
GPIO_PIN_INTR_ANYEDGE(3) |
使能该引脚的双边沿中断 |
- |
GPIO_PIN_INTR_LOLEVEL(4) |
使能该引脚的低电平中断 |
- |
GPIO_PIN_INTR_HILEVEL(5) |
使能该引脚的高电平中断 |
示例 |
gpio_pin_intr_state_set(GPIO_ID_PIN(0),GPIO_PIN_INTR_ANYEDGE); |
配置GPIO0的中断触发方式为双边沿触发方式 |
示例
#include "ets_sys.h"
#include "osapi.h"
#include "user_interface.h"
#include "eagle_soc.h"
#include "gpio.h"
#include "gpio16.h"
/** 开关输入相关 宏定义 */
#define SWITCH_Pin_NUM 5
#define SWITCH_Pin_FUNC FUNC_GPIO5
#define SWITCH_Pin_MUX PERIPHS_IO_MUX_GPIO5_U
#define SWITCH_Pin_Rd_Init() GPIO_DIS_OUTPUT(SWITCH_Pin_NUM)
#define SWITCH_Pin_Wr_Init() GPIO_OUTPUT_SET(SWITCH_Pin_NUM,0)
#define SWITCH_Pin_Set_High() GPIO_OUTPUT_SET(SWITCH_Pin_NUM,1)
#define SWITCH_Pin_Set_Low() GPIO_OUTPUT_SET(SWITCH_Pin_NUM,0)
#define SWITCH_Pin_State ( GPIO_INPUT_GET(SWITCH_Pin_NUM) != 0 )
/**
*******************************************************************************
* @brief GPIO中断处理函数
* @param [in/out] void
* @return void
* @note None
*******************************************************************************
*/
static void GPIO_ISR_Handler( void )
{
/** 读取GPIO中断状态 */
u32 pin_status = GPIO_REG_READ( GPIO_STATUS_ADDRESS );
/** 关闭GPIO中断 */
ETS_GPIO_INTR_DISABLE();
/** 清除GPIO中断标志 */
GPIO_REG_WRITE( GPIO_STATUS_W1TC_ADDRESS, pin_status );
/** 检测是否已开关输入引脚中断 */
if ( pin_status & BIT( SWITCH_Pin_NUM ) )
{
if( SWITCH_Pin_State )
{
gpio16_output_set(0);
}
else
{
gpio16_output_set(1);
}
}
/** 开启GPIO中断 */
ETS_GPIO_INTR_ENABLE();
}
/**
*******************************************************************************
* @brief 输入初始化函数
* @param [in/out] void
* @return void
* @note None
*******************************************************************************
*/
static void drv_Input_Init( void )
{
PIN_FUNC_SELECT( SWITCH_Pin_MUX, SWITCH_Pin_FUNC );
SWITCH_Pin_Rd_Init();
ETS_GPIO_INTR_DISABLE();
ETS_GPIO_INTR_ATTACH( &GPIO_ISR_Handler, NULL );
gpio_pin_intr_state_set( GPIO_ID_PIN( SWITCH_Pin_NUM ),
GPIO_PIN_INTR_ANYEDGE );
/** 清除该引脚的GPIO中断标志 */
GPIO_REG_WRITE( GPIO_STATUS_W1TC_ADDRESS, BIT(SWITCH_Pin_NUM) );
ETS_GPIO_INTR_ENABLE();
}
/**
*******************************************************************************
* @brief 用户初始化程序
* @param [in/out] void
* @return void
* @note None
*******************************************************************************
*/
void user_init( void )
{
drv_Input_Init();
gpio16_output_conf();
}
参考资料
[1]. ESP8266技术参考
[2]. ESP8266Non-OS SDK API参考
[3]. ESP8266 管脚清单