PWMV2固定占空比修改频率方法
前言
固定占空比改变频率功能是先楫pwmv2提供的众多功能之一。该功能被广泛用于电源管理、加热元件控制等应用,在保持电压输出稳定的同时,根据负载条件调整频率以优化性能。本文将介绍pwmv2实现相关功能的配置选项。
实现原理
pwmv2的pwm波的周期是由reload值确定的。占空比是根据每个通道的compare值和reload值的相对关系确定的。在通常情况下
\text{duty\_cycle} = \frac{\text{compare2} \ - \ \text{compare1}}{reload}
因此在实现固定占空比修改频率时,我们需要将compare
值和reload
值建立比例关系,再修改通道的reload
值即可解决。
实现
在pwmv2中,可以在硬件上实现reload和compare之间的比例关系,也可将计算好的compare值直接更新到工作寄存器,以实现固定占空比输出。
硬件实现
通用计算单元是pwmv2中独特的组成,通用计算单元建立了关联的compare
值和关联计数器的周期值reload以及外部输入DAC值之间的联系。如下公式,S为补偿值,pD为DAC系数,pT为周期T的系数。
compare = S + DAC * pD + T *pT
在实现固定占空比应用时,由于不涉及DAC值的输入,我们将通用计算单元的DAC值加权系数设置为0,将补偿值设置为0,将周期T的系数设置为所需比例,即可在硬件上建立compare值和周期reload值的关系。
目前,通用计算单元的pT
值提供下列比例选项
-\frac{\text{15}}{8}、-\frac{\text{14}}{8}、...\ \ \frac{\text{14}}{8}、\frac{\text{15}}{8}
代码实现
- 硬件配置
/* 配置compare0、1来自通用计算单元0、1 */
pwmv2_select_cmp_source(PWM, PWMV2_CMP_INDEX(0), cmp_value_from_calculate, PWMV2_CALCULATE_INDEX(0));
pwmv2_select_cmp_source(PWM, PWMV2_CMP_INDEX(1), cmp_value_from_calculate, PWMV2_CALCULATE_INDEX(1));
pwmv2_cmp_update_trig_time(PWM, PWMV2_CMP_INDEX(0), pwm_shadow_register_update_on_reload);
pwmv2_cmp_update_trig_time(PWM, PWMV2_CMP_INDEX(1), pwm_shadow_register_update_on_reload);
/* 配置计数器计算单元的DAC系数为0 */
pwmv2_counter_set_dac_data_parameter(PWM, pwm_counter_0, 0);
/* 配置通用计算单元上下限 */
pwmv2_calculate_set_up_limit_parameter(PWM, PWMV2_CALCULATE_INDEX(0), 8);
pwmv2_calculate_set_low_limit_parameter(PWM, PWMV2_CALCULATE_INDEX(0), 0);
/* 配置通用计算单元周期系数和DAC系数 */
pwmv2_calculate_set_period_parameter(PWM, PWMV2_CALCULATE_INDEX(0), cmp_value0_factor);
pwmv2_calculate_set_dac_value_parameter(PWM, PWMV2_CALCULATE_INDEX(0), 0);
/* 配置通用计算单元周期T来源和偏移值来源 */
pwmv2_calculate_select_counter_calculate_index(PWM, PWMV2_CALCULATE_INDEX(0), PWM_PRIVATE_CLAC_0);
pwmv2_calculate_select_in_offset(PWM, PWMV2_CALCULATE_INDEX(0), 31);
pwmv2_calculate_select_low_limit_offset(PWM, PWMV2_CALCULATE_INDEX(0), PWMV2_SHADOW_INDEX(1));
/* 配置compare1关联的通用计算单元 */
pwmv2_calculate_set_up_limit_parameter(PWM, PWMV2_CALCULATE_INDEX(1), 8);
pwmv2_calculate_set_low_limit_parameter(PWM, PWMV2_CALCULATE_INDEX(1), 0);
pwmv2_calculate_set_period_parameter(PWM, PWMV2_CALCULATE_INDEX(1), cmp_value1_factor);
pwmv2_calculate_set_dac_value_parameter(PWM, PWMV2_CALCULATE_INDEX(1), 0);
pwmv2_calculate_select_counter_calculate_index(PWM, PWMV2_CALCULATE_INDEX(1), PWM_PRIVATE_CLAC_0);
pwmv2_calculate_select_in_offset(PWM, PWMV2_CALCULATE_INDEX(1), 31);
pwmv2_calculate_select_low_limit_offset(PWM, PWMV2_CALCULATE_INDEX(1), PWMV2_SHADOW_INDEX(1));
- 更新周期reload值
/* 修改计数器重载值,周期T */
pwmv2_set_shadow_val(PWM, PWMV2_SHADOW_INDEX(0), t_reload, 0, false);
软件实现
pwmv2也支持直接通过影子寄存器机制去同时修改reload值和compare值,需注意将更新时机选择为软件更新以保证更新的原子性。
- 硬件配置
pwmv2_shadow_register_unlock(PWM);
pwmv2_set_shadow_val(PWM, PWMV2_SHADOW_INDEX(0), 0, 0, false);
pwmv2_set_shadow_val(PWM, PWMV2_SHADOW_INDEX(1), 0, 0, false);
pwmv2_set_shadow_val(PWM, PWMV2_SHADOW_INDEX(2), 0, 0, false);
pwmv2_set_reload_update_time(PWM, pwm_counter_0, pwm_reload_update_on_shlk);
/* 配置reload值、compare0、compare1关联影子寄存器0、1、2 */
pwmv2_counter_select_data_offset_from_shadow_value(PWM, pwm_counter_0, PWMV2_SHADOW_INDEX(0));
pwmv2_select_cmp_source(PWM, PWMV2_CMP_INDEX(0), cmp_value_from_shadow_val, PWMV2_SHADOW_INDEX(1));
pwmv2_select_cmp_source(PWM, PWMV2_CMP_INDEX(1), cmp_value_from_shadow_val, PWMV2_SHADOW_INDEX(2));
pwmv2_cmp_update_trig_time(PWM, PWMV2_CMP_INDEX(0), pwm_shadow_register_update_on_shlk);
pwmv2_cmp_update_trig_time(PWM, PWMV2_CMP_INDEX(1), pwm_shadow_register_update_on_shlk);
pwmv2_shadow_register_lock(PWM);
- 更新周期reload值
pwmv2_shadow_register_unlock(PWM);
/* 修改影子寄存器0、1、2的值,在register_lock后生效 */
pwmv2_set_shadow_val(PWM, PWMV2_SHADOW_INDEX(0), reload, 0, false);
pwmv2_set_shadow_val(PWM, PWMV2_SHADOW_INDEX(1), PWM_CMP_VALUE0(reload), 0, false);
pwmv2_set_shadow_val(PWM, PWMV2_SHADOW_INDEX(2), PWM_CMP_VALUE1(reload), 0, false);
pwmv2_shadow_register_lock(PWM);
效果
图示波形,不断修改pwm波的频率,保持占空比不变。