【杰理AC696X】软件定时器介绍

测试SDK版本:《ac696n_soundbox_sdk_v1.6.0》


文章目录

  • 【杰理AC696X】软件定时器介绍
  • 前言
  • 一、功能概述
    • 1.1 软件定时器类型
    • 1.2 软件定时器相关知识
  • 二、流程框架
    • 2.1 usr_timer 流程框架
    • 2.1 sys_timer 流程框架
  • 三、接口详细说明
    • 3.1 usr_timer定时循环接口
    • 3.2 usr_timer定时超时接口
    • 3.3 sys_timer定时循环接口
    • 3.4 sys_timer定时超时接口
  • 四、使用示例
    • 4.1 循环定时器写法
    • 4.2 延时定时器写法
  • 总结

前言

SDK给出了软件定时器的相关接口,主要有 sys_hi_timer_add、sys_s_hi_timer_add、sys_timer_add等。
列出AC696X系列软件定时器的相关知识点,再结合代码调试和工具测试,总结出使用案例。


一、功能概述

1.1 软件定时器类型


1.2 软件定时器相关知识

  • 上面的低功耗指的是 power down,不是soft poweroff。

  • usr_timer的强弱节拍指的是优先级的差异,使用高优先级定时器,系统无法进power down。使用低优先级定时器,系统可以进power down,但定时周期会被改变 。

  • sys_timer/usr_timer 与 sys_timerout/usr_timerout 接口区别在于 timeout 接口的回调只会被做一次,也就是设定一个未来的时间, 时间到了响应之后便结束这个定时器的生命周期。

  • usr_timer与sys_timer主要区别是,usr_timer是由硬件定时器提供时基, sys_timer是由systimer线程提供时基。

  • 注册软件定时器不耗费硬件定时器,系统默认使用了 timer1 为系统 2ms 时钟定时用,所有的软件定时器都基于这个 timer1 拓展出来。拓展出 2 种定时器使用方式(此知识点与实际应用有出入,但杰理各系列大致一样,这里只作为参考):

    1、在中断函数回调执行(切记不可调用延时或耗时等操作)
    sys_hi_timer_add() 定时循环函数,会导致不进低功耗,直到主动删除
    sys_hi_timeout_add() 定时超时执行一次函数
    sys_s_hi_timer_add() 定时循环函数,不影响系统进低功耗,周期会变,建议使用此种定时器
    sys_s_hi_timerout_add() 定时超时执行一次函数
    注意点:此种定时器,注册的函数是在中断函数里面回调的,不可添加延时,或耗时的操作。 单位是 ms,但是是以 2ms 步进的。3ms 等同于 4ms 的。

    2、在系统线程中执行,几乎可执行所有的操作
    sys_timer_add() 定时循环函数,会影响下次进低功耗的时间点,周期太短会影响功耗。
    sys_timeout_add() 定时超时执行一次函数

    注意点:此种定时器,注册的函数是在线程执行的,优先级依赖于注册的线程的优先级。单位是 ms,但是是以 10ms 步进的。5ms 等同于 10ms 的。系统是以 10ms为系统滴答的。

二、流程框架

2.1 usr_timer 流程框架


2.1 sys_timer 流程框架


三、接口详细说明

3.1 usr_timer定时循环接口

强节拍:

#define sys_hi_timer_add(a, b, c)\usr_timer_add(a, b, c, 1)#define sys_hi_timer_modify(a, b)\usr_timer_modify(a, b)#define sys_hi_timer_del(a)\usr_timer_del(a)

弱节拍:

#define sys_s_hi_timer_add(a, b, c)\usr_timer_add(a, b, c, 0)#define sys_s_hi_timer_modify(a, b)\usr_timer_modify(a, b)#define sys_s_hi_timer_del(a)\usr_timer_del(a)

接口展开:

//*----------------------------------------------------------------------------*/
/**@brief   usr_timer定时扫描增加接口@parampriv:私有参数func:定时扫描回调函数msec:定时时间, 单位:毫秒priority:优先级,范围:0/1@return  定时器分配的id号@note    1、usr_timer的参数priority(优先级)为1,使用该类定时器,系统无法进入低功耗2、usr_timer的参数priority(优先级)为0,使用该类定时器,系统低功耗会忽略该节拍,节拍不会丢失,但是周期会变3、usr_timer属于异步接口, add的时候注册的扫描函数将在硬件定时器中时基到时候被调用。4、对应释放接口usr_timer_del
*/
/*----------------------------------------------------------------------------*/
u16 usr_timer_add(void *priv, void (*func)(void *priv), u32 msec, u8 priority);
//*----------------------------------------------------------------------------*/
/**@brief   usr_timer修改定时扫描时间接口@paramid:usr_timer_add时分配的id号msec:定时时间, 单位:毫秒@return@note
*/
/*----------------------------------------------------------------------------*/
int usr_timer_modify(u16 id, u32 msec);
//*----------------------------------------------------------------------------*/
/**@brief   usr_timer删除接口@paramid:usr_timer_add时分配的id号@return@note    注意与usr_timer_add成对使用
*/
/*----------------------------------------------------------------------------*/
void usr_timer_del(u16 id);

3.2 usr_timer定时超时接口

强节拍:

#define sys_hi_timeout_add(a, b, c)\usr_timeout_add(a, b, c, 1)#define sys_hi_timeout_modify(a, b)\usr_timeout_modify(a, b)#define sys_hi_timeout_del(a)\usr_timeout_del(a)

弱节拍:

#define sys_s_hi_timerout_add(a, b, c)\usr_timeout_add(a, b, c, 0)#define sys_s_hi_timeout_modify(a, b)\usr_timeout_modify(a, b)#define sys_s_hi_timeout_del(a)\usr_timeout_del(a)

接口展开:

//*----------------------------------------------------------------------------*/
/**@brief   usr_timer超时增加接口@parampriv:私有参数func:超时回调函数msec:定时时间, 单位:毫秒priority:优先级,范围:0/1@return  定时器分配的id号@note    1、usr_timerout的参数priority(优先级)为1,使用该类定时器,系统无法进入低功耗2、usr_timerout的参数priority(优先级)为0,使用该类定时器,系统低功耗会忽略该节拍,节拍不会丢失,但是周期会变3、usr_timerout属于异步接口, add的时候注册的扫描函数将在硬件定时器中时基到时候被调用。4、对应释放接口usr_timerout_del4、timeout回调只会被执行一次
*/
/*----------------------------------------------------------------------------*/
u16 usr_timeout_add(void *priv, void (*func)(void *priv), u32 msec, u8 priority);
//*----------------------------------------------------------------------------*/
/**@brief   usr_timerout修改超时时间接口@paramid:usr_timerout_add时分配的id号msec:定时时间, 单位:毫秒@return@note
*/
/*----------------------------------------------------------------------------*/
int usr_timeout_modify(u16 id, u32 msec);
//*----------------------------------------------------------------------------*/
/**@brief   usr_timeout删除接口@paramid:usr_timerout_add时分配的id号@return@note    注意与usr_timerout_add成对使用
*/
/*----------------------------------------------------------------------------*/
void usr_timeout_del(u16 id);

3.3 sys_timer定时循环接口

//*----------------------------------------------------------------------------*/
/**@brief   sys_timer定时扫描增加接口@parampriv:私有参数func:定时扫描回调函数msec:定时时间, 单位:毫秒@return  定时器分配的id号@note    1、系统会进入低功耗,节拍不会丢失2、sys_timer由systimer线程提供时基,属于同步接口,也就是说在哪个线程add的sys_timer,定时时基到了systimer线程会发事件通知对应的add线程响应(回调函数被执行)3、与sys_timer_del成对使用
*/
/*----------------------------------------------------------------------------*/
u16 sys_timer_add(void *priv, void (*func)(void *priv), u32 msec);
//*----------------------------------------------------------------------------*/
/**@brief   sys_timer定时扫描删除接口@paramid:sys_timer_add分配的id号@return@note    1、与sys_timer_add成对使用
*/
/*----------------------------------------------------------------------------*/
void sys_timer_del(u16);

3.4 sys_timer定时超时接口

//*----------------------------------------------------------------------------*/
/**@brief   sys_timer超时增加接口@parampriv:私有参数func:定时扫描回调函数msec:定时时间, 单位:毫秒@return  定时器分配的id号@note    1、系统会进入低功耗,节拍不会丢失2、sys_timerout由systimer线程提供时基,属于同步接口,也就是说在哪个线程add的sys_timerout,定时时基到了systimer线程会发事件通知对应的add线程响应(回调函数被执行)3、timeout回调只会被执行一次4、与sys_timerout_del成对使用
*/
/*----------------------------------------------------------------------------*/
u16 sys_timeout_add(void *priv, void (*func)(void *priv), u32 msec);
//*----------------------------------------------------------------------------*/
/**@brief   sys_timer超时删除接口@paramid:sys_timerout_add分配的id号@return@note    1、与sys_timerout_add成对使用
*/
/*----------------------------------------------------------------------------*/
void sys_timeout_del(u16);

四、使用示例

4.1 循环定时器写法

static u16 timer_loop = 0;static void timer_loop_func(void *priv)
{static u16 cnt = 0;cnt++;printf("%s[cnt: %d]\n",__func__,cnt);if(cnt > 100){if(timer_loop){sys_timer_del(timer_loop);//删除前要判断//sys_hi_timeout_del(timer_loop);//sys_s_hi_timer_del(timer_loop);timer_loop = 0;//删除后要清0}cnt = 0;}
}void timer_loop_init(void)
{printf("%s[id: %d]\n",__func__,timer_loop);if(timer_loop){sys_timer_del(timer_loop);//注册前,如果有注册过要deltimer_loop = 0;}timer_loop = sys_timer_add(NULL, timer_loop_func, 100);//timer_loop = sys_hi_timer_add(NULL, timer_loop_func, 2);//timer_loop = sys_s_hi_timer_add(NULL, timer_loop_func, 10);
}

4.2 延时定时器写法

static u16 timer_one = 0;static void timer_one_func(void *priv)
{printf("%s\n", __func__);//sys_timeout_add注册的只会执行一次,底层会自动删除//回调函数内不可调用sys_timeout_deltimer_one = 0;//ID号清0,必须要有!!!
}void timer_one_init(void)
{printf("%s[id: %d]\n", __func__, timer_one);if (timer_one) {sys_timeout_del(timer_one);//注册前,如果有注册过要deltimer_one = 0;}timer_one = sys_timeout_add(NULL, timer_one_func, 100);
}void timer_one_del(void)
{printf("%s[id: %d]\n", __func__, timer_one);if (timer_one) {sys_timeout_del(timer_one);timer_one = 0;}
}

总结

1、用软件定时器时,要注意看说明,有些定时器会被低功耗影响到周期,必要的时候可以关低功耗

#define TCFG_LOWPOWER_LOWPOWER_SEL           0//SLEEP_EN                     //SNIFF状态下芯片是否进入powerdown

2、分别用 sys_hi_timer_add、sys_s_hi_timer_add、sys_timer_add三种定时器类型注册循环定时器,定时参数最小可设置2ms,即使设置1ms,也是2ms执行一次回调函数,可见,usr_timer和sys_timer的时基应为2ms。

3、调整定时时间,测试发现,这三种软件定时器都是以2ms为步进的,但定时时间设为奇数时,比如3ms,发现并不像资料中描述的那样,设置3ms等同于4ms,而是有时2ms执行一次,有时4ms执行一次。定时时间设为2ms的倍数,则正常。

4、有些需求需要开机就跑一些定时器扫描任务的,注册定时器不能太靠前,建议放在下面的位置:

void app_main()
{log_info("app_main\n");app_var.start_time = timer_get_ms();... ... user_func_init();//用户功能初始化,注册软件定时器... ... app_task_loop();
}

5、AC696X系列SDK中有Usec Timer的接口,但是底层是没实现的,不可用。如果有微秒级的延时需求,比如一些单线控制的功放,微秒级的控制时序,杰理有提供硬件定时器实现的方法。

6、如果需要定时时间小于2ms的循环,切对精度要求高的,要使用硬件定时器中断,有必要的话,还要放到RAM中运行。

【杰理AC696X】软件定时器介绍相关推荐

  1. 杰理AC692X---红外按键介绍

    红外按键介绍 打开宏定义 把这个宏定义置1,红外按键就打开了,红外按键是可以和其他按键一起使用的,也就是说你用红外按键的同时也可用其他按键,相关宏定义也置1就可以了. 红外接收引脚和头码 遥控器都会有 ...

  2. 杰理AC692X---常用模式介绍

    常用模式介绍 692X系列的SDK支持多种模式切换,以下是一些常用的模式介绍,RTC模式和录音模式在此不讲解. 蓝牙模式 用的最多的应该是蓝牙模式,蓝牙模式主要由以下宏定义进行协议选择: 注销掉的是B ...

  3. 杰理芯片软件加密钥的操作流程

    前言: 软件加密钥的目的:1. 对软件加密,可以保护自身的软件:2. 杰理芯片烧录时,软件的密钥要与烧录座的密钥一致,方可烧录,所以在量产时,相关软件一定要加密才能批量烧录生产: 操作流程(以JL杰理 ...

  4. 【杰理AC696X】PWM推RGB灯实例

    SDK版本:ac696n_soundbox_sdk_v1.2.3 杰理的PWM,定时器会绑定默认的硬件IO,而且支持任意IO映射,硬件io对应用户手册上的io,有硬件io的尽量使用硬件io. 注意:因 ...

  5. 【杰理AC696X】外挂FLASH音乐播放及Bin文件制作

    外挂FLASH音乐播放及Bin文件制作 测试SDK版本:<ac696n_soundbox_sdk_v1.6.0> 文章目录 外挂FLASH音乐播放及Bin文件制作 前言 一.板级配置 1. ...

  6. 【杰理AC696X】外挂收音IC RDA5807的频段设置

    外挂收音IC RDA5807的频段设置 测试SDK版本:<ac608n_soundbox_sdk_v1.2.2> 文章目录 外挂收音IC RDA5807的频段设置 前言 一.RDA5807 ...

  7. 杰理之烧写器简要介绍【篇】

    杰理科技一拖八烧写器主要用于烧写已贴片的样机芯片程序,支持开发过程使用一台烧写器对1~8个样机芯片进行程序烧录,量产配合烧录治具实现对N台烧写器的N*8个样机芯片同时进行手动或者自动烧录程序. 一拖八 ...

  8. 【杰理AC696X】MIC能量采集的三种方式

    MIC能量采集的三种方式 测试SDK版本:<ac696n_soundbox_sdk_v1.5.0-20211217> 文章目录 MIC能量采集的三种方式 前言 一.混响流程的MIC能量检测 ...

  9. 【杰理AC696X】各功能占ROM大小说明

最新文章

  1. 加油站会员管理系统源码php_分享一下:关于一对一直播源码的重要组成部分
  2. python小游戏编程实例-Python实现的弹球小游戏示例
  3. SpringMVC详细执行流程整理
  4. python 修饰器 参数_具有参数的Python类修饰器,但未运行修饰的...
  5. 聊聊天,如果能重来,还干不干程序员?
  6. 【Liunx】Linux 系统启动过程
  7. dictionary new一个实例_超全的Python 字典(Dictionary)介绍
  8. python基础判断题汇总_python基础 判断题
  9. Java 代理中转下载 url 文件
  10. JS中动态创建元素的三种方法
  11. 基于51单片机霍尔汽车自行车码表测速测里程显示proteus仿真原理图PCB
  12. python 批量转换xls to xlsx,出现pywintypes.com_error: (-2147417848, ‘被调用的对象已与其客户端断开连接)’的问题处理
  13. CRC16-IBM/MAXIM/USB/MODBUS/CCITT/CCITT-FALSE/X25/XMODEM查表算法
  14. QsciScintilla等编辑器实现不同区域鼠标右键处理方式不同的方法
  15. linux 进程间界面嵌套,WPF 同一窗口内的多线程/多进程 UI(使用 SetParent 嵌入另一个窗口)...
  16. 对彩色花图像进行分类-基于R语言的Keras实现
  17. 毕业季基于ssm框架的管理系统设计与实现如何写开题报告,怎么完成设计
  18. 面试题 02.08. 环路检测-快慢指针+如何找到环的入口?(证明)Java
  19. 脑洞故事|万圣节的起源并非恶魔,而是M星系机器人!
  20. JSON解析合集:你再也不用怕JSON解析了!!!

热门文章

  1. android sqlite delete 返回值,SQLite 使用详解
  2. python sum函数的用法
  3. ks:能定阈值的评价指标
  4. TDM-GCC MINGW配置与优化算法测试函数使用
  5. 名医高效良方(三叉神经痛)
  6. 北京市专精特新中小企业认定要求及流程,补贴60万
  7. Lua: Error during loading: \[string “/usr/share/wireshark/init.lua“\]:45
  8. 给一段下雪的代码。。。
  9. Tkinter:文本框Entry
  10. javascript正则检测用户名验证密码邮箱手机号