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)