CH32V203 TIM的CNT寄存器是否可以动态写入

测试的时候发现, 更新ARR后, 关闭TIM, CNT写入0, 然后启动TIM, 对于TIM3是存在问题的, TIM4则没问题, TIM3会出现断续

1676986036197334.jpg

1676986036829180.jpg

1676986037177810.jpg


您好,定时器的CNT寄存器是可读可写的,可以动态写入。注意修改完重装载寄存器ARR的值之后,需调用TIM_ARRPreloadConfig函数使能开启ARR配置,否则会有问题,你可以按照该要求试一下。后续若有问题,可通过邮箱(lzs@wch.cn)和我沟通



你好, 问题依旧, 下面是我TIM3的改变频率的代码,

void tim3_update_set_frequency(uint32_t f){
    uint32_t period = 0;
    // static uint16_t ccr = 0;
    static uint32_t minfreq = 0, maxfreq = 0;

    if(minfreq == maxfreq){
        uint16_t ccr = 0;
        ccr = TIM_GetCapture1(TIM3);
        minfreq = STEP_TIM_CLK / (UINT16_MAX - ccr - 1) + 1;
        maxfreq = STEP_TIM_CLK / (ccr + 1) - 1;
        // printf("%ldHz < f < %ldHz\n", minfreq, maxfreq);
    }
   
    if(f == 0){
        tim3_update_set_status(0);
        return;
    }else if(f < minfreq){
        f = minfreq;
    }else if(f > maxfreq){
        f = maxfreq;
    }
    period = (STEP_TIM_CLK / f);
   
    // TIM_SetCounter(TIM3, 0);   /// TIM3 不要动态写CNT, 会出现断续
    TIM_SetAutoreload(TIM3, (uint16_t)period);
    TIM_ARRPreloadConfig(TIM3, ENABLE);
    // TIM_SetCounter(TIM3, 0);   /// TIM3 不要动态写CNT, 会出现断续
    // tim3_update_set_status(1);   /// 不要重新启动, 速度模式会出现问题
}


取消注释

TIM_SetCounter(TIM3, 0);


会出现以下情况:第一个中断响应完后定时器像是停止计数一样, 过一段时间又会恢复.

image.png

展开第一个脉冲位置,时序如下:


image.png


注释

TIM_SetCounter(TIM3, 0);   /// TIM3 不要动态写CNT, 会出现断续


则是正常的.


image.png


TIM4改变频率的代码,

void tim4_update_set_frequency(uint32_t f){
    uint32_t period = 0;
    // static uint16_t ccr = 0;
    static uint32_t minfreq = 0, maxfreq = 0;

    if(minfreq == maxfreq){
        uint16_t ccr = 0;
        ccr = TIM_GetCapture1(TIM4);
        minfreq = STEP_TIM_CLK / (UINT16_MAX - ccr - 1) + 1;
        maxfreq = STEP_TIM_CLK / (ccr + 1) - 1;

        // printf("%ldHz < f < %ldHz\n", minfreq, maxfreq);
    }
   
    if(f == 0){
        tim4_update_set_status(0);
        return;
    }else if(f < minfreq){
        f = minfreq;
    }else if(f > maxfreq){
        f = maxfreq;
    }
    period = (STEP_TIM_CLK / f);
    // TIM_SetCounter(TIM4, 0);
    TIM_SetAutoreload(TIM4, (uint16_t)period);
    TIM_ARRPreloadConfig(TIM4, ENABLE);
    // tim4_update_set_status(1);   
}


对于TIM4都是正常的。











之所以要写入ARR后要CNT置零,是因为测试过程发现TIM2 UPDATE 中断里计算新的频率,花时在3us到8us之间,如果刚好卡在TIM3 OC1和UPDATE之间,会导致控制管脚低电平时间过短,频率过度不顺滑, 比如会出现下面情况:


image.png


重新计数我可以保证有足够的低电平时间,


image.png


所有定时器中断优先级是相同的,不用嵌套的原因在于计算频率的数据要依靠其他中断里的数据,嵌套就很难保证完整性和准确性了


您好,这边模拟你的应用测试了一下,并没有出现断续的问题,若方便,可将你的程序发至我的邮箱(lzs@wch.cn)这边看一下具体复现一下,并在此基础上检查一下问题帮助你修改程序,有什么问题也可以具体沟通一下。

image.png

image.png




只有登录才能回复,可以选择微信账号登录