| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- #include "board.h"
- #include "hpm_pwm_drv.h"
- // #include "hpm_trgm_drv.h"
- #include "bsp_V8M_YY_pwm.h"
- #include "hpm_gpio_drv.h"
- #include "hpm_gpiom_drv.h"
- #include "ver_config.h"
- #include "test.h"
- #include "main.h"
- // PB16 PWM0 PB17 PWM0 PB18 PWM1 PB19 PWM1
- // motor用的ahb时钟,还有其他外设也用的这个,不对其进行分频了 保留200M
- // 2.5ms * 200 000000 => period = 500 000 - 1
- // 不要对ahb时钟进行修改
- #define PWM_MOTOR1 HPM_PWM1
- #define PWM_MOTOR1_CLK_NAME
- #define PWM_MOTOR1_OUT 1
- #define PWM_MOTOR1_CMP 0
- #define PWM_MOTOR2 HPM_PWM1
- #define PWM_MOTOR2_CLK_NAME
- #define PWM_MOTOR2_OUT 0
- #define PWM_MOTOR2_CMP 1
- #define PWM_MOTOR3 HPM_PWM1
- #define PWM_MOTOR3_CLK_NAME
- #define PWM_MOTOR3_OUT 3
- #define PWM_MOTOR3_CMP 2
- #define PWM_MOTOR4 HPM_PWM3
- #define PWM_MOTOR4_CLK_NAME
- #define PWM_MOTOR4_OUT 2
- #define PWM_MOTOR4_CMP 3
- #define PWM_MOTOR5
- #define PWM_MOTOR5_CLK_NAME
- #define PWM_MOTOR5_OUT
- #define PWM_MOTOR5_CMP 4
- #define PWM_MOTOR6
- #define PWM_MOTOR6_CLK_NAME
- #define PWM_MOTOR6_OUT
- #define PWM_MOTOR6_CMP 5
- #define PWM_EN_GPIO_CTRL HPM_GPIO0
- #define PWM_EN_GPIO_INDEX GPIO_DI_GPIOB
- #define PWM_EN_GPIO_PIN 3
- #define GPIOM_BASE HPM_GPIOM
- #define GPIOM_PORT_ASSIGN GPIOM_ASSIGN_GPIOB
- /*------------------ Macros definitions --------------------------------------*/
- #define V8M_MOTOR_PERIOD (2500*PRESCALER_FACTOR) /* PWM输出的周期,单位 us */
- #define V8M_PWM_DEF_VALUE (1000*PRESCALER_FACTOR) /* 默认初始化的 PWM 占空比 */
- /**----------------- Variables definitions -----------------------------------*/
- /*------------------ Functions definitions -----------------------------------*/
- static void __motor_pwm_gpio_config(void);
- static void __motor_pwm_timer_config(void);
- static void gen_pwm_to_motor(PWM_Type *pwm_x, uint8_t pwm_out, uint8_t cmp_index, uint32_t reload, uint32_t set_cmp_value )
- {
-
- pwm_cmp_config_t cmp_config = {0};
- pwm_config_t pwm_config = {0};
- // 准备pwm_config
- pwm_get_default_pwm_config(pwm_x, &pwm_config); // 填充 pwm_config_t 默认值
- pwm_config.enable_output = true;
- pwm_config.dead_zone_in_half_cycle = 0;
- #ifdef WAVE_INV
- pwm_config.invert_output = true;
- #else
- pwm_config.invert_output = false;
- #endif
- // 准备cmp_config
- pwm_get_default_cmp_config(pwm_x, &cmp_config); // 填充 pwm_cmp_config_t 默认值
- cmp_config.mode = pwm_cmp_mode_output_compare; // 设置PWM工作模式为输出
- cmp_config.cmp = set_cmp_value; // 设置初始CMP值,这样直接设置为 1/2 则后续不需要更新即可生成 50% 占空比
- // cmp_config.cmp = pwm_reload + 1; // CMP > RLD, 由于计数器值 CNT 始终达不到 CMPx,比较器输出 OCx 会保持逻辑 0
- cmp_config.update_trigger = pwm_shadow_register_update_on_modify; // 设置CMP影子寄存器值生效时刻为 更新后的下一个周期
- // pwm_shadow_register_update_on_modify 这种方式下一个指令周期就会重装CMP,可能会导致PWM波形不完整,手册不推荐这种方式
- pwm_stop_counter(pwm_x); // 停止计数(没有也可以)
- pwm_set_reload(pwm_x, 0, reload); // 设置RLD寄存器
- pwm_set_start_count(pwm_x, 0, 0); // 设置STA寄存器
- // 使用给定参数对PWM通道进行设置
- if (status_success != pwm_setup_waveform(pwm_x, pwm_out, &pwm_config, cmp_index, &cmp_config, 1)) {
- printf("failed to setup waveform\\n");
- while(1);
- }
-
- pwm_start_counter(pwm_x); // 开始计数(PWM输出开始)
- pwm_issue_shadow_register_lock_event(pwm_x); // 锁定影子寄存器
- // 和 cmp = pwm_reload + 1 一起使用,也可以得到 50% 占空比的 PWM波形
- // 在这里更新CMP影子寄存器,下一个周期CMP寄存器会得到更新,这种方式便于动态更新PWM波形
- // pwm_update_raw_cmp_edge_aligned(pwm_x, cmp_index, pwm_reload / 2); // 50 % HIGH
- }
- /**
- * @brief pwm 初始化
- */
- void Bsp_V8M_YY_PwmInit(void)
- {
- __motor_pwm_gpio_config();
- __motor_pwm_timer_config();
- // 输出默认值
- for (uint8_t i = V8M_PWM_YY_CH1; i <= V8M_PWM_YY_CH4; ++i)
- Bsp_V8M_YY_PwmSetCHValue(i, V8M_PWM_DEF_VALUE);
- }
- /**
- * @brief 配置PWM GPIO引脚
- */
- static void __motor_pwm_gpio_config(void)
- {
-
- HPM_IOC->PAD[IOC_PAD_PB18].FUNC_CTL = IOC_PB18_FUNC_CTL_PWM1_P_1;
- HPM_IOC->PAD[IOC_PAD_PB19].FUNC_CTL = IOC_PB19_FUNC_CTL_PWM1_P_0;
- HPM_IOC->PAD[IOC_PAD_PB21].FUNC_CTL = IOC_PB21_FUNC_CTL_PWM1_P_3;
- HPM_IOC->PAD[IOC_PAD_PE06].FUNC_CTL = IOC_PE06_FUNC_CTL_PWM3_P_2;
-
- HPM_IOC->PAD[IOC_PAD_PB03].FUNC_CTL = IOC_PB03_FUNC_CTL_GPIO_B_03;
- // PWM 使能引脚 失能后pwm信号无效 修改引脚后这里要修改 https://tools.hpmicro.com/pinmux
- gpiom_set_pin_controller(GPIOM_BASE, GPIOM_PORT_ASSIGN, PWM_EN_GPIO_PIN, gpiom_soc_gpio0);
- gpio_set_pin_output(PWM_EN_GPIO_CTRL, PWM_EN_GPIO_INDEX, PWM_EN_GPIO_PIN);
- gpio_write_pin(PWM_EN_GPIO_CTRL, PWM_EN_GPIO_INDEX, PWM_EN_GPIO_PIN, 1);
-
- }
- /**
- * @brief pwm 定时器初始化
- *
- */
- static void __motor_pwm_timer_config(void)
- {
- uint32_t freq0, freq1, freq2, freq3;
- freq0 = clock_get_frequency(clock_mot0);
- freq1 = clock_get_frequency(clock_mot1);
- freq2 = clock_get_frequency(clock_mot2);
- freq3 = clock_get_frequency(clock_mot3);
- printf("PWM0,1,2,3时钟频率: %d %d %d %d Hz\n", freq0, freq1, freq2, freq3);
- gen_pwm_to_motor(PWM_MOTOR1, PWM_MOTOR1_OUT, PWM_MOTOR1_CMP, V8M_MOTOR_PERIOD, V8M_PWM_DEF_VALUE);
- gen_pwm_to_motor(PWM_MOTOR2, PWM_MOTOR2_OUT, PWM_MOTOR2_CMP, V8M_MOTOR_PERIOD, V8M_PWM_DEF_VALUE);
- gen_pwm_to_motor(PWM_MOTOR3, PWM_MOTOR3_OUT, PWM_MOTOR3_CMP, V8M_MOTOR_PERIOD, V8M_PWM_DEF_VALUE);
- gen_pwm_to_motor(PWM_MOTOR4, PWM_MOTOR4_OUT, PWM_MOTOR4_CMP, V8M_MOTOR_PERIOD, V8M_PWM_DEF_VALUE);
- }
- /**
- * @brief 改变 pwm 通道值
- */
- void Bsp_V8M_YY_PwmSetCHValue(uint8_t m_ch, uint32_t m_value)
- {
- if (m_value > V8M_MOTOR_PERIOD) {
- m_value = V8M_MOTOR_PERIOD;
- }
- switch (m_ch)
- {
- case 1:
-
- pwm_cmp_update_cmp_value(PWM_MOTOR1, PWM_MOTOR1_CMP, m_value, 0);
- break;
- case 2:
- pwm_cmp_update_cmp_value(PWM_MOTOR2, PWM_MOTOR2_CMP, m_value, 0);
- break;
- case 3:
- pwm_cmp_update_cmp_value(PWM_MOTOR3, PWM_MOTOR3_CMP, m_value, 0);
- break;
- case 4:
- pwm_cmp_update_cmp_value(PWM_MOTOR4, PWM_MOTOR4_CMP, m_value, 0);
- break;
- //case 5:
- // pwm_cmp_update_cmp_value(PWM_MOTOR5, PWM_MOTOR5_CMP, m_value, 0);
- // break;
- //case 6:
- // pwm_cmp_update_cmp_value(PWM_MOTOR6, PWM_MOTOR6_CMP, m_value, 0);
- // break;
- default:
- break;
- }
- }
- /**
- * @brief 获取对应通道比较值
- */
- uint32_t Bsp_V8M_YY_PwmGetCHValue(uint8_t m_ch)
- {
- uint16_t m_value = 0;
- switch (m_ch)
- {
- case 1:
- m_value = PWM_CMP_CMP_GET(PWM_MOTOR1->CMP[PWM_MOTOR1_CMP]);
- break;
- case 2:
- m_value = PWM_CMP_CMP_GET(PWM_MOTOR2->CMP[PWM_MOTOR2_CMP]);
- break;
- case 3:
- m_value = PWM_CMP_CMP_GET(PWM_MOTOR3->CMP[PWM_MOTOR3_CMP]);
- break;
- case 4:
- m_value = PWM_CMP_CMP_GET(PWM_MOTOR4->CMP[PWM_MOTOR4_CMP]);
- break;
- //case 5:
- // m_value = PWM_CMP_CMP_GET(PWM_MOTOR5->CMP[PWM_MOTOR5_CMP]);
- // break;
- //case 6:
- // m_value = PWM_CMP_CMP_GET(PWM_MOTOR6->CMP[PWM_MOTOR6_CMP]);
- // break;
- default:
- break;
- }
- return m_value;
- }
- static void print_pwm_cmp_values_direct(void)
- {
- printf("=== PWM 通道比较值 ===\n");
-
- // 通道1
- uint32_t cmp1 = PWM_CMP_CMP_GET(PWM_MOTOR1->CMP[PWM_MOTOR1_CMP]);
- printf("通道1 比较值: 0x%06lX (%lu)\n", cmp1, cmp1);
-
- // 通道2
- uint32_t cmp2 = PWM_CMP_CMP_GET(PWM_MOTOR2->CMP[PWM_MOTOR2_CMP]);
- printf("通道2 比较值: 0x%06lX (%lu)\n", cmp2, cmp2);
-
- // 通道3
- uint32_t cmp3 = PWM_CMP_CMP_GET(PWM_MOTOR3->CMP[PWM_MOTOR3_CMP]);
- printf("通道3 比较值: 0x%06lX (%lu)\n", cmp3, cmp3);
-
- // 通道4
- uint32_t cmp4 = PWM_CMP_CMP_GET(PWM_MOTOR4->CMP[PWM_MOTOR4_CMP]);
- printf("通道4 比较值: 0x%06lX (%lu)\n", cmp4, cmp4);
-
- printf("====================\n");
- }
- void PWM_IS_ENABLE(void)
- {
- gpio_write_pin(PWM_EN_GPIO_CTRL, PWM_EN_GPIO_INDEX, PWM_EN_GPIO_PIN, 1);
- }
- void PWM_IS_DISABLE(void)
- {
- gpio_write_pin(PWM_EN_GPIO_CTRL, PWM_EN_GPIO_INDEX, PWM_EN_GPIO_PIN, 0);
- }
- /* motor_pwm_test 经过测试 2026/03/13 */
- #ifdef PWM_TEST
- void v8m_yy_motor_pwm_test(void)
- {
- Bsp_V8M_YY_PwmInit();
-
- while(1)
- {
- board_delay_ms(500);
- print_pwm_cmp_values_direct();
-
- }
- }
- #endif
|