测试的时候发现, 更新ARR后, 关闭TIM, CNT写入0, 然后启动TIM, 对于TIM3是存在问题的, TIM4则没问题, TIM3会出现断续
您好,定时器的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);
会出现以下情况:第一个中断响应完后定时器像是停止计数一样, 过一段时间又会恢复.
展开第一个脉冲位置,时序如下:
注释
TIM_SetCounter(TIM3, 0); /// TIM3 不要动态写CNT, 会出现断续
则是正常的.
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之间,会导致控制管脚低电平时间过短,频率过度不顺滑, 比如会出现下面情况:
重新计数我可以保证有足够的低电平时间,
所有定时器中断优先级是相同的,不用嵌套的原因在于计算频率的数据要依靠其他中断里的数据,嵌套就很难保证完整性和准确性了
您好,这边模拟你的应用测试了一下,并没有出现断续的问题,若方便,可将你的程序发至我的邮箱(lzs@wch.cn)这边看一下具体复现一下,并在此基础上检查一下问题帮助你修改程序,有什么问题也可以具体沟通一下。