FR801xH 硬件定时器能支持us级精度吗,如何支持,目前80us定时不准



  • 参照demo及文档使用定时器有以下几个疑问,希望知到的大佬能解答?

    1、使用us级定时时,目前测试80us 和 160us,while循环中直接调用接口函数uint32_t timer_get_current_value(uint32_t timer_addr)获取并打印到的当前计数值非线性递减,而是在定时范围内在随机值,这正常吗?

    2、开启中断后,定时80us,在中断中进行IO翻转,通过示波器测量,80us在脉冲实际上变成200us左右在脉冲。每次进中断的间隔,通过打印计数也不准。

    3、单次计时模式和周期计时模式的区别是否仅仅是重装定时值的区别,无论哪种模式,中断都会一直进(目前测试是这样,中断标志位每次进中断都会清)。

    4、定时器初始化中关于100us以下在定时限制已经注释,上述现象一样存在,目前需求是准确的us级定时,想知道如何实现
    uint8_t timer_init(uint32_t timer_addr, uint32_t count_us, uint8_t run_mode)
    {
    uint8_t sysclk;
    uint16_t count;
    uint8_t prescale;

    // if(count_us < 100)
    // {
    // return false;
    // }

    prescale = timer_calc_prescale(count_us);
    if(prescale == TIMER_PRESCALE_MAX)
    {
        return false;
    }
    
    sysclk = system_get_pclk_config();
    if(prescale == TIMER_PRESCALE_1)
    {
        count = count_us*sysclk;
    }
    else if(prescale == TIMER_PRESCALE_16)
    {
        count = (count_us * sysclk) >> 4;
    }
    else if(prescale == TIMER_PRESCALE_256)
    {
        count = (count_us * sysclk) >> 8;
    }
    
    volatile struct timer *timerp = (volatile struct timer *)timer_addr;
    
    timerp->control.count_enable = 0;
    timerp->control.count_mode = run_mode;
    timerp->control.pselect = prescale;
    timerp->interrupt_clear.data = 0x01;
    timerp->load_value.load = count;
    
    return true;
    

    }



  • 你要实现什么功能



  • 希望实现的功能是,通过定时器实现us级延时


    在任务中开启定时器,定时60us后,在while死循环阻塞,循环中读取定时器当前定时值,定时值为0则退出死循环完成60us延时,目前通过该逻辑的代码无法实现。(不使用延时函数co_delay_10us,实际使用时,误差太大超过10us。)



  • 本来我也想用80us定时中断来做遥控器的发送。可是,常常丢包,接着,我把80us做中断分个240us做驱动蜂鸣器,发现蜂鸣器的声音会有破音。所以,你想80us定时准可能有点难,要FAE动到底层。



  • @xiexie 用中断还是可以做在,你把主频调高到48M,代码输入段指定到ram,优化代码,尽量直接操作寄存器。