HPM6E00:PWM V2使用指南

先楫推出的HPM6E00系列芯片,PWM功能升级到了V2版本。和V1版本不同的是,V2版本的每组PWM模块包含4个独立的PWM生成模块,每个PWM生成模块包含一个counter和4个比较器,可以生成4组频率不同的PWM波。每个PWM生成模块,对应两个PWM输出通道,可以生成两路PWM波。不同于PWM V1将多个比较器分配到一个PWM输出通道的方式。PWM V2的一个PWM生成模块,通过4个比较器来控制2个PWM通道的波形,可以单独控制,也可以成对控制。

PWM V2同样支持故障保护功能,通过输入IO来停止PWM的发波。最多支持16个IO,直接作为故障信号的触发源,这个mux在PWM内部。

下面通过PWM V2的例程,讲解PWM V2控制单通道PWM的原理。

以生成PWM 通道1为例:通过影子寄存器0来设置PWM周期,比较器0和比较器1控制PWM channel 0,比较器2和比较器3控制PWM channel 1。比较器2的值来自影子寄存器3,比较器3的值来自影子寄存器4。当PWM开始计数时,计数值达到比较器2和比较器3的值的时候,进行电平翻转。达到counter的值时重新进行计数,不会进行电平翻转。例程中,比较器3的值固定为reload,通过改变比较器2的值来改变占空比。

void generate_edge_aligned_waveform(void)
{
    uint32_t duty, duty_step;
    bool increase_duty_cycle = true;

    pwmv2_disable_counter(PWM, pwm_counter_0);
    pwmv2_reset_counter(PWM, pwm_counter_0);
    pwmv2_shadow_register_unlock(PWM);

    pwmv2_set_shadow_val(PWM, PWMV2_SHADOW_INDEX(0), reload, 0, false);
    pwmv2_set_shadow_val(PWM, PWMV2_SHADOW_INDEX(1), reload + 1, 0, false);
    pwmv2_set_shadow_val(PWM, PWMV2_SHADOW_INDEX(2), reload, 0, false);
    pwmv2_set_shadow_val(PWM, PWMV2_SHADOW_INDEX(3), reload >> 1, 0, false);
    pwmv2_set_shadow_val(PWM, PWMV2_SHADOW_INDEX(4), reload, 0, false);

    pwmv2_counter_select_data_offset_from_shadow_value(PWM, pwm_counter_0, PWMV2_SHADOW_INDEX(0));
    pwmv2_counter_burst_disable(PWM, pwm_counter_0);
    pwmv2_set_reload_update_time(PWM, pwm_counter_0, pwm_reload_update_on_reload);

    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_select_cmp_source(PWM, PWMV2_CMP_INDEX(2), cmp_value_from_shadow_val, PWMV2_SHADOW_INDEX(3));
    pwmv2_select_cmp_source(PWM, PWMV2_CMP_INDEX(3), cmp_value_from_shadow_val, PWMV2_SHADOW_INDEX(4));

    pwmv2_shadow_register_lock(PWM);
    //pwmv2_disable_four_cmp(PWM, BOARD_APP_PWM_OUT1);
    pwmv2_disable_four_cmp(PWM, BOARD_APP_PWM_OUT2);
    //pwmv2_channel_enable_output(PWM, BOARD_APP_PWM_OUT1);
    pwmv2_channel_enable_output(PWM, BOARD_APP_PWM_OUT2);
    pwmv2_enable_counter(PWM, pwm_counter_0);
    pwmv2_start_pwm_output(PWM, pwm_counter_0);

    //pwmv2_shadow_register_unlock(PWM);
    //pwmv2_set_shadow_val(PWM, PWMV2_SHADOW_INDEX(1), 0, 0, false);
    //pwmv2_shadow_register_lock(PWM);

    //pwmv2_shadow_register_unlock(PWM);
    //pwmv2_set_shadow_val(PWM, PWMV2_SHADOW_INDEX(4), 0, 0, false);
    //pwmv2_shadow_register_lock(PWM);

    //board_delay_ms(1000);

    // 占空比100%,PWM默认低电平,CMP2先翻转
    pwmv2_shadow_register_unlock(PWM);
    pwmv2_set_shadow_val(PWM, PWMV2_SHADOW_INDEX(3), 2, 0, false);
    pwmv2_shadow_register_lock(PWM);
    board_delay_ms(1000);

    // 占空比50%
    pwmv2_shadow_register_unlock(PWM);
    pwmv2_set_shadow_val(PWM, PWMV2_SHADOW_INDEX(3), reload/2, 0, false);
    pwmv2_shadow_register_lock(PWM);
    board_delay_ms(1000);

    // 占空比75%
    pwmv2_shadow_register_unlock(PWM);
    pwmv2_set_shadow_val(PWM, PWMV2_SHADOW_INDEX(3), reload/4, 0, false);
    pwmv2_shadow_register_lock(PWM);
    board_delay_ms(1000);

    pwmv2_disable_counter(PWM, pwm_counter_0);
    pwmv2_reset_counter(PWM, pwm_counter_0);
    pwmv2_shadow_register_unlock(PWM);


}

PWM故障保护:

void pwm_fault_async(void)
{
    pwmv2_async_fault_source_config_t fault_cfg;

    fault_cfg.async_signal_from_pad_index = BOARD_APP_PWM_FAULT_PIN;
    fault_cfg.fault_async_pad_level = pad_fault_active_high;
    pwmv2_config_async_fault_source(PWM, BOARD_APP_PWM_OUT1, &fault_cfg);
    pwmv2_config_async_fault_source(PWM, BOARD_APP_PWM_OUT2, &fault_cfg);
    pwmv2_set_fault_mode(PWM, BOARD_APP_PWM_OUT1, pwm_fault_output_0);
    pwmv2_set_fault_mode(PWM, BOARD_APP_PWM_OUT2, pwm_fault_output_0);
    pwmv2_enable_fault_from_pad(PWM, BOARD_APP_PWM_OUT1);
    pwmv2_enable_fault_from_pad(PWM, BOARD_APP_PWM_OUT2);
}
int main(void)
{
    uint32_t freq;
    board_init();
    init_pwm_pins(PWM);
    init_pwm_fault_pins();
    printf("pwm example\n");

    freq = clock_get_frequency(PWM_CLOCK_NAME);
    reload = freq / 10000 * PWM_PERIOD_IN_MS - 1;

    pwm_fault_async();
    printf("\n\n>> Test force PWM output on P%d and P%d\n", PWM_OUTPUT_PIN1, PWM_OUTPUT_PIN2);
    pwm_force_output();
    printf("\n\n>> Generate edge aligned waveform\n");
    printf("Two waveforms will be generated, PWM P%d is the target waveform\n", PWM_OUTPUT_PIN1);
    printf("whose duty cycle will be updated from 0 - 100 and back to 0; PWM P%d is a reference\n", PWM_OUTPUT_PIN2);
    generate_edge_aligned_waveform();

    printf("test done\n");
    while (1) {
        ;
    }
    return 0;
}

 程序测试结果:测试占空比

 

故障保护功能:给故障管脚输入高电平,PWM发波立即停止。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AllenSun-1990

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值