ESP8266 GPIO中斷學習

前言

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 管腳清單

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章