Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
Devices
hwtimer硬件定时器驱动和使用经验
发布于 2018-11-07 23:45:54 浏览:7560
订阅该版
1、 硬件定时器设备概述RT-Thread内置了已经内置了软件定时器,但是对于需求更高实时性或者定时精度的场合不太适用。RT-Thread提供了一种驱动设备框架提供硬件定时器驱动,源码位于drivers/hwtimer目录下。hwtimer本身不依赖于其他组件,直接添加到工程里面就能用。2、 硬件定时器驱动实现这里以stm32单片机内部的TIM6这个基本定时器为例,实现一个硬件定时器驱动。a) 至少要实现的接口初始化函数:这个函数用于实现对TIM6硬件的相关初始化。函数原型:void (*init)(struct rt_hwtimer_device *timer,rt_uint32_t state); 启动函数:这个函数用于启动TIM6硬件的定时功能函数原型:rt_err_t (*start)(struct rt_hwtimer_device *timer,rt_uint32_t cnt, rt_hwtimer_mode_t mode); 停止函数:这个函数用于停止TIM6硬件的定时功能函数原型:void (*stop)(struct rt_hwtimer_device *timer); 获取定时器计数值函数:这个函数用于获取TIM6的Counter值(似乎没啥用)函数原型:rt_uint32_t (*count_get)(struct rt_hwtimer_device*timer); 控制函数:用于对定时器进行控制,控制功能主要是设置定时器中断频率。函数原型:rt_err_t (*control)(struct rt_hwtimer_device *timer,rt_uint32_t cmd, void *args);b) 初始化函数实现方法初始化函数参数中有一个state参数,这里一定要判定这个值是否等于1,其他情况不要进行硬件初始化。代码片段:if(state==1){//先开启TIM6的时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);//对TIM6硬件进行默认参数初始化TIM_TimeBaseStructure6.TIM_Period = 10000-1;TIM_TimeBaseStructure6.TIM_Prescaler = 7200-1;TIM_TimeBaseStructure6.TIM_ClockDivision = 0x0;TIM_TimeBaseStructure6.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseStructure6.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure6);//开启TIM6的溢出中断请求TIM_ITConfig(TIM6,TIM_IT_Update, ENABLE);//先不启动TIM6这个定时器TIM_Cmd(TIM6, DISABLE);//配置TIM6的NVIC 这里省略具体配置过程NVIC_Timer6_Config();}c) 启动函数实现方法这个函数中的cnt和mode两个参数分别用于设置定时器的计数值和运行模式,这个计数值其实就是定时器的溢出值,当定时器计数到这个值的时候产生一次溢出中断请求。模式设置就两种,单次模式和连续模式,这里可以不用理会这个参数直接把定时器设置成连续模式,因为驱动框架中会在单次模式定时时间到了以后把定时器停掉(具体执行过程见hwtimer.c的第303行函数rt_device_hwtimer_isr)。这里不理会这个参数。代码片段://设置定时器溢出值TIM_TimeBaseStructure6.TIM_Period = cnt;//配置定时器TIM_TimeBaseInit(TIM6, dev);//启动定时器TIM_Cmd(TIM6, ENABLE);d) 停止函数实现方法这个函数很简单,直接禁能掉硬件定时器就是。代码片段:TIM_Cmd(TIM6,DISABLE);e) 控制函数实现方法这里函数中的cmd和arg分别用于指定命令类型和命令参数。其中arg是void指针,这里需要根据不同命令进行强转成需要的数据类型。这里我们只需要实现一种命令的实现,HWTIMER_CTRL_FREQ_SET,这个控制指令用于设置定时器的定时频率,此命令传入的参数类型是rt_uint32_t,用于指定频率值。根据这个值进行定时器的频率设定。代码片段:uint16_t val; //临时变量 用于存储计算出的分频值rt_uint32_t freq;//用于获取参数中的频率设定值//判定命令是不是 设置频率命令if(cmd == HWTIMER_CTRL_FREQ_SET){freq = *((rt_uint32_t*)arg);//从参数中获取频率设定值val = TIMER_CLK / freq;//算分频值TIM_TimeBaseStructure6. TIM_Prescaler=val-1;//设置硬件分频系数TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure6);//初始化TIM6硬件return RT_EOK;//返回正常值}f) 获取定时器计数值函数实现方法这个函数比较简单,直接返回定时器内部的计数值就行。return TIM_GetCounter(TIM6);g) 添加定时器到系统中 i. 根据rt_hwtimer_ops结构体定义实现一个实例,这个结构体将所有相关的硬件定时器操作函数集合在一起,根据结构体的成员把上面实现好的函数放在里面。代码片段:static struct rt_hwtimer_ops ops={rt_hwtimer_init,rt_hwtimer_start,rt_hwtimer_stop,rt_hwtimer_get,rt_hwtimer_control} ii. 根据rt_hwtimer_info 结构体定义实现一个实例,这个结构体用于界定定时器所能运行的频率范围和定时器最大计数值。static struct rt_hwtimer_info hw_timer6_info= { 100000,//最大频率2000,//最小频率0xFFFF,//最大计数值HWTIMER_MODE_PERIOD//周期模式}; iii. 使用rt_hwtimer_t结构体定义一个实例,这个结构体是硬件定时器设备结构体,把上面两步的两个结构体的地址赋值给这个实例的相应成员。然后使用rt_device_hwtimer_register函数注册这个设备到操作系统中。代码片段:timer6.info = &hw_timer6_info;timer6.ops = &ops;rt_device_hwtimer_register(&timer6, "timer6",RT_NULL);h) 中断函数实现方法中断函数中需要调用rt_device_hwtimer_isr函数通知驱动框架某个硬件定时器设备发生了溢出中断,使得驱动框架正常计时。代码片段:rt_interrupt_enter();//先进入临界区if(TIM_GetITStatus(TIM6,TIM_IT_Update) != RESET)//判定是不是溢出中断{ TIM_ClearITPendingBit(TIM6,TIM_IT_Update);//清中断标志rt_device_hwtimer_isr(&timer6);//调用驱动框架的中断通知函数} rt_interrupt_leave();//离开临界区3、 硬件定时器使用a) 初始化定时器使用rt_device_find函数查找设备,判定是否为空然后再进行下面的初始化等工作。rt_device_t rt_d;//定义一个设备指针rt_d = rt_device_find("timer6");//从操作系统中查找timer6这个设备if(rt_d == RT_NULL) return RT_ERROR;//判空rt_d->init(rt_d);//初始化b) 设置定时器中断频率rt_uint32_t p = 10000;//设置频率rt_d->control(rt_d,HWTIMER_CTRL_FREQ_SET,(void*)(&p));//调用控制函数进行频率设置,注意指针强转c) 打开定时器rt_d->open(rt_d,0);//最后一个参数没用d) 设置计时器定时时间rt_hwtimerval_t timeval;//这个结构体用于设置定时器计时时间timeval.sec = 2;//sec成员是多少秒timeval.usec = 0;//usec成员是多少微秒rt_d->write(rt_d,0,(void*)&timeval,sizeof(timeval));//使用写函数设置计时时间e) 挂回调函数rt_d->rx_indicate = &timer6_callback;//这个回调函数在计时时间到了以后会被自动调用 ![period.c](/uploads/201811/07/233955aua8eaz5aogew5o8.attach) ![drv_hwtime.c](/uploads/201811/07/234530yl0itjkkftk8jlo0.attach) ![drv_hwtimer.h](/uploads/201811/07/234530qxe1eyhyz6xmfu7i.attach)
查看更多
6
个回答
默认排序
按发布时间排序
whj467467222
认证专家
2018-11-08
开源,分享,交流,共同进步
zan
luzixing
2018-11-27
这家伙很懒,什么也没写!
在使用定时器时通过设置的中断频率和设置的定时器时间如何计算超时时间
微而不语
2018-11-28
这家伙很懒,什么也没写!
[i=s] 本帖最后由 微而不语 于 2018-11-28 14:34 编辑 [/i] 你这驱动写的不对
q80351951
2019-02-11
这家伙很懒,什么也没写!
b) 设置定时器中断频率 d) 设置计时器定时时间 这2个怎么理解?比如我想要一个100微秒的定时中断应该怎么做?
misonyo
2019-02-13
这家伙很懒,什么也没写!
>b) 设置定时器中断频率 >d) 设置计时器定时时间 --- 请参考官方文档:[https://www.rt-thread.org/document/site/programming-manual/device/hwtimer/hwtimer/](https://www.rt-thread.org/document/site/programming-manual/device/hwtimer/hwtimer/)
q80351951
2019-02-13
这家伙很懒,什么也没写!
>请参考官方文档:https://www.rt-thread.org/document/site/programming-manual/device/hwtimer/hwtimer/ ... --- 明白了多谢!
撰写答案
登录
注册新账号
关注者
0
被浏览
7.6k
关于作者
lzlz70707
这家伙很懒,什么也没写!
提问
2
回答
0
被采纳
0
关注TA
发私信
相关问题
1
问个问题,ili9320驱动里面rt_hw_lcd_draw_blit_line 这个函数是干什么用的
2
LCD双缓冲有什么好的办法实现
3
LCD NT35510 驱动代码
4
io设备驱动的疑惑与建议
5
液晶屏驱动 U8g2 移植
6
求助:在模板上添加LCD模块出现L6406E错误
7
硬件定时器超时时间计算问题
8
请教spi驱动lcd显示屏问题
9
rtt-master(3.1.1)bsp—armfly中drv_lcd.c中是不是错了啊?
10
不使用 RT-Thread 的驱动框架结构可以吗?
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
简单两步配置RTT源码阅读环境 vsc+clangd
2
恩智浦[FRDM-MCXN947]初探 之 ADC与DAC
3
LVGL使用字库IC芯片显示中文
4
基于STM32H750和Rt-Thread的CANFD通信实现的记录(一)
5
freemodbus主机在freertos的适配,参考rtthread例程
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
编译报错
Debug
SFUD
msh
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1443
个答案
289
次被采纳
张世争
805
个答案
174
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
4
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
1
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部