主要记录一下调试时候的注意点:

1、PWMv2模块包含28个32位的影子寄存器,可以随意使用

2、PWMv2 支持4个PWM生成子模块,每个子模块包含一个32位计数器,计数器构成了输出信号的时间基 准。所以每一个子模块都应该配置自己的时间基准,我以为同一个PWM外设用同一个基准,所以踩坑半天!

3、看下图,每个子模块都有对应的比较值,不要乱分配 P0就是1、2;P1就是2、3。

4、PWM生成的规则:靠两个比较值(也可以靠4个需要配置)控制一个PWM端口的输出,注意这两个值的大小有讲究,可以控制PWM在周期内的任意位置和大小,挺厉害。

5、配置流程:

        1)、初始化引脚、设置影子寄存器(因为后面设置都是直接操作影子寄存器,不要直接操作比较值的寄存器),相当于给时间基准和比较值寄存器找了个替身。

        2)、将时钟源绑定到影子寄存器、将比较器绑定到影子寄存器,不同的比较器可以使用同一个影子寄存器。

        3)、其他的就是一些配置,关闭输出固定个数的PWM功能,设置每个PWM用两个寄存器配置....

void Pin_Init(void)
{

    HPM_IOC->PAD[IOC_PAD_PD00].FUNC_CTL = IOC_PD00_FUNC_CTL_PWM0_P_0;
    HPM_IOC->PAD[IOC_PAD_PD02].FUNC_CTL = IOC_PD02_FUNC_CTL_PWM0_P_2;
    HPM_IOC->PAD[IOC_PAD_PD04].FUNC_CTL = IOC_PD04_FUNC_CTL_PWM0_P_4;

    Pwm_Init();
}


#define FAN_PWM_PERIOD_IN_MS    10

#define FAN_PWM0_CH0    0
#define FAN_PWM0_CH2    2
#define FAN_PWM0_CH4    4

void Pwm_Init(void)
{
    uint32_t freq,duty,reload = 0;
    freq = clock_get_frequency(clock_pwm0);
    reload = freq / 1000 * FAN_PWM_PERIOD_IN_MS - 1;
    duty = reload / 100;

    pwmv2_deinit(HPM_PWM0);
    pwmv2_shadow_register_unlock(HPM_PWM0);

    pwmv2_set_shadow_val(HPM_PWM0, PWMV2_SHADOW_INDEX(0), reload, 0, false);

    pwmv2_set_shadow_val(HPM_PWM0, PWMV2_SHADOW_INDEX(1),  0,             0, false);    // P0 
    pwmv2_set_shadow_val(HPM_PWM0, PWMV2_SHADOW_INDEX(2),  reload >> 2,   0, false);
    pwmv2_set_shadow_val(HPM_PWM0, PWMV2_SHADOW_INDEX(3),  0,             0, false);    // P2
    pwmv2_set_shadow_val(HPM_PWM0, PWMV2_SHADOW_INDEX(4),  reload >> 2,   0, false);
    pwmv2_set_shadow_val(HPM_PWM0, PWMV2_SHADOW_INDEX(5),  0,             0, false);    // P4 
    pwmv2_set_shadow_val(HPM_PWM0, PWMV2_SHADOW_INDEX(6), reload >> 2,   0, false);


    pwmv2_counter_select_data_offset_from_shadow_value(HPM_PWM0, pwm_counter_0, PWMV2_SHADOW_INDEX(0));
    pwmv2_counter_select_data_offset_from_shadow_value(HPM_PWM0, pwm_counter_1, PWMV2_SHADOW_INDEX(0));
    pwmv2_counter_select_data_offset_from_shadow_value(HPM_PWM0, pwm_counter_2, PWMV2_SHADOW_INDEX(0));
    pwmv2_counter_burst_disable(HPM_PWM0, pwm_counter_0);    // P0 P1
    pwmv2_counter_burst_disable(HPM_PWM0, pwm_counter_1);    // P2 P3
    pwmv2_counter_burst_disable(HPM_PWM0, pwm_counter_2);    // P4 P5
    pwmv2_set_reload_update_time(HPM_PWM0, pwm_counter_0, pwm_reload_update_on_reload);
    pwmv2_set_reload_update_time(HPM_PWM0, pwm_counter_1, pwm_reload_update_on_reload);
    pwmv2_set_reload_update_time(HPM_PWM0, pwm_counter_2, pwm_reload_update_on_reload);

    pwmv2_select_cmp_source(HPM_PWM0, PWMV2_CMP_INDEX(0), cmp_value_from_shadow_val, PWMV2_SHADOW_INDEX(1));    // P0 
    pwmv2_select_cmp_source(HPM_PWM0, PWMV2_CMP_INDEX(1), cmp_value_from_shadow_val, PWMV2_SHADOW_INDEX(2));
    pwmv2_select_cmp_source(HPM_PWM0, PWMV2_CMP_INDEX(4), cmp_value_from_shadow_val, PWMV2_SHADOW_INDEX(3));    // P2 
    pwmv2_select_cmp_source(HPM_PWM0, PWMV2_CMP_INDEX(5), cmp_value_from_shadow_val, PWMV2_SHADOW_INDEX(4));
    pwmv2_select_cmp_source(HPM_PWM0, PWMV2_CMP_INDEX(8), cmp_value_from_shadow_val, PWMV2_SHADOW_INDEX(5));    // P4 
    pwmv2_select_cmp_source(HPM_PWM0, PWMV2_CMP_INDEX(9), cmp_value_from_shadow_val, PWMV2_SHADOW_INDEX(6));

    pwmv2_shadow_register_lock(HPM_PWM0);
    // 选择两个比较点
    pwmv2_disable_four_cmp(HPM_PWM0, FAN_PWM0_CH0);
    pwmv2_channel_enable_output(HPM_PWM0, FAN_PWM0_CH0);
    pwmv2_disable_four_cmp(HPM_PWM0, FAN_PWM0_CH2);
    pwmv2_channel_enable_output(HPM_PWM0, FAN_PWM0_CH2);
    pwmv2_disable_four_cmp(HPM_PWM0, FAN_PWM0_CH4);
    pwmv2_channel_enable_output(HPM_PWM0, FAN_PWM0_CH4);

    pwmv2_enable_counter(HPM_PWM0, pwm_counter_0);
    pwmv2_enable_counter(HPM_PWM0, pwm_counter_1);
    pwmv2_enable_counter(HPM_PWM0, pwm_counter_2);
    pwmv2_start_pwm_output(HPM_PWM0, pwm_counter_0);
    pwmv2_start_pwm_output(HPM_PWM0, pwm_counter_1);
    pwmv2_start_pwm_output(HPM_PWM0, pwm_counter_2);

    // 初始化输出占空比
    pwmv2_shadow_register_unlock(HPM_PWM0);
    pwmv2_set_shadow_val(HPM_PWM0, PWMV2_SHADOW_INDEX(2), duty * 38 , 0, false);
    pwmv2_set_shadow_val(HPM_PWM0, PWMV2_SHADOW_INDEX(4), duty * 28 , 0, false);
    pwmv2_set_shadow_val(HPM_PWM0, PWMV2_SHADOW_INDEX(6), duty * 15 , 0, false);
    pwmv2_shadow_register_lock(HPM_PWM0);
}

最后补充一句:还是要回去看数据手册比较准,不要靠猜测写代码。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐