2.9. TIMER
Overview
提供TIMER应用示例、常见问题。
2.9.1. 应用实例
示例演示:
可用定时器选择
定时器中断/轮询方法使用
开始/暂停/继续/停止/计时功能使用
定时器捕获功能使用
1.以上整体功能example: 具体示例代码详见
apps/common/example/peripheral/timer/test1.c
,示例工程实现需在apps/demo/demo_DevKitBoard/include/demo_config.h
中开启宏USE_TIMER_TEST2_DEMO
。
Note
c_main()入口:
A)timer_clk = clk_get(“timer”);//先获取定时器的时钟源
B)request_irq(timer_irq, 3, timer_isr, 0);//注册中断函数定和中断优先级
C)timer_set(50 * 1000);//初始化50ms进一次中断
D)os_time_dly(500);//延时5s后,timer4_stop();//定时器停止
E)os_time_dly(500);//延时5s后,timer4_run(2);//定时器开始
F)os_time_dly(500);//延时5s后,test();//输入捕获功能测试,引脚为PC8
test()入口:
A)timer5_init(1);//定时器5初始化,1代表下降沿捕获
B)while(1)//进入while循环中
while(1):
A)timer5_start();//清空数据
B)while(!timer5_interrupt())
- {
os_time_dly(20);//检测到有下降沿则为true,采用轮询方式每200ms检测一次
}
C) printf(”——-%s——-%d get cnt = %drn”,__func__,__LINE__,timer5_get_cnt()); //返回出来的单位是10us 的cnt 就是 cnt* 100 000就是秒
2.定时中断example: 具体示例代码详见
apps/common/example/peripheral/timer/test2.c
,示例工程实现需在apps/demo/demo_DevKitBoard/include/demo_config.h
中开启宏USE_TIMER_TEST1_DEMO
。3.如果想获得精确的time_delay,可以如下配置:
static void timer_cfg(u32 freq, u32 us) { JL_TIMER_TypeDef *TMR = JL_TIMER4;//选择定时器4 u8 timer_irq = IRQ_TIMER4_IDX;//选择定时器4 const u8 timer_index[16] = {0, 4, 1, 5, 2, 6, 3, 7, 8, 12, 9, 13, 10, 14, 11, 15}; const u32 timer_table[16] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768}; u32 clock = clk_get("timer"); u8 psc = 0; u8 tmp = 0; u32 prd = 0; u32 ts = us / (1000 * 1000);//计算秒 u32 tu = us % (1000 * 1000);//计算秒剩余us u8 i; float tp = 0; if (freq >= clock) { freq = clock; } else if (freq <= 1) { freq = 1; if (ts) { tp = (float)tu / (1000 * 1000); } } /*求prd值*/ prd = clock / freq; if (prd > 65535) { for (psc = 0; psc < 16; psc++) { prd = (u32)(clock / (timer_table[psc]) / freq); if (prd <= 65535) { break; } else if (psc == 15) { prd = 65535; break; } } } prd = ts ? (prd * ts + tp * prd) : prd; psc = timer_index[psc]; TMR->CON = 0; TMR->CNT = 0; TMR->CON |= BIT(14); TMR->PRD = prd; TMR->CON |= psc << 4; //lsb_clk分频 TMR->CON |= BIT(0); while(!(TMR->CON & BIT(15))); TMR->CON |= BIT(14); TMR->CON = 0; } void time_delay(u32 us)//设置时间 { u32 freq = 1000000 / us; timer_cfg(freq, us);//传参:当只需要设置频率,则us = 0 }
2.9.2. 常见问题
定时器频率比较高,中断响应慢,或者使得系统变慢。
答:中断函数和中断函数调用函数全部指定在内部sram,指定方法:在函数定义加上
SEC_USED(.volatile_ram_code)
。建议中断时间<=1ms使用这种方法,以便提高整个系统效率。
例如:
static SEC_USED(.volatile_ram_code)
void timer_cfg(u32 freq, u32 us)