登录发现更多内容
首页
分类
发帖
账号
自动登录
找回密码
密码
登录
立即注册
立即登录
立即注册
其他登录
QQ
微信
首页
Portal
求助问答
Xiuno资源
Xiuno教程
Xiuno插件
Xiuno主题
休闲茶馆
定制主题
产品教程
BBS
求助问答
Xiuno资源
Xiuno教程
Xiuno插件
Xiuno主题
休闲茶馆
定制主题
开发资料
求助问答
Xiuno资源
Xiuno教程
Xiuno插件
Xiuno主题
休闲茶馆
定制主题
样品购买
求助问答
Xiuno资源
Xiuno教程
Xiuno插件
Xiuno主题
休闲茶馆
定制主题
IoT云平台
求助问答
Xiuno资源
Xiuno教程
Xiuno插件
Xiuno主题
休闲茶馆
定制主题
GitHub
求助问答
Xiuno资源
Xiuno教程
Xiuno插件
Xiuno主题
休闲茶馆
定制主题
技术博客
求助问答
Xiuno资源
Xiuno教程
Xiuno插件
Xiuno主题
休闲茶馆
定制主题
搜索
搜索
热搜:
LoRa
ESP8266
安信可
本版
帖子
用户
请
登录
后使用快捷导航
没有账号?
立即注册
每日签到
任务
广播
导读
排行榜
设置
我的收藏
退出
23
1
0
首页
小安派&M61零基础开发教程(官方)
›
(十五)零基础开发小安派-Eyes-S1【外设篇】——TIMER ...
1
2
3
/ 3 页
下一页
返回列表
(十五)零基础开发小安派-Eyes-S1【外设篇】——TIMER
[ 复制链接 ]
发布帖子
Ai-Thinker小泽
论坛元老
38
主题
539
回帖
6834
积分
论坛元老
论坛元老, 积分 6834, 距离下一级还需 9993165 积分
论坛元老, 积分 6834, 距离下一级还需 9993165 积分
积分
6834
私信
21人留言
楼主
小安派&M61零基础开发教程(官方)
7622
23
2023-12-14 20:37:00
# 零基础开发小安派-Eyes-S1【外设篇】——TIMER TIMER也就是定时器,定时器故名思意就是用来定时的东西,可以根据时钟源来分配计时的时间周期,实现准确的计时,一般软件的定时会出现误差,一些特殊情况需要精准的定时,那就需要使用到硬件定时器,如定时5分钟执行某些特殊任务。定时器可以搭配中断来使用,利用好时间间隔而满足我们的需求。 ## 一、了解小安派-Eyes-S1的TIMER 芯片内置了两个32-Bit定时器,这两个定时器在LHAL库里对应timer0和timer1。 这两组TIMER有以下特征: • 多种时钟来源,最高可支持 80M 时钟 • 8-bit 时钟分频器,分频系数为 1-256 • 两个 32-bit 定时器:channel 0 和 channel 1 • 定时器包含三组报警值设定,可设定报警值溢出时报警 • 支持 Free Run 模式和 Pre_load 模式 • 一个 16-bit 看门狗定时器 • 支持写入密码保护,防止误设定造成系统异常 • 支持中断或复位两种看门狗溢出方式 • 支持测量外部 GPIO 的脉冲宽度 定时器的时钟来源有以下五种选择: • BCLK--总线时钟 • 32K--32K 时钟 • 1K--1K 时钟(32K 的分频) • XTAL--外部晶振 • GPIO--外部 GPIO ``` #define TIMER_CLKSRC_BCLK 0 #define TIMER_CLKSRC_32K 1 #define TIMER_CLKSRC_1K 2 #define TIMER_CLKSRC_XTAL 3 #define TIMER_CLKSRC_GPIO 4 #define TIMER_CLKSRC_NO 5 ``` 计数模式有以下两种: 定时器计数模式分为两种: freerun(向上计数模式)、preload(重装载模式)。 ``` #define TIMER_COUNTER_MODE_PROLOAD 0 #define TIMER_COUNTER_MODE_UP 1 ``` 定时器一共三个 compare id, 用于设置不同的定时时间,可以当三个定时器使用。 ``` #define TIMER_COMP_ID_0 0 #define TIMER_COMP_ID_1 1 #define TIMER_COMP_ID_2 2 ``` ## 二、结构体与函数接口 ### struct bflb_timer_config_s 说明:Timer初始化配置结构体。 ``` struct bflb_timer_config_s { uint8_t counter_mode; uint8_t clock_source; uint8_t clock_div; uint8_t trigger_comp_id; uint32_t comp0_val; uint32_t comp1_val; uint32_t comp2_val; uint32_t preload_val; }; ``` |parameter| description| | ------- | ---------- | | counter_mode | 计数模式 | | clock_source | 时钟源选择 | | clock_div | 分频值 | | trigger_comp_id | 选择触发的最高 comp id(选择越高,则能够定时的个数越多) | | comp0_val | comp0 比较值 | | comp1_val | comp1 比较值(需要大于 comp0_val) | | comp2_val | comp2 比较值(需要大于 comp1_val) | | preload_val | 重装载值 | ### bflb_timer_init 说明: 初始化 timer。使用之前需要开启 timer ip 时钟。 ``` void bflb_timer_init(struct bflb_device_s *dev, const struct bflb_timer_config_s *config); ``` |parameter| description| | ------- | ---------- | | dev | 设备句柄 | | config | 配置项 | ### bflb_timer_deinit 说明: 反初始化 timer。 ``` void bflb_timer_deinit(struct bflb_device_s *dev); ``` |parameter| description| | ------- | ---------- | | dev | 设备句柄 | ### bflb_timer_start 说明: 启动 timer 。 ``` void bflb_timer_start(struct bflb_device_s *dev); ``` |parameter| description| | ------- | ---------- | | dev | 设备句柄 | ### bflb_timer_stop 说明: 停止 timer。 ``` void bflb_timer_stop(struct bflb_device_s *dev); ``` |parameter| description| | ------- | ---------- | | dev | 设备句柄 | ### bflb_timer_set_compvalue 说明: 设置 timer comp id 比较值。 ``` void bflb_timer_set_compvalue(struct bflb_device_s *dev, uint8_t cmp_no, uint32_t val); ``` |parameter| description| | ------- | ---------- | | dev | 设备句柄 | | cmp_no | comp id | | val | 比较值 | ### bflb_timer_get_compvalue 说明: 获取 comp id 比较值。 ``` uint32_t bflb_timer_get_compvalue(struct bflb_device_s *dev, uint8_t cmp_no); ``` |parameter| description| | ------- | ---------- | | dev | 设备句柄 | | cmp_no | comp id | | val | 比较值 | ### bflb_timer_get_countervalue 说明: 获取 timer 计数值。 ``` uint32_t bflb_timer_get_countervalue(struct bflb_device_s *dev); ``` |parameter| description| | ------- | ---------- | | dev | 设备句柄 | | return | 计数值 | ### bflb_timer_compint_mask 说明: timer comp 中断屏蔽开关。 ``` void bflb_timer_compint_mask(struct bflb_device_s *dev, uint8_t cmp_no, bool mask); ``` |parameter| description| | ------- | ---------- | | dev | 设备句柄 | | cmp_no | comp id | | mask | 是否屏蔽中断 | ### bflb_timer_get_compint_status 说明: 获取 timer comp id 中断匹配标志。 ``` bool bflb_timer_get_compint_status(struct bflb_device_s *dev, uint8_t cmp_no); ``` |parameter| description| | ------- | ---------- | | dev | 设备句柄 | | cmp_no | comp id | | return | 为 true 表示匹配 | ### bflb_timer_compint_clear 说明: 清除 timer comp id 中断标志。 ``` void bflb_timer_compint_clear(struct bflb_device_s *dev, uint8_t cmp_no); ``` |parameter| description| | ------- | ---------- | | dev | 设备句柄 | | cmp_no | comp id | ## 三、定时器的两种计数方式以及中断触发 ### 一、定时器时钟源的选择以及分频 以选择TIMER_CLKSRC_XTAL这个外部晶振的时钟源来举例,频率为40MHz,而分频系数,也就是结构体中的clock_div,这里系数可选0~255,选择39,时钟计数=时钟频率/(分频系数+1)。也就是40Mhz/(39+1),也就是1Mhz,而周期与频率互为倒数,也就是1us一个计数。这样分频的话就是一微秒计数+1。 ### 二、计数模式 TIMER有两种计数模式,分别是**freerun(向上计数模式)、preload(重装载模式)**。 **FreeRun模式下**,计数器的初始值为0,定时器开始后,累加计数,当达到计数最大值后,然后从 0 再次开始计数。而最大值的数量估计是comp0的数据类型最大值,也就是32位数据。 **相比之下,PreLoad模式就好用多了**,计数器的初始值是 PreLoad 寄存器的值,然后向上累加计数,当满足 PreLoad 条件时,计数器的值被置为 PreLoad 寄存器的值,然后计数器再次开始向上累加计数。 ### 三、中断 结构体有trigger_comp_id选择几个比较ID,如果选择三个ID的情况下,在定时器的计数器计数过程中,一旦计数器的值与三个比较器中的某比较值一致,该比较器的比较标志就会置位,并可以产生相应的比较中断。在所有的ID中断调节都达到后,会回到PreLoad的值,也就是preload_val重新开始计时。有如下一个示例的时序图,若预加载寄存器的值为 10,比较器 0 的值为 13,比较器 1 的值为 16,比较器 2 的值为 19。  在 FreeRun 模式下,定时器工作时序与 PreLoad 基本相同,只是计数器会从 0 开始累计到最大值,期间产生的比较标志和比较中断的机制与 FreeRun 模式相同。 ## 四、简单示例——定时器分频一秒进入一次中断,在中断修改全局变量在主函数中打印 ### Main ``` #include "bflb_mtimer.h" #include "bflb_timer.h" #include "board.h" struct bflb_device_s *timer0; volatile static uint16_t MyTime_s = 0; //定义一个全局变量,在中断中修改,这里注意要用volatile关键字防止变量被优化 void timer0_isr(int irq, void *arg) { bool status = bflb_timer_get_compint_status(timer0, TIMER_COMP_ID_0); if (status) { bflb_timer_compint_clear(timer0, TIMER_COMP_ID_0); if (MyTime_s==60) { MyTime_s = 0; } MyTime_s++; printf("time is %d\r\n",MyTime_s); } } //中断服务函数,每进入一次变量自增1,到达60也就是1分钟置为0 int main(void) { board_init(); printf("Timer basic test\n"); /* timer clk = XCLK/(div + 1 )*/ struct bflb_timer_config_s cfg0; cfg0.counter_mode = TIMER_COUNTER_MODE_PROLOAD; /* 选择重装载模式 */ cfg0.clock_source = TIMER_CLKSRC_XTAL;//选择外部时钟晶振,40MHz cfg0.clock_div = 39; /* for bl616/bl808/bl606p is 39, for bl702 is 31 */ cfg0.trigger_comp_id = TIMER_COMP_ID_0;//选择比较ID的个数,这里选择一个ID,也就是只会到达下面的ID1 cfg0.comp0_val = 1000000; /* 比较值ID1,当计数达到1000000时,根据前面的分频一微秒一个计数,也就是总共1秒 */ cfg0.comp1_val = 2500000; /* 比较值ID2,需要大于ID1,由于前面只设置了一个ID,所以这里不会触发 */ cfg0.comp2_val = 3500000; /* 比较值ID2,需要大于ID2,由于前面只设置了一个ID,所以这里不会触发 */ cfg0.preload_val = 0; /* 重装载值,开始的值,以及比较完所有ID个数后重启的值 */ timer0 = bflb_device_get_by_name("timer0"); /* Timer init with default configuration */ bflb_timer_init(timer0, &cfg0); bflb_irq_attach(timer0->irq_num, timer0_isr, NULL); bflb_irq_enable(timer0->irq_num); /* Enable timer */ bflb_timer_start(timer0);//开启定时器 printf("case success.\r\n"); while (1) { switch (MyTime_s) { case 10: printf("10 seconds have passed\r\n"); break; case 20: printf("20 seconds have passed\r\n"); break; case 30: printf("30 seconds have passed\r\n"); break; case 40: printf("40 seconds have passed\r\n"); break; case 50: printf("50 seconds have passed\r\n"); break; case 60: printf("One minute has already passed\r\n"); break; default: break; } //对全局变量进行判断,通过switch语句分别打印 bflb_mtimer_delay_ms(900); //这个延迟是为了防止在主函数中重复判断导致疯狂打印 } } ``` ### 效果 
点赞
1
收藏
0
淘帖
2
────
1
人觉得很赞
────
本帖被以下淘专辑推荐:
·
小安派S1&M61教程合集
|
主题: 19, 订阅: 5
·
小安派&M61零基础教程
|
主题: 19, 订阅: 5
回复
使用道具
举报
21 回复
电梯直达
正序浏览
倒序浏览
正序浏览
沙发
AXK123456
回复
使用道具
举报
2023-12-14 20:38:31
前排围观
回复
评论
使用道具
举报
板凳
iiv
回复
使用道具
举报
2023-12-14 21:52:58
泽哥终于又出马了
回复
评论
使用道具
举报
地板
shawnting
回复
使用道具
举报
2023-12-14 23:09:12
围观一下
回复
评论
使用道具
举报
5
#
bzhou830
回复
使用道具
举报
2023-12-15 08:33:22
前排围观
回复
评论
使用道具
举报
选择去发光,而不是被照亮
6
#
爱笑
回复
使用道具
举报
2023-12-15 08:37:00
回复
评论
使用道具
举报
用心做好保姆工作
7
#
WT_0213
回复
使用道具
举报
2023-12-15 09:01:31
学习
回复
评论
使用道具
举报
8
#
1084504793
回复
使用道具
举报
2023-12-15 09:02:12
学到了
回复
评论
使用道具
举报
9
#
lazy
回复
使用道具
举报
2023-12-15 09:11:43
学习了
回复
评论
使用道具
举报
10
#
干簧管
回复
使用道具
举报
2023-12-15 09:18:11
泽哥开始更新了
回复
评论
使用道具
举报
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
立即登录
手机登录
点评
高级模式
本版积分规则
回帖并转播
回帖后跳转到最后一页
下一页 »
1
2
3
/ 3 页
下一页
今日推荐
AiPi-PalChatV1_“湾湾小何”提示音测试固件V2.9_UART-MCP
[WB2] 实现自动发现局域网下的设备
热帖排行
[AiPi-PalchatV1] [Windows] 克隆仓库和在线烧录遇到的一些小问
AT+MQTTPUBRAW指令所支持的最大数据传输量是多少
AiPi-PalChatV1_UART-MCP_v2.8 UART-MCP 协议配置 问题
Ai-WB2蓝牙怎么连接打印机
AI-WB2-12F电脑蓝牙连接秒断,手机搜索不到
AiPi-PalChatV1_“湾湾小何”提示音测试固件V2.9_UART-MCP
从零搭建 Ai-WB2 开发板的 Linux 开发环境—— 基于 VMware 虚拟
【公告】第九期电子DIY活动中奖通知
统计信息
会员数: 30471 个
话题数: 44643 篇
首页
分类
我的