Arduino for Esp8266 基础篇之Ticker

本文介绍了在Arduino for Esp8266环境下,如何利用Ticker类实现无操作系统环境下的多任务定时调度。Ticker提供了定时器管理与启用的方法,包括一次性执行和周期性执行,适用于IO输入电平事件检测与消抖等应用场景。

Arduino for Esp8266 基础篇之Ticker

前言:Arduino for esp8266属于无操作系统环境,对于开发多任务的复杂应用还是比较麻烦的,所以这里就提供了一个近似于操作系统调度器的功能Ticker类;Ticker的功能非常简单,就是规定时间后调用函数,总体上,根据功能可以把方法分为两大类:1 定时器管理方法;2 定时器启用方法;

1 定时器管理方法:

void Ticker::detach()  //停止定时器
{
    if (!_timer)
        return;
    os_timer_disarm(_timer); //关闭软件定时器
    _timer = nullptr; // 定时器指针为nullptr;
    _callback_function = nullptr; // 回调函数指针为nullptr; 
}
bool Ticker::active() const   //  定时器是否工作状态
{
    return _timer;
}

2定时器启用方法:

void Ticker::once(float seconds, callback_function_t callback); xx秒后只执行一次
其中入口参数:seconds—秒数 ;callback—回调函数;
void Ticker::once(float seconds, void (*callback)(TArg), TArg arg); xx秒后只执行一次
其中入口参数:seconds—秒数 ;callback—回调函数;arg—回调函数参数;
void Ticker::once_ms(uint32_t milliseconds, callback_function_t callback) ;xx毫秒后只执行一次
其中入口参数:milliseconds—毫秒数 ;callback—回调函数;
void Ticker::once_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg) xx毫秒后只执行一次
其中入口参数:milliseconds—毫秒数 ;callback—回调函数;arg—回调函数参数;
void Ticker::attach(float seconds, callback_function_t callback); 每隔xx秒周期性执行
其中入口参数:seconds—秒数 ;callback—回调函数;
void Ticker::attach(float seconds, void (*callback)(TArg), TArg arg) 每隔xx秒周期性执行
其中入口参数:seconds—秒数 ;callback—回调函数;arg—回调函数参数;
void Ticker::attach_ms_scheduled(uint32_t milliseconds, callback_function_t callback) ;每隔xx毫秒周期性执行
其中入口参数:milliseconds—毫秒数 ;callback—回调函数;
void Ticker::attach_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg);每隔xx毫秒周期性执行
其中入口参数:milliseconds—毫秒数 ;callback—回调函数;arg—回调函数参数;
核心函数:

// 入口参数:milliseconds:毫秒数 ;repeat:是否重复(周期性);callback:回调函数;arg:回调函数参数
void Ticker::_attach_ms(uint32_t milliseconds, bool repeat, callback_with_arg_t callback, void* arg)
{
    if (_timer)
    {
        os_timer_disarm(_timer);//关闭软件定时器
    }
    else
    {
        _timer = &_etsTimer; 
    }

    os_timer_setfn(_timer, callback, arg);//设置定时器,设置回调函数
    os_timer_arm(_timer, milliseconds, repeat);//使能定时器
}

应用举例:

应用1:检测IO输入电平事件并消抖(无参数调度)
#include "Ticker.h" //引入调度器头文件
#define Input_Pin          3
bool blINputEventSWFlag= false;
uint_8 INputEventStatusCount=0;
Ticker myTicker; //建立一个需要定时调度的对象
void tickerHandle(void) //到20毫秒时间时需要执行的任务 
{
  if(GetINputEventStatus())
     INputEventStatusCount ++;
  else 
     INputEventStatusCount=0;
  if(INputEventStatusCount>5)
    {
      INputEventStatusCount=0;
      blINputEventSWFlag = true;
    }
}
bool GetINputEventStatus(void)
{
  bool blRev=  true;
  uint8_t  INputEventStatus;
  INputEventStatus =(uint8_t)digitalRead(Input_Pin);
  if(INputEventStatus ==0)
    blRev = false ;
  return blRev;
}
void setup()
{
    Serial.begin(115200);
    Serial.println();
    pinMode(Input_Pin, INPUT_PULLUP);  
    myTicker.attach_ms(20, tickerHandle); //初始化调度任务,每20毫秒执行一次tickerHandle()
}

void loop()
{
   if( blINputEventSWFlag )
     {
        // do task
     }
}
应用2:检测IO输入电平事件并消抖(有参数调度)
#include "Ticker.h"
#define Input_Pin          3
bool blINputEventSWFlag= false;
uint_8 INputEventStatusCount=0;
Ticker myTicker; //建立一个需要定时调度的对象
void tickerHandle(uint8_t MaxNumbers) //到20毫秒时间时需要执行的任务 
{
  if(GetINputEventStatus())
     INputEventStatusCount ++;
  else 
     INputEventStatusCount=0;
  if(INputEventStatusCount>MaxNumbers)
    {
      INputEventStatusCount=0;
      blINputEventSWFlag = true;
    }
}
bool GetINputEventStatus(void)
{
  bool blRev=  true;
  uint8_t  INputEventStatus;
  INputEventStatus =(uint8_t)digitalRead(Input_Pin);
  if(INputEventStatus ==0)
    blRev = false ;
  return blRev;
}
void setup()
{
    Serial.begin(115200);
    Serial.println();
    pinMode(Input_Pin, INPUT_PULLUP); 
    myTicker.attach_ms(20, tickerHandle,5); //初始化调度任务,每20毫秒执行一次tickerHandle()并传入参数
}

void loop()
{
    if( blINputEventSWFlag )
     {
        // do task
     }
}
应用3:任务调度的启动和停止
#include "Ticker.h"
Ticker myTicker1;
Ticker myTicker2;

void tickerHandle1()
{
    Serial.println(millis());
    myTicker1.detach(); //停止当前任务
}

void tickerHandle2()
{
    Serial.println("start myTicker1");
    myTicker1.attach(0.5, tickerHandle1); //重新开始myTicker1
}

void setup()
{
    Serial.begin(115200);
    Serial.println();
    myTicker1.attach(0.5, tickerHandle1); 
    myTicker2.attach(2, tickerHandle2); 
}

void loop()
{
}

####应用3: 时间任务调度回调函数的快速处理

#include "Ticker.h" 
#define Input_Pin          3
uint_8 INputEventStatusCount=0;
Ticker myTicker; 
bool BlOnTimeFlag = false; //定时标志
bool GetINputEventStatus(void)
{
  bool blRev=  true;
  uint8_t  INputEventStatus;
  INputEventStatus =(uint8_t)digitalRead(Input_Pin);
  if(INputEventStatus ==0)
    blRev = false ;
  return blRev;
}
void tickerHandle() 
{
    BlOnTimeFlag = true; //更新标志
}

void setup()
{
    Serial.begin(115200);
    Serial.println();
    myTicker.attach_ms(20, tickerHandle);
}

void loop()
{
    if (BlOnTimeFlag) //如果BlOnTimeFlag==true
    {
        BlOnTimeFlag= false; //标志重置
        if(GetINputEventStatus())
           INputEventStatusCount ++;
       else 
         INputEventStatusCount=0;
      if(INputEventStatusCount>5)
         {
          INputEventStatusCount=0;
          // do task
        }
    }
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值