#include "pdctrl.h" #include "main.h" #include "entity.h" #include "leds.h" #include "board.h" pdctrl_t pdctrl_data; pdctrl_t pdctrl_data_out; __IO static pdctrl_mode_e out_mode = PDCTRL_DAC; __IO static BOOL pdctrl_run_flag = FALSE; static void dac_dinit(void) { DAC_STOP(DAC, PDCTRL_DAC_CHINNEL); // DAC通道禁用 GPIO_SET_ANALOG(PDCTRL_DAC_GPIO_Port, PDCTRL_DAC_Pin); } static void dac_init(void) { pdctrl_data.last_out = 0xffff; GPIO_SET_ANALOG(PDCTRL_DAC_GPIO_Port, PDCTRL_DAC_Pin); DAC_START(DAC, PDCTRL_DAC_CHINNEL); // DAC通道使能 } static void pwm_dinit(void) { PWM_STOP(PDCTRL_PWM_TIM, PDCTRL_PWM_CHINNEL); // PWM通道禁用 GPIO_SET_ANALOG(PDCTRL_PWM_GPIO_Port, PDCTRL_PWM_Pin); } static void pwm_init(void) { pdctrl_data.last_out = 0xffff; GPIO_SET_ALTERNATE(PDCTRL_PWM_GPIO_Port, PDCTRL_PWM_Pin); if (pdctrl_data.pwm_arr_default == 0) { pdctrl_data.pwm_arr_default = LL_TIM_GetAutoReload(PDCTRL_PWM_TIM); } PWM_START(PDCTRL_PWM_TIM, PDCTRL_PWM_CHINNEL); // PWM通道使能 } static void pwmp_dinit(void) { PWM_STOP(PDCTRL_PWMP_TIM, PDCTRL_PWMP_CHINNEL); // PWM通道禁用 GPIO_SET_ANALOG(PDCTRL_PWMP_GPIO_Port, PDCTRL_PWMP_Pin); } static void pwmp_init(void) { pdctrl_data.last_out = 0xffff; GPIO_SET_ALTERNATE(PDCTRL_PWM_GPIO_Port, PDCTRL_PWM_Pin); ENABLE_TIM_ARR_RELOAD(PDCTRL_PWMP_TIM); PWM_START(PDCTRL_PWMP_TIM, PDCTRL_PWMP_CHINNEL); // PWM通道使能 } /** * @brief 控制初始化 * @param {pdctrl_mode_e} mode * @param {uint8_t} pwm_frequency * @return {*} * @note */ void pdctrl_init(pdctrl_mode_e mode) { out_mode = mode; pdctrl_data.pwm_wid = PWM_WID; osel_memset((uint8_t *)&pdctrl_data, 0, sizeof(pdctrl_t)); dac_dinit(); pwm_dinit(); pwmp_dinit(); if (out_mode == PDCTRL_DAC) { dac_init(); } else if (out_mode == PDCTRL_PWM) { pwm_init(); } else if (out_mode == PDCTRL_PWMP) { pwmp_init(); } else { return; } } /** * @brief 控制停止 * @return {*} * @note */ void pdctrl_stop(void) { pdctrl_run_flag = FALSE; if (out_mode == PDCTRL_DAC) { dac_dinit(); } else if (out_mode == PDCTRL_PWM) { pwm_dinit(); } else if (out_mode == PDCTRL_PWMP) { pwmp_dinit(); } else { return; } } /** * @brief 控制运行 * @return {*} * @note */ void pdctrl_run(void) { pdctrl_run_flag = TRUE; if (out_mode == PDCTRL_DAC) { dac_init(); } else if (out_mode == PDCTRL_PWM) { pwm_init(); } else if (out_mode == PDCTRL_PWMP) { pwmp_init(); } else { return; } } /** * @brief 获取控制器 * @return {*} * @note */ pdctrl_t *pdctrl_get(void) { return &pdctrl_data; } /** * @brief 占空比转换为CCR值 * @param {float32} out * @return {*} * @note */ uint16_t pdctrl_pwm_duty_convert_ccr(float32 pwm_duty) { return (pwm_duty * pdctrl_data.pwm_arr_default) / 100; } // 计算频率 static void calculate_pwm_freq(uint32_t arr) { pdctrl_data.sysclk = SystemCoreClock / 1000; pdctrl_data.psc = LL_TIM_GetPrescaler(PDCTRL_PWM_TIM); pdctrl_data.freq = (float32)pdctrl_data.sysclk / (float32)(pdctrl_data.psc + 1) / (float32)arr; } /** * @brief 变频计算占空比 * @param {uint32_t} arr 自动加载值 * @return {*} * @note */ uint16_t calculate_pwm_duty(uint32_t arr) { float32 wid = pdctrl_data.pwm_wid; calculate_pwm_freq(arr); if (arr < pdctrl_data.pwm_arr_default) { wid = (pdctrl_data.pwm_arr_default - arr) * 10 / pdctrl_data.pwm_arr_default + wid; } pdctrl_data.arr_us = 1000.0f / pdctrl_data.freq; pdctrl_data.duty_percent = ((float32)wid * 100.0f) / pdctrl_data.arr_us; pdctrl_data.duty = arr * pdctrl_data.duty_percent / 100; return pdctrl_data.duty; } /** * @brief 设置PWM频率 * @param {uint32_t} freq * @return {*} * @note */ void pdctrl_set_pwm_wid(uint16_t wid) { pdctrl_data.pwm_wid = wid; } /** * @brief 动态修改频率 * @param {uint32_t} arr 自动加载值 * @return {*} * @note */ void pdctrl_pwm_set_arr(uint32_t arr) { uint16_t pwm_arr = LL_TIM_GetAutoReload(PDCTRL_PWM_TIM); if (pwm_arr == arr) { return; } if (arr == 0) { arr = pdctrl_data.pwm_arr_default; } LL_TIM_SetAutoReload(PDCTRL_PWM_TIM, arr); uint16_t duty = calculate_pwm_duty(arr); #if PDCTRL_PWM_CHINNEL == LL_TIM_CHANNEL_CH4 PWM_SET_DUTY(PDCTRL_PWM_TIM, 4, duty); #else #error "PDCTRL_PWM_CHINNEL undefined" #endif } /** * @brief 获取占空比 * @param {uint32_t} arr 自动加载值 * @return {*} * @note */ float32 pdctrl_pwm_get_duty_percent(uint32_t arr) { calculate_pwm_duty(arr); return pdctrl_data.duty_percent; } /** * @brief 控制输出 * @param {uint16_t} out * @return {*} * @note */ void pdctrl_out(uint16_t out) { if (pdctrl_run_flag == FALSE) { return; } if (pdctrl_data.last_out == out && (pdctrl_data.sysclk != (SystemCoreClock / 1000))) { return; } pdctrl_data.last_out = out; rt_data.ip_output = out; if (out_mode == PDCTRL_DAC) { DAC_OUT(DAC, PDCTRL_DAC_CHINNEL, out); } else if (out_mode == PDCTRL_PWM) { pdctrl_pwm_set_arr(out); } else if (out_mode == PDCTRL_PWMP) { #if PDCTRL_PWMP_CHINNEL == LL_TIM_CHANNEL_CH4 PWM_SET_DUTY(PDCTRL_PWMP_TIM, 4, out); #else #error "PDCTRL_PWMP_CHINNEL undefined" #endif } else { return; } } /** * @brief 获取控制模式 * @return {*} * @note */ uint8_t get_pdctrl_mode(void) { return out_mode; } /** * @brief 获取PWM默认频率 * @return {*} * @note */ uint16_t get_pwm_arr_default(void) { return pdctrl_data.pwm_arr_default; }