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发波立即停止。

### 关于 HPM6e80 和 Eclipse 插件兼容性或使用的分析 针对 HPM6e80 的开发环境设置,尤其是与 Eclipse 集成的相关技术资料和解决方案,可以从以下几个方面展开讨论: #### 1. **HPM SDK 支持** HPM6e80 是基于 HPM 系列的一款高性能微控制器。在其官方提供的开发资源包 `hpm_sdk-1.6` 中包含了适用于该系列芯片的各种驱动程序、库文件以及示例代码[^1]。这些资源对于配置 Eclipse IDE 至关重要。 通常情况下,SDK 提供了一个名为 `project_generator` 的工具,用于生成适合不同集成开发环境 (IDE) 的项目模板,其中包括对 Eclipse 的支持。开发者可以通过运行此工具并选择目标硬件平台(即 HPM6e80),自动生成适配的工程结构。 #### 2. **Eclipse Plugin 安装与配置** 为了使 Eclipse 能够高效地管理嵌入式项目的编译流程,建议安装 GNU ARM Embedded Toolchain 及其对应的插件 CDT (C/C++ Development Tools)。具体操作如下: - 下载并解压最新版本的 GNU 工具链至本地目录。 - 打开 Eclipse Marketplace 或者手动导入 p2 update site 地址以获取必要的组件更新站点链接。 - 设置交叉编译器路径到刚刚下载好的工具链位置下。 完成上述步骤之后,在新建 C Project 向导界面里应该能够看到由 project generator 创建出来的选项卡;按照提示填写好相关参数即可顺利建立初始框架。 #### 3. **PWM 故障保护机制简介** 值得一提的是,虽然当前查询主要围绕着HPE6e80及其配套软件生态展开探讨,但从另一份文档得知关于同家族产品——HPM6E00 上实现了一种新颖而强大的 PWM 控制方案[PWM V2][^2] 。它允许利用多达十六路独立可编程输入端口充当紧急制动开关角色,一旦检测到来自信号线路上异常状态变化便会立即中断脉宽调制输出动作序列执行过程。尽管两者型号有所区别,但考虑到它们可能共享相似架构设计思路,因此这一特性或许也能间接启发我们如何更好地规划涉及实时控制应用场景下的软硬协同策略制定工作。 ```bash # Example command to generate an Eclipse-compatible project using the provided tool. ./project_generator --board=HPM6e80-EVB --ide=eclipse-cdt --output_dir=./generated_projects ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

AllenSun-1990

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

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

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

打赏作者

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

抵扣说明:

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

余额充值