外部中断只针对于输入设备,当设备输入时的IO口电平发送变化时,调用相对应的IO的外部中断函数或者寄存器就会进入到IO口的外部中断控制。
当配置完成时,加入需要对外部IO口变化之后进行操作时,通常的单片机需要外部中断服务函数控制,但是我们的ESP8266单片机不需要外部中断服务函数,它需要的是一个回调函数,而且它的回调函数是需要声明的。
函数原型:ETS_GPIO_INTR_ATTACH(func, arg)
#define ETS_GPIO_INTR_ATTACH(func, arg) ets_isr_attach(ETS_GPIO_INUM, (func), (void *)(arg))
void ets_isr_attach(int i, ets_isr_t func, void *arg);
函数功能:注册GPIO中断处理函数`在这里插入代码片`
函数形参:
func:中断服务函数名称
arg:
返回值:无
例子:ETS_GPIO_INTR_ATTACH(KeyExtiInterruptFunction, NULL);
函数原型:ETS_GPIO_INTR_DISABLE()
函数功能:关闭GPIO中断功能
函数形参:无
返回值: 无
函数原型:ETS_GPIO_INTR_ENABLE()
函数功能:打开GPIO中断功能
函数形参:无
返回值: 无
函数原型:void gpio_pin_intr_state_set(uint32 i, GPIO_INT_TYPE intr_state)
函数功能:设置GPIO中断出发状态
函数形参:
uint32 i:GPIO引脚的ID
可填参数:GPIO_ID_PIN(x) //x表示要设置的引脚号
GPIO_INT_TYPE intr_state:中断触发方式;
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_NEGEDGE);//设置GPIO0为下降沿触发进入中断
函数原型:GPIO_REG_READ(reg)
以上函数为宏定义:
#define GPIO_REG_READ(reg) READ_PERI_REG(PERIPHS_GPIO_BASEADDR + reg)
#define PERIPHS_GPIO_BASEADDR 0x60000300
#define READ_PERI_REG(addr) (*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr)))
#define ETS_UNCACHED_ADDR(addr) (addr)
函数功能:获取GPIO中断状态
函数形参:
reg:乐鑫官方文档提供的地址形参为GPIO_STATUS_ADDRESS
#define GPIO_STATUS_ADDRESS 0x1c
返回值:所有GPIO口的中断状态
官方举例:
uint32 gpio_status;
gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
注:官方标明该文件必须添加在GPIO中断处理函数内
函数原型:GPIO_REG_WRITE(reg, val)
以上函数为宏定义:
#define GPIO_REG_WRITE(reg, val) WRITE_PERI_REG(PERIPHS_GPIO_BASEADDR + reg, val)
#define PERIPHS_GPIO_BASEADDR 0x60000300
#define WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr))) = (uint32_t)(val)
#define ETS_UNCACHED_ADDR(addr) (addr)
函数功能:清除GPIO中断状态->退出中断
函数形参:
reg:乐鑫官方文档提供的地址形参为GPIO_STATUS_ADDRESS
val:GPIO_REG_READ()函数的返回值
返回值:无
官方举例:GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status);
//user_mian.c源代码
void ICACHE_FLASH_ATTR user_init(void)
{
system_soft_wdt_feed();//喂软件看门狗,防止程序跑偏
uart_init(9600, 9600);//设置串口波特率
LedInitConfig();//LED灯初始化函数
KeyInitConfig();//按键初始化函数
KeyExtiInitConfig();//配置按键外部中断
os_printf("=============================================\r\n");
os_printf("\t SDK version:\t%s", system_get_sdk_version());
os_printf("\r\n嵌入式陈工个人编辑资料\r\n未经本人同意请勿私自传播\r\n");
os_printf("\r\n按键外部中断测试代码\r\n");
os_printf("\r\n带看门狗\r\n");
os_printf("=============================================\r\n");
}
//key.c源代码
/*
* key.c
*
* Created on: 2018年8月10日
* Author: 小良哥
*/
#include "driver/key.h"
#include "driver/led.h"
#include "ets_sys.h" // 回调函数
void KeyInitConfig(void)
{
//1.设置按键所对应的GPIO0口为IO口模式 -- 详见文档3.3.1.1章节
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0); // GPIO0设为IO口
//2.由于GPIO0通过R3进行电源上拉,所以GPIO0默认为高电平状态,在这里要将内部拉高取消
PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO0_U);
//3.设定GPIO0引脚为输入模式
GPIO_DIS_OUTPUT(GPIO_ID_PIN(0));
}
void KeyExtiInitConfig(void)
{
//1.关闭GPIO中断
ETS_GPIO_INTR_DISABLE();
//2.注册中断回调函数
ETS_GPIO_INTR_ATTACH((ets_isr_t)KeyExtiInterruptFunction, NULL);
//3.设置外部中断IO口以及触发方式
gpio_pin_intr_state_set(GPIO_ID_PIN(0), GPIO_PIN_INTR_NEGEDGE); // GPIO_0下降沿中断
//4.打开GPIO中断
ETS_GPIO_INTR_ENABLE();
}
//按键外部中断服务函数--需要函数声明
void KeyExtiInterruptFunction(void)
{
static i = 1;
uint32 gpio_status;
uint32 GpioFlag;
//1.读取GPIO中断状态
gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
//2.清除中断状态位
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status);
//3.判断按键的中断状态
GpioFlag = gpio_status & (0x01 << 0);
os_printf("\r\n进入中断\r\n");
if (GpioFlag == 1)
{
LED(i);
i = !i;
os_printf("\r\n按下按键\r\n");
}
}
//key.h源代码
/*
* key.h
*
* Created on: 2018年8月10日
* Author: 小良哥
*/
#ifndef APP_INCLUDE_DRIVER_KEY_H_
#define APP_INCLUDE_DRIVER_KEY_H_
#include "ets_sys.h"
#include "osapi.h"
#include "user_interface.h"
#include "driver/uart.h"
#include "gpio.h"
#include "eagle_soc.h"
#include "driver/delay.h"
void KeyInitConfig(void);
void KeyExtiInitConfig(void);
void KeyExtiInterruptFunction(void);
#define KEY (!!(GPIO_INPUT_GET(GPIO_ID_PIN(0))))
#endif /* APP_INCLUDE_DRIVER_KEY_H_ */
源代码参考:https://github.com/ChenJiliang00/ESP8266