ESP8266开软件定时器中断


前言

以下软件定时器接口位于/ESP8266NONOS-SDKlinclude/osapih。请注意,以下接口使用的定时器由软件实现,定时器的函数在任务中被执行。因为任务可能被中断,或者被其他高优先级的任务延迟,因此以下os_timer系列的接口并不能保证定时器精确执行。如果需要精确的定时,例如,周期性操作某GPIO,请使用硬件中断定时器,具体可参考hw_timer.c,硬件定时器的执行函数在中断里被执行。

注意:

  • 对于同一个timer, os_timer_arm或os_timer_arm_us不能重复调用,必须先os_timer_disarm
  • os_timer_setfn必须在timer未使能的情况下调用,在os_timer_arm或os_timer_arm_us之前或者os_timer_disarm之后
    参考资料《ESP8266 Non-OS SDK-API参考》

一、思路

定义软件定时器变量也就是os_timer_t型结构体
软件定时的回调函数
用户封装软件定时器初始化函数
调用

二、解释

1.定义软件定时器变量(os_timer_t型结构体)

在这里插入图片描述
注意:

  • 该定义必须为全局变量,因为ESP8266内核程序要使用
  • 前面os_timer_t为函数类型,后面为变量名指针

2.软件定时的回调函数

在这里插入图片描述
注意:

  • 回调函数函数名可以任意取
  • 回调函数内参数,参考上方手册

3.用户封装软件定时器初始化函数

void os_Time_1_Init(u32 TimeMS,u8 i)
TimeMS 为定的时间
i 为是否重复定时参数

1.关闭定时器

在这里插入图片描述

2.设置定时器(设置注册回调函数)

在这里插入图片描述
注意:

  • 参数1,要设置的定时器
  • 参数2,回调函数(需要类型转换)
  • 参数3,回调函数的参数(无参数NULL)
3.设置定时器参数,及使用定时器

在这里插入图片描述
参数3,代表是否循环,0为只定时1次,1为重复定时

3.调用

在用户回调函数中调用刚才封装好的函数
os_Time_1_Init(500,1);//定时500MS,无限循环

三.程序


#include "ets_sys.h"
#include "osapi.h"
#include "driver/uart.h"
#include "user_interface.h"
#include "driver/eagle_soc.h"
#include "driver/gpio16.h"
os_timer_t OS_Timer_1;//定义函数类型
/*******************************************************************************
 * 毫秒延迟函数
 *
 *
 *
 ****************************************************************************/
void delayms(uint32 i)
{
	for(;i>0;i--)
	{
		os_delay_us(1000);  //调用的微秒延迟函数
	}

}
u8 LED;
/************************************************************
 * 软件定时回调函数
 **************************************************************/
void  Timer_Interrupt1()
{
	LED=!LED;
	GPIO_OUTPUT_SET(GPIO_ID_PIN(4), LED);
	os_printf("\r\n------ Timer_Interrupt1--------\r\n");
	system_soft_wdt_feed(); //喂狗函数
}

/*************************************************************
 * 软件定时器初始化
 ***********************************************************/
void  OS_Time_1_Init(u32 TimeMS,u8 i)
{
	os_timer_disarm(&OS_Timer_1);//关闭定时
	os_timer_setfn(&OS_Timer_1,(os_timer_func_t*)Timer_Interrupt1,NULL);//注册定时回调函数
	os_timer_arm(&OS_Timer_1,TimeMS,i);//设置定时
}



/********************************************************************
 * GPIO口初始化
 *
 ****************************************************************/
void GPIO_INIT()
{
    //------------------------------------------------------------------初始化管脚功能
   //管脚功能选择(注意:参数1 【PINNAME】管脚名、参数2 【FUNC】管脚功能)
    PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U ,0);  //将GPIO4设置为IO口
    //将相应管脚设为输出模式,并输出对应电平(参数1 【gpio_no】、参数2:输出电平)
    // GPIO_DIS_OUTPUT(GPIO_ID_PIN(0));            //设置GOIO0为输入模式
    //PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO0_U);//设置IO0使能,禁止上拉
    // PIN_PULLUP_EN(PERIPHS_IO_MUX_GPIO0_U);//管脚上拉使能
   /*******************************************************************************************
    * 注意: 【PIN NAME】【FUNC】【gpio_no】不要混淆
    *【PIN NAME】                管脚名称                "PERIPHS_IO_MUX" + "管脚名
    *【FUNC】                       管脚功能                 功能序号-1
    *【gpio_no】                I0端口序号                GPI0 ID PIN (IO端口序号)
    *
    *********************************************************************************************/
  //GPIO中断设置
   // ETS_GPIO_INTR_DISABLE();//关闭中断
   // ETS_GPIO_INTR_ATTACH((ets_isr_t)(GPIO_INTERRUPT), NULL);//注册GPIO中断处理函数
    //gpio_pin_intr_state_set(GPIO_ID_PIN(0),GPIO_PIN_INTR_NEGEDGE);//中断口,中断出发方式
    /*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,             高电平中断
    */
    //ETS_GPIO_INTR_ENABLE();//打开中断
}




/******************************************************************************
 * FunctionName : user_rf_cal_sector_set
 * Description  : SDK just reversed 4 sectors, used for rf init data and paramters.
 *                We add this function to force users to set rf cal sector, since
 *                we don't know which sector is free in user's application.
 *                sector map for last several sectors : ABCCC
 *                A : rf cal
 *                B : rf init data
 *                C : sdk parameters
 * Parameters   : none
 * Returns      : rf cal sector
*******************************************************************************/
uint32 ICACHE_FLASH_ATTR
user_rf_cal_sector_set(void)
{
    enum flash_size_map size_map = system_get_flash_size_map();
    uint32 rf_cal_sec = 0;

    switch (size_map) {
        case FLASH_SIZE_4M_MAP_256_256:
            rf_cal_sec = 128 - 5;
            break;

        case FLASH_SIZE_8M_MAP_512_512:
            rf_cal_sec = 256 - 5;
            break;

        case FLASH_SIZE_16M_MAP_512_512:
            rf_cal_sec = 512 - 5;
            break;
        case FLASH_SIZE_16M_MAP_1024_1024:
            rf_cal_sec = 512 - 5;
            break;

        case FLASH_SIZE_32M_MAP_512_512:
            rf_cal_sec = 1024 - 5;
            break;
        case FLASH_SIZE_32M_MAP_1024_1024:
            rf_cal_sec = 1024 - 5;
            break;

        case FLASH_SIZE_64M_MAP_1024_1024:
            rf_cal_sec = 2048 - 5;
            break;
        case FLASH_SIZE_128M_MAP_1024_1024:
            rf_cal_sec = 4096 - 5;
            break;
        default:
            rf_cal_sec = 0;
            break;
    }

    return rf_cal_sec;
}


void ICACHE_FLASH_ATTR
user_rf_pre_init(void)
{
}

/******************************************************************************
 * FunctionName : user_init
 * Description  : entry of user application, init user function here
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_init(void)
{
	//-------------------------------------------------------------------设置串口波特率
	uart_init(115200,115200);//串口0,串口1
    os_delay_us(1000);
	os_printf("\n\r----------------------");
	os_printf("\n\rHello,Wolrd");                                     //串口打印
	os_printf("\n\rSDK version: %s \n", system_get_sdk_version());
    os_printf("\r------------------------\n\r");
    GPIO_INIT();//IO口初始化,
    OS_Time_1_Init(500,1);
  //while(1)
 // {
	  // system_soft_wdt_feed(); //喂狗函数


 // }

}


四.实现效果

LED灯以500MS间隔闪烁一次,每次闪烁向PC串口发送中断标志符
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值