Esp8266学习之旅③ 利用 " 软件定时器 "或“硬件定时器” 定时0.5秒闪烁点亮一盏LED。(附带demo)

版权声明:本文为博主半颗心脏一心一血敲出来的原创作品,未经博主允许不得转载,多谢支持。 https://blog.csdn.net/xh870189248/article/details/78155357

目录:


一、软件定时器。


  • 在我们的SDK编程手册可以清楚看到8266有软件定时器和硬件定时器。

这里写图片描述


  • 个人见解。如果你可以使用更为精确的定时时间,那你就用硬件定时器来。至于在性能上,我觉得硬件定时器是比较耗性能的,在PWM里面,hw_timer.c 的接⼝口不不能跟 PWM 驱动接⼝口函数同时使⽤用,因为二者共⽤用了了同⼀一个硬 件中断定时器。

  • 而且硬件中断定时器器的回调函数定义,请勿添加 ICACHE_FLASH_ATTR。


二、使用软件定时器步骤:


  • ①、先宏定义一个定时器结构体:
// 定时器结构体 
static os_timer_t os_timer;
  • ②、对于同一个定时器不能同时使用,所以我在初始化前先关闭该定时器
// 关闭该定时器 
os_timer_disarm( &os_timer );
  • ③、初始化定时器的回调函数,即每次定时任务函数。下图是函数os_timer_setfn()有关说明。我这里的定时器回调函数是Led_Task_Run ()。
// 配置该定时器回调函数 
os_timer_setfn( &os_timer, (ETSTimerFunc *) ( Led_Task_Run ), NULL );

这里写图片描述

  • ④、开始执行我们的定时器,也就是使能操作。下图是这个函数的说明:第二个参数是定时时间,单位us,注意: os_timer_arm()的时间参数的单位是ms,1s =1000ms ,第三个参数是boolean值,false是不重复,true是重复执行。但是os_timer_arm_us()时间参数的单位是us,1s =1000ms =1000 000 us;
// 启动该定时器 
os_timer_arm( &os_timer, 500, true );

  • 单位是 us:

这里写图片描述


  • 单位是 ms:
    这里写图片描述

三、看看我们的效果图(0.5秒LED灯闪一次):


这里写图片描述


  • 电路图:

电路图


  • 我们的逻辑是:通过定时器每0.5秒执行一次开灯或关灯指令。使GPIO12为高电平输出或低电平输出。

  • 代码:


/** 定时器结构体 */
static os_timer_t os_timer;


/** LED操作命令 */
void Led_Cmd(bool status ){
    if (status == true ) {
        GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 0);
    } else {
        GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 1);
    }
}



void Led_Task_Run(void){

    static bool status = false;
      if ( status == true ) {
            status = false;
        } else  {
            status = true;
        }
     Led_Cmd( status );
}

void  user_init(void)//初始化
{

        // 设置串口0和串口1的波特率
        uart_init(57600, 57600);

        PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12);
        Led_Cmd(false);

       /** 关闭该定时器 */
       os_timer_disarm( &os_timer );
       /** 配置该定时器回调函数 */
       os_timer_setfn( &os_timer, (ETSTimerFunc *) ( Led_Task_Run ), NULL );
       /** 启动该定时器 */
       os_timer_arm( &os_timer, 500, true );
}

void user_rf_pre_init()
{

}

四、硬件中断定时器。


  • 前面已经说了。硬件中断定时器,顾名思义,就是利用中断进行的定时。而且更为的准确,但是你用了这个硬件中断定时器,你这无法使用PWM驱动接口,因为公用了一个硬件定时器。切记切记!!

  • 以下是乐鑫给出的相关文档。

    • 硬件中断定时器器的回调函数定义,请勿添加 ICACHE_FLASH_ATTR 。

这里写图片描述


  • 硬件定时器不像软件定时器,它的驱动接口是一个c文件,所以我们必须要拿过来。hw_timer.c 复制到编译目录即可。

  • ①、初始化。
void ICACHE_FLASH_ATTR user_init(void) {

    uart_init(57600, 57600);
    os_printf("SDK version:%s\n", system_get_sdk_version());

    PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12);
    Led_Cmd(false);

    //第一个参数0使用的是FRC1_SOURCE,如果是1则为NMI_SOURCE类型,第二个参数是否自动填充,也就是是否重复。
    hw_timer_init(0, 1);
    //设置定时器的回调函数
    hw_timer_set_func(hw_test_timer_cb);
    //设置定时时间
    hw_timer_arm(500);

}

  • ②、这是控制LED的方法,同上面的软件定时器。
void Led_Cmd(bool status) {
    if (status == true) {
        GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 0);
    } else {
        GPIO_OUTPUT_SET(GPIO_ID_PIN(12), 1);
    }
}

void hw_test_timer_cb(void) {
    static bool status = false;
    if (status == true) {
        status = false;
        os_printf("Led_Cmd false");
    } else {
        status = true;
        os_printf("Led_Cmd true");
    }
    Led_Cmd(status);
}

软件定时器工程源码下载 : https://github.com/xuhongv/StudyInEsp8266/tree/master/3_TimerLED

硬件中断定时器工程源码下载 :https://github.com/xuhongv/StudyInEsp8266/tree/master/15_ESP8266_Timer2


猜你喜欢

转载自blog.csdn.net/xh870189248/article/details/78155357