1.SysTick分析
在board.c中,提到了定时器0.如下图
将关于定时器和systick的代码进行分析。
// 定时器0中断
void timer0_isr(int vector, void param)
{
rt_interrupt_enter();
TMR0CPND = BIT(9); // timer0中断清除标志位
rt_tick_increase(); // 滴答时钟增加
rt_interrupt_leave();
}
void timer0_init(void)
{
TMR0CON = BIT(7); //使能溢出中断
TMR0CNT = 0; // timer0 计数值清0
rt_hw_interrupt_install(IRQ_TMR0_VECTOR, timer0_isr, RT_NULL, "tick"); // 注册中断
}
void timer0_cfg(uint32_t ticks)
{
TMR0PR = (uint32_t)(ticks - 1UL); //1ms interrupt
TMR0CON |= BIT(0); // EN 使能timer0
}
// 系统时钟初始化
void rt_hw_systick_init(void)
{
CLKCON2 &= 0x00ffffff;
CLKCON2 |= (25 << 24); //配置x26m_div_clk = 1M (timer, ir, fmam ...用到)
CLKCON0 &= ~(7 << 23);
CLKCON0 |= BIT(24); //tmr_inc select x26m_div_clk = 1M
set_sysclk(SYSCLK_48M); // 最高可倍频到120MHz
/ Setting software interrupt */
set_cpu_irq_comm(cpu_irq_comm);
rt_hw_interrupt_install(IRQ_SW_VECTOR, rt_soft_isr, RT_NULL, "sw_irq");
timer0_init();
hal_set_tick_hook(timer0_cfg);
hal_set_ticks(get_sysclk_nhz()/RT_TICK_PER_SECOND); // get_sysclk_nhz()/RT_TICK_PER_SECOND = 48000
PICCON |= 0x10002; // 中断向量表使能
}
2.软件定时器的使用
#include "main.h"
// 函数定义
static void Led_TimerCallback(void *parameter);
// 变量定义
int8_t flag = 0;
static void Led_TimerCallback(void parameter){
RGB_Blue(~flag);
flag = ~flag;
}
/
软件定时器
*/
rt_timer_t Timer_Init(void){
return rt_timer_create("led", Led_TimerCallback, RT_NULL, 1000, RT_TIMER_FLAG_PERIODIC); //创建一个1s周期定时器
}
int Timer_Start(void){
RGB_Init();
rt_timer_t timer = Timer_Init();
rt_timer_start(timer);
return 0;
}
INIT_APP_EXPORT(Timer_Start);
效果:RGB灯蓝光间隔一秒闪烁
3.硬件定时器
配置
代码
rt_device_t hw_dev; //设备句柄
rt_hwtimer_mode_t mode; //控制参数,单次定时OR周期定时
rt_hwtimerval_t timeout_t; //定时器超出值
/* 定时器超时回调函数 /
rt_err_t timeout_cb(rt_device_t dev, rt_size_t size)
{
rt_kprintf("this is hwtimer timeout callback fucntion!\n");
return 0;
}
int hw_sample(void)
{
rt_err_t ret = RT_EOK;
/ 查找设备 /
hw_dev = rt_device_find("timer1");
if(hw_dev == RT_NULL)
{
rt_kprintf("find %s failed\t\n", "timer1");
return RT_ERROR;
}
/ 查找设备成功 /
rt_kprintf("find %s success \t\n","timer1");
/ 以读写的方式打开设备 /
rt_device_open(hw_dev, RT_DEVICE_OFLAG_RDWR);
/ 设置定时器工作模式为周期定时 /
mode = HWTIMER_MODE_PERIOD;
rt_device_control(hw_dev, HWTIMER_CTRL_MODE_SET, &mode);
/ 超值回调函数 /
rt_device_set_rx_indicate(hw_dev, timeout_cb);
/ 配置超时值 */
timeout_t.sec = 5;
timeout_t.usec = 0;
rt_device_write(hw_dev, 0, &timeout_t, sizeof(timeout_t));
return RT_EOK;
}
INIT_APP_EXPORT(hw_sample);
4.总结
RT-Thread的系统时钟,使用timer0,精度为1ms。因此,在使用硬件定时器时,不能使用定时器0.
原作者: JiangYangJie
|