ESP8266学习三

1 篇文章 0 订阅

ESP8266学习三

软件定时器

软件定时器不一定看可以成功得执行 在CPU长期占用得情况下软件定时器不会执行;

毫秒级别定时

os_timer_t OS_TIMER_1; //定义定时器结构   必须要全局变量  
						//不要写成os_timer_t *OS_TIMER_1;

//  定时器中断回调函数
void Timer_INTERRUPT()
{
	flag = !flag;
	GPIO_OUTPUT_SET(GPIO_ID_PIN(4),flag);
}
/*  初始化软件定时器
*delay_ms  为延长多长时间
*repeat_flag 为是否需要重复定时中断  1 需要  0只执行一次
*/
void ICACHE_FLASH_ATTR
OS_TIMER_Init(uint32_t delay_ms,bool repeat_flag)
{
	//取消定时器定时
	os_timer_disarm	(&OS_TIMER_1);
	//设置定时器回调函数
	os_timer_setfn(&OS_TIMER_1,(os_timer_func_t *)Timer_INTERRUPT,NULL);
	//启动定时器
	os_timer_arm(&OS_TIMER_1,delay_ms,repeat_flag);
	//- 如未调⽤ system_timer_reinit,可⽀持范围 5 ~ 0x68D7A3 
	//- 如调⽤了 system_timer_reinit,可⽀持范围 100 ~ 0x689D0
}
void ICACHE_FLASH_ATTR
user_init(void)
{
	uart_init(9600,115200);
	os_printf("------------------------------------\r\n");
	uart0_sendStr("串口开始打印13\r\n");
	uart0_sendStr("------------------------------------\r\n");

	PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U,FUNC_GPIO4); // 选择引脚4
	GPIO_OUTPUT_SET(GPIO_ID_PIN(4),0);      //IO4 = 0


	OS_TIMER_Init(500,1);

}

注意
如果要使用system_timer_reinit()函数 必须要先定义USE_US_TIMER
(#define USE_US_TIMER) 而system_timer_reinit()函数 必须在程序最开始调⽤,user_init 的第⼀句。

硬件定时

需要提前将hw_timer.c得文件提前包含到app/driver中
注意:

  1. • 如果使⽤ NMI 中断源,且为⾃动填装的定时器,调⽤ hw_timer_arm 时参数 val 必须⼤于 100。
  2. • 如果使⽤ NMI 中断源,那么该定时器将为最⾼优先级,可打断其他 ISR。
  3. • 如果使⽤ FRC1 中断源,那么该定时器⽆法打断其他 ISR。
  4. • hw_timer.c 的接⼝不能跟 PWM 驱动接⼝函数同时使⽤,因为⼆者共⽤了同⼀个硬件定时器。
  5. • 硬件中断定时器的回调函数定义,请勿添加 ICACHE_FLASH_ATTR 宏。
  6. • 使⽤ hw_timer.c 的接⼝,请勿调⽤ wifi_set_sleep_type(LIGHT_SLEEP);
    将⾃动睡眠模式设置为 Light-sleep。因为 Light-sleep 在睡眠期间会停 CPU,停 CPU 期间不能响应 NMI
    中断。
//  定时器中断回调函数  不需要写   ICACHE_FLASH_ATTR
void HWTimer_INTERRUPT()
{
	flag = !flag;
	GPIO_OUTPUT_SET(GPIO_ID_PIN(4),flag);
}
//初始化硬件定时器
void ICACHE_FLASH_ATTR
HW_Timer_Init(uint32_t delay_ms,bool repeat_flag)
{
	//初始化硬件定时器
	hw_timer_init(0,repeat_flag);//使⽤ FRC1 中断源   repeat_flag是否自动重装
	//hw_timer_init(1,repeat_flag);//使⽤ NMI 中断源   repeat_flag是否自动重装
	hw_timer_set_func(HWTimer_INTERRUPT);  //设置定时器回调函数
	hw_timer_arm(delay_ms);                //使能硬件中断定时器
}
void ICACHE_FLASH_ATTR
user_init(void)
{
	uart_init(9600,115200);
	os_printf("------------------------------------\r\n");
	uart0_sendStr("串口开始打印14\r\n");
	uart0_sendStr("------------------------------------\r\n");

	PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO4_U,FUNC_GPIO4); // 选择引脚4
	GPIO_OUTPUT_SET(GPIO_ID_PIN(4),0);      //IO4 = 0


	HW_Timer_Init(50000,1);

}

hw_timer.c 文件

/*
 * ESPRESSIF MIT License
 *
 * Copyright (c) 2016 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
 *
 * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case,
 * it is free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
 * to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */

#include "ets_sys.h"
#include "os_type.h"
#include "osapi.h"

#define US_TO_RTC_TIMER_TICKS(t)          \
    ((t) ?                                   \
     (((t) > 0x35A) ?                   \
      (((t)>>2) * ((APB_CLK_FREQ>>4)/250000) + ((t)&0x3) * ((APB_CLK_FREQ>>4)/1000000))  :    \
      (((t) *(APB_CLK_FREQ>>4)) / 1000000)) :    \
     0)

#define FRC1_ENABLE_TIMER  BIT7
#define FRC1_AUTO_LOAD  BIT6

//TIMER PREDIVED MODE
typedef enum {
    DIVDED_BY_1 = 0,		//timer clock
    DIVDED_BY_16 = 4,	//divided by 16
    DIVDED_BY_256 = 8,	//divided by 256
} TIMER_PREDIVED_MODE;

typedef enum {			//timer interrupt mode
    TM_LEVEL_INT = 1,	// level interrupt
    TM_EDGE_INT   = 0,	//edge interrupt
} TIMER_INT_MODE;

typedef enum {
    FRC1_SOURCE = 0,
    NMI_SOURCE = 1,
} FRC1_TIMER_SOURCE_TYPE;

/******************************************************************************
* FunctionName : hw_timer_arm
* Description  : set a trigger timer delay for this timer.
* Parameters   : uint32 val :
in autoload mode
                        50 ~ 0x7fffff;  for FRC1 source.
                        100 ~ 0x7fffff;  for NMI source.
in non autoload mode:
                        10 ~ 0x7fffff;
* Returns      : NONE
*******************************************************************************/
void  hw_timer_arm(u32 val)
{
    RTC_REG_WRITE(FRC1_LOAD_ADDRESS, US_TO_RTC_TIMER_TICKS(val));
}

static void (* user_hw_timer_cb)(void) = NULL;
/******************************************************************************
* FunctionName : hw_timer_set_func
* Description  : set the func, when trigger timer is up.
* Parameters   : void (* user_hw_timer_cb_set)(void):
                        timer callback function,
* Returns      : NONE
*******************************************************************************/
void  hw_timer_set_func(void (* user_hw_timer_cb_set)(void))
{
    user_hw_timer_cb = user_hw_timer_cb_set;
}

static void hw_timer_isr_cb(void *arg)
{
    if (user_hw_timer_cb != NULL) {
        (*(user_hw_timer_cb))();
    }
}

static void hw_timer_nmi_cb(void)
{
    if (user_hw_timer_cb != NULL) {
        (*(user_hw_timer_cb))();
    }
}

/******************************************************************************
* FunctionName : hw_timer_init
* Description  : initilize the hardware isr timer
* Parameters   :
FRC1_TIMER_SOURCE_TYPE source_type:
                        FRC1_SOURCE,    timer use frc1 isr as isr source.
                        NMI_SOURCE,     timer use nmi isr as isr source.
u8 req:
                        0,  not autoload,
                        1,  autoload mode,
* Returns      : NONE
*******************************************************************************/
void ICACHE_FLASH_ATTR hw_timer_init(FRC1_TIMER_SOURCE_TYPE source_type, u8 req)
{
    if (req == 1) {
        RTC_REG_WRITE(FRC1_CTRL_ADDRESS,
                      FRC1_AUTO_LOAD | DIVDED_BY_16 | FRC1_ENABLE_TIMER | TM_EDGE_INT);
    } else {
        RTC_REG_WRITE(FRC1_CTRL_ADDRESS,
                      DIVDED_BY_16 | FRC1_ENABLE_TIMER | TM_EDGE_INT);
    }

    if (source_type == NMI_SOURCE) {
        ETS_FRC_TIMER1_NMI_INTR_ATTACH(hw_timer_nmi_cb);
    } else {
        ETS_FRC_TIMER1_INTR_ATTACH(hw_timer_isr_cb, NULL);
    }

    TM1_EDGE_INT_ENABLE();
    ETS_FRC1_INTR_ENABLE();
}

//-------------------------------Test Code Below--------------------------------------
#if 0
void   hw_test_timer_cb(void)
{
    static uint16 j = 0;
    j++;

    if ((WDEV_NOW() - tick_now2) >= 1000000) {
        static u32 idx = 1;
        tick_now2 = WDEV_NOW();
        os_printf("b%u:%d\n", idx++, j);
        j = 0;
    }

    //hw_timer_arm(50);
}

void ICACHE_FLASH_ATTR user_init(void)
{
    hw_timer_init(FRC1_SOURCE, 1);
    hw_timer_set_func(hw_test_timer_cb);
    hw_timer_arm(100);
}
#endif
/*
NOTE:
1 if use nmi source, for autoload timer , the timer setting val can't be less than 100.
2 if use nmi source, this timer has highest priority, can interrupt other isr.
3 if use frc1 source, this timer can't interrupt other isr.

*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值