1. 程式人生 > >esp8266~GPIO中斷和硬體定時器的正確使用

esp8266~GPIO中斷和硬體定時器的正確使用

最近專案需要檢測IO口下降沿訊號和定時計數,於是就用到了GPIO中斷和硬體定時器。有點可惜,github上面RTOS版sdk沒有硬體定時器的使用方法,能夠參考的只有1.5的sdk,然而我不會移植,只能班門弄斧。參考網上給的demo,實際在專案中用了發現網上給的用法很坑,有一些點需要注意,總結分享給大家,以下用法基於sdk 1.5。

1、gpio硬體中斷使用

/* gpio interrupt handler */
LOCAL void gpio_interrupt_cb(void){
	/*
	// 不可靠的程式碼
	_xt_isr_mask(1<<ETS_GPIO_INUM);    //disable interrupt
	
	printf("gpio_interrupt_cb \n");
	
	GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS,TRUE); //clear interrupt mask
	_xt_isr_unmask(1<<ETS_GPIO_INUM); //Enable the GPIO interrupt
	*/
uint32 gpio_status; gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS ); GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS,gpio_status); printf("gpio_interrupt_cb \n"); } void gpio_input_set(void){ GPIO_ConfigTypeDef gpio_in_cfg; gpio_in_cfg.GPIO_IntrType = GPIO_PIN_INTR_NEGEDGE; // 下降沿 GPIO_PIN_INTR_LOLEVEL
gpio_in_cfg.GPIO_Mode = GPIO_Mode_Input; gpio_in_cfg.GPIO_Pullup = GPIO_PullUp_EN; // GPIO_PullUp_EN gpio_in_cfg.GPIO_Pin = GPIO_Pin_4; gpio_config(&gpio_in_cfg); GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, TRUE); //清除中斷標誌 gpio_intr_handler_register(gpio_interrupt_cb, NULL); _xt_isr_unmask(1 <<
ETS_GPIO_INUM); // 使能GPIO中斷 }

2、硬體定時器

硬體定時器中斷使用的一些注意事項:
1、之前的開發文件,硬體定時器最下支援100us的計時,實際更改為50us也是可以正常執行的,但在實際應用中根據需要儘量改大一點,不然cpu總是去響應中斷效率很低,且中斷回撥函式裡面的函式儘可能短小簡潔。
2、hw_test_timer_cb中可刪除其他程式碼替換為自己的程式碼
3、當設定定時的時間很短是,切忌在hw_test_timer_cb中處理延時或執行時間長的程式碼,printf都不可以(當我設定為50us時,回撥中只執行printf,cpu都會跑飛掉,大家可以自己驗證一下)。
4、如何去開啟關閉硬體定時器,參考 [ESP8266 關閉硬體定時器]

#include "hw_timer.h"

#define REG_WRITE(_r,_v)    (*(volatile uint32 *)(_r)) = (_v)
#define REG_READ(_r)        (*(volatile uint32 *)(_r))
#define WDEV_NOW()          REG_READ(0x3ff20c00)

uint32 tick_now2 = 0;
void hw_test_timer_cb(void)
{
    static uint16 j = 0;
    j++;

    if ((WDEV_NOW() - tick_now2) >= 10000) {// 1000000 ~ 1s , 10000 ~ 10ms 
        static uint32 idx = 1;
        tick_now2 = WDEV_NOW();
        printf("b%u:%d\n", idx++, j);
        j = 0;
    }

    //hw_timer_arm(50);
}

void user_init(void)
{
    hw_timer_init(1);
    hw_timer_set_func(hw_test_timer_cb);
    hw_timer_arm(1000);
}

gpio中斷和硬體定時器更詳細的請參考:
1,ESP8266 NON-OS SDK 和 RTOS SDK實現GPIO中斷不同點
2,嵌入式應用程式設計經驗之談-ESP8266引腳中斷程式設計
3,ESP8266 GPIO中斷學習
4, ESP8266-Demos/H01-gpio_app/user/user_gpio.c

5,利用 " 軟體定時器 "或“硬體定時器” 定時0.5秒閃爍點亮一盞LED