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

猜你喜欢

转载自blog.csdn.net/Bluechalk/article/details/82971376