【中科蓝讯AB32VG1 RISC-V板“碰上”RTT测评】软件定时器+硬件定时器
本帖最后由 xiyue521 于 2021-5-7 14:06 编辑<p><span style="font-size:24px;">概述:</span></p>
<p><span style="font-size:24px;">1)硬件定时器是芯片本身提供的定时功能。一般是由外部晶振提供给芯片输入时钟,芯片向软件模块提供一组配置寄存器,接受控制输入,到达设定时间值后芯片中断控制器产生时钟中断。硬件定时器的精度一般很高,可以达到纳秒级别,并且是中断触发方式。</span></p>
<p><span style="font-size:24px;">2)软件定时器是由操作系统提供的一类系统接口,它构建在硬件定时器基础之上,使系统能够提供不受数目限制的定时器服务。</span></p>
<p><span style="font-size:24px;">RT-Thread 操作系统提供软件实现的定时器,以时钟节拍(OS Tick)的时间长度为单位,即定时数值必须是 OS Tick 的整数倍,例如一个 OS Tick 是 10ms,那么上层软件定时器只能是 10ms,20ms,100ms 等,而不能定时为 15ms。RT-Thread 的定时器也基于系统的节拍,提供了基于节拍整数倍的定时能力。</span></p>
<p><span style="font-size:24px;">1.先来看看软件定时器的使用:</span></p>
<p><span style="font-size:24px;">软件定时器其实可以看做是一个特殊的任务,对比一下线程和定时器的创建就知道了,很相似,就是软件定时器功能只有定时。</span></p>
<p> </p>
<p> </p>
<p><span style="font-size:24px;">rt_timer_create 与rt_thread_create</span></p>
<p> </p>
<p><span style="font-size:24px;">rt_timer_start 与rt_thread_startup</span></p>
<p> </p>
<p><span style="font-size:24px;">定时器创建:</span></p>
<p> </p>
<p> </p>
<p> </p>
<p class="imagemiddle" style="text-align: center;"><span style="font-size:24px;"></span></p>
<p> </p>
<p> </p>
<p><span style="font-size:24px;">线程创建:</span></p>
<p class="imagemiddle" style="text-align: center;"><span style="font-size:24px;"></span></p>
<p> </p>
<p> </p>
<p><span style="font-size:24px;">rt_timer_t rt_timer_create(const char *name,</span></p>
<p><span style="font-size:24px;"> void (*timeout)(void *parameter),</span></p>
<p><span style="font-size:24px;"> void *parameter,</span></p>
<p><span style="font-size:24px;"> rt_tick_t time,</span></p>
<p><span style="font-size:24px;"> rt_uint8_t flag)</span></p>
<p><span style="font-size:24px;">主要就是void (*timeout)(void *parameter),和time这两个参数,一个是定时器回调函数指针,一个是定时的时间,单位和时间片有关,就是他的整数倍了。</span></p>
<p><span style="font-size:24px;">软件定时器使用比较简单类比下线程创建即可。</span></p>
<p><span style="font-size:24px;">代码:</span></p>
<div aria-label="代码段 小部件" contenteditable="false" role="region" tabindex="-1">
<pre data-widget="codesnippet">
<code class="hljs">
static void Led_TimerCallback(void *parameter){
RGB_Blue(~flag);
flag = ~flag;
}
int Timer_Start(void){
RGB_Init();
rt_timer_t timer= rt_timer_create("soft_timer",
Led_TimerCallback,
RT_NULL,
1000,
RT_TIMER_FLAG_PERIODIC
);//创建一个1s周期定时器
rt_timer_start(timer);
return 0;
}
INIT_APP_EXPORT(Timer_Start);
</code></pre>
<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" /><span style="background: url("https://bbs.eeworld.com.cn/static/editor/plugins/widget/images/handle.png") rgba(220, 220, 220, 0.5); top: -15px; left: 0px; display: block;"><img height="15" role="presentation" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" title="点击并拖拽以移动" width="15" /></span></div>
<p><span style="font-size:24px;">2.再来看看硬件定时器,这个就比较麻烦了,要先在RTThread setings使能timer1,然后保存下,</span></p>
<p> </p>
<p> </p>
<p class="imagemiddle" style="text-align: center;"><span style="font-size:24px;"></span></p>
<p class="imagemiddle" style="text-align: center;"> </p>
<p class="imagemiddle" style="text-align: center;"> </p>
<p><span style="font-size:24px;"> 先查找设备: <br />
hw_timer = rt_device_find("timer1");</span></p>
<p><span style="font-size:24px;"> 以读写的方式打开设备 :<br />
rt_device_open(hw_timer, RT_DEVICE_OFLAG_RDWR);</span></p>
<p> </p>
<p><span style="font-size:24px;"> 设置定时器工作模式为周期定时 :<br />
timer_mode = HWTIMER_MODE_PERIOD;<br />
rt_device_control(hw_timer, HWTIMER_CTRL_MODE_SET, &timer_mode);</span></p>
<p><span style="font-size:24px;">有以下几个参数:用HWTIMER_CTRL_MODE_SET</span></p>
<p><span style="font-size:24px;"></span></p>
<p> </p>
<p><span style="font-size:24px;"> /超值回调函数 :<br />
rt_device_set_rx_indicate(hw_timer, timeout_cb);</span></p>
<p> </p>
<p><span style="font-size:24px;"> /配置超时值 :<br />
timeout_t.sec = 5;<br />
timeout_t.usec = 0;<br />
rt_device_write(hw_timer, 0, &timeout_t, sizeof(timeout_t));</span></p>
<p><span style="font-size:24px;"></span></p>
<p><span style="font-size:24px;">其中可以设置秒和ms</span></p>
<p class="imagemiddle" style="text-align: center;"> </p>
<p class="imagemiddle"><span style="font-size:24px;">现象:</span></p>
<p class="imagemiddle" style="text-align: center;"><span style="font-size:24px;"></span></p>
<p class="imagemiddle"><span style="font-size: 24px;">代码:</span></p>
<pre>
<code>
/* 定时器超时回调函数 */
rt_err_t timeout_cb(rt_device_t dev, rt_size_t size)
{
rt_kprintf("hwtimer timeout callback fucntion!\n");
return 0;
}
int hw_sample(void)
{
rt_err_t ret = RT_EOK;
/* 查找设备 */
hw_timer = rt_device_find("timer1");
if(hw_timer == RT_NULL)
{
rt_kprintf("find %s failed\t\n", "time1");
return RT_ERROR;
}
/* 查找设备成功 */
rt_kprintf("find %s success \t\n","");
/* 以读写的方式打开设备 */
rt_device_open(hw_timer, RT_DEVICE_OFLAG_RDWR);
/* 设置定时器工作模式为周期定时 */
timer_mode = HWTIMER_MODE_PERIOD;
rt_device_control(hw_timer, HWTIMER_CTRL_MODE_SET, &timer_mode);
/* 超值回调函数 */
rt_device_set_rx_indicate(hw_timer, timeout_cb);
/* 配置超时值 */
timeout_t.sec = 5;
timeout_t.usec = 0;
rt_device_write(hw_timer, 0, &timeout_t, sizeof(timeout_t));
return RT_EOK;
}
INIT_APP_EXPORT(hw_sample);
</code></pre>
<p class="imagemiddle" style="text-align: center;"> </p>
<p class="imagemiddle" style="text-align: center;"> </p>
<p class="imagemiddle" style="text-align: center;"> </p>
<p class="imagemiddle" style="text-align: center;"> </p>
<p class="imagemiddle" style="text-align: center;"> </p>
<p class="imagemiddle" style="text-align: center;"> </p>
<p class="imagemiddle" style="text-align: center;"> </p>
<p class="imagemiddle" style="text-align: center;"> </p>
<p class="imagemiddle" style="text-align: center;"> </p>
<p class="imagemiddle" style="text-align: center;"> </p>
<p class="imagemiddle" style="text-align: center;"> </p>
<p class="imagemiddle" style="text-align: center;"> </p>
<p> </p>
<p> </p>
<p> </p>
补充内容 (2021-5-9 00:20):
2.先来看看本芯片AB322VG1的硬件定时器外设资源:一种是基本定时器,仅支持32位定时器功能,分别为定时器0/1/2;另一种是带有高级功能的定时器,其支持定时器模式、计数器模式、捕获模式以及PWM模式,为定时器3/4/... <p style="text-align:justify">本芯片AB322VG1的硬件定时器外设资源:一种是基本定时器,仅支持32位定时器功能,分别为定时器0/1/2;另一种是带有高级功能的定时器,其支持定时器模式、计数器模式、捕获模式以及PWM模式,为定时器3/4/5。</p>
<p style="text-align:justify"></p>
<p style="text-align:justify">本次主要使用了TIMER1,设计到的寄存器有:</p>
<p style="text-align:justify">TIMER1CON: 定时器1控制寄存器;</p>
<p style="text-align:justify">TIMER1CPND:定时器1清除挂起寄存器;</p>
<p style="text-align:justify">TIMER1CNT: 定时器1计数器寄存器;</p>
<p style="text-align:justify">TIMER1PR:定时器1周期寄存器</p>
<p>硬件定时器是先查找设备,在RTThread setings使能timer1,再保存,步骤有点多</p>
<p> </p>
页:
[1]