From 09b993ba0d23ffb689732dc730ba240059e2f4b9 Mon Sep 17 00:00:00 2001 From: Aiden Date: Wed, 1 Jul 2026 14:52:14 +0800 Subject: [PATCH] feat: adjust LLC period parameters and enhance control logic for stability --- .../Examples/template/LLC_48V/inc/main.h | 6 +- .../Examples/template/LLC_48V/src/main.c | 111 +++++------------- 2 files changed, 35 insertions(+), 82 deletions(-) diff --git a/pec930_sdk-v1.0.1/Examples/template/LLC_48V/inc/main.h b/pec930_sdk-v1.0.1/Examples/template/LLC_48V/inc/main.h index 4978a43..a9d3791 100644 --- a/pec930_sdk-v1.0.1/Examples/template/LLC_48V/inc/main.h +++ b/pec930_sdk-v1.0.1/Examples/template/LLC_48V/inc/main.h @@ -53,12 +53,12 @@ extern "C" // 武士 12V 變壓器 + 47nF 諧振頻率 ~ 75KHZ // 實測值 106uH + 47nF = 73KHZ --> PERIOD = 820 ~ 830 // 高正 40uH + 68nF ~ 95KHZ -#define LLC_PERIOD_SS 300 // 300 = 200khz (EPWM initial use) +#define LLC_PERIOD_SS 200 // 300 = 200khz (EPWM initial use) #define DEAD_TIME 500 // ns #define DEAD_TIME_VALUE (DEAD_TIME * 0.06) // double // LLC free run, 改控 vbus_set -#define LLC_PERIOD_MIN 300 // MIN, 300 = 200KHZ (>760不會振) -#define LLC_PERIOD_MAX 600 // MAX, 600 = 100KHZ // 可調範圍太大會共振 +#define LLC_PERIOD_MIN 200 // MIN, 300 = 200KHZ (>760不會振) +#define LLC_PERIOD_MAX 400 // MAX, 600 = 100KHZ // 可調範圍太大會共振 #define LLC_COMP_GAIN_BIT 10 // 要慢才不會振 #define LLC_COMP_MAX ((LLC_PERIOD_MAX - LLC_PERIOD_MIN) << LLC_COMP_GAIN_BIT) // LLC Soft Start 掃頻 2倍 ~ 1倍 = 150KHZ ~ 73KHZ diff --git a/pec930_sdk-v1.0.1/Examples/template/LLC_48V/src/main.c b/pec930_sdk-v1.0.1/Examples/template/LLC_48V/src/main.c index 1163ff5..1a75c2c 100644 --- a/pec930_sdk-v1.0.1/Examples/template/LLC_48V/src/main.c +++ b/pec930_sdk-v1.0.1/Examples/template/LLC_48V/src/main.c @@ -81,8 +81,11 @@ uint16_t llc_ss_cnt = 0; uint8_t power_on_cmd = 0; uint32_t vac_avg1; -uint32_t vbus_avg = 0; +uint32_t vbus_avg; uint32_t vcomp_avg; +uint32_t ipcs_avg; + +uint8_t power_on = 0; uint32_t static digital_vcomp = (LLC_PERIOD_MAX - LLC_PERIOD_MIN) << LLC_COMP_GAIN_BIT; uint16_t llc_period_ss = LLC_SS_MIN; @@ -198,7 +201,10 @@ static void Capture_Dump_IfReady(void) //------------------------------------------------------------------------- void llc_set_period(uint16_t val) { - if (val > LLC_PERIOD_MAX) val = LLC_PERIOD_MAX; // 可以小,不能過大 + if (val > LLC_PERIOD_MAX) + val = LLC_PERIOD_MAX; + else if (val < LLC_PERIOD_MIN) + val = LLC_PERIOD_MIN; EPWM->ARR = val; EPWM->CCR1 = val >> 1; } @@ -206,11 +212,13 @@ void llc_set_period(uint16_t val) void llc_pwm_enable() { REG_SET_BITS(EPWM->CCER, TIM_CCER_CC1E_Msk | TIM_CCER_CC1NE_Msk); + power_on = 1; } //=================================================================================== void llc_pwm_disable() { REG_CLR_BITS(EPWM->CCER, TIM_CCER_CC1E_Msk | TIM_CCER_CC1NE_Msk); + power_on = 0; } //=================================================================================== // Cr 1P1Z 回授,做負載驟變補償,執行頻率 10KHZ @@ -433,61 +441,14 @@ __attribute__((always_inline)) static inline void Cur_Loop_PFC_2P2Z(void) // 優 } //============================================================================ -void Vol_Loop_LLC(void) // 測試可工作 +void Vol_Loop_LLC(void) // 調整 period 控制 vcomp 穩定 { - static uint8_t last_gpio = 0; - static uint16_t toggle_cnt = 0; - static uint16_t stable_timer = 0; + uint32_t new_arr = EPWM->ARR; - // 1. 讀取 GPIO 回授 - uint8_t gpio = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_12); - - // 2. 判斷是否發生翻轉 (判斷是否在平衡點附近跳動) - if (gpio != last_gpio) - { - toggle_cnt++; - last_gpio = gpio; - stable_timer = 0; // 只要有翻轉,就重置穩定計時器 - } - else - { - // 如果 GPIO 長時間沒翻轉,說明離目標還很遠 - if (stable_timer < 1000) stable_timer++; - } - - // 3. 根據翻轉頻率決定步長 - uint16_t current_step; - if (toggle_cnt > STABLE_THRES) - { - // 頻繁翻轉:進入「死區」或「極小步長」模式 - current_step = 0; // 設為 0 表示進入死區,完全停止震盪 - - // 為了防止永久卡死,當連續相同狀態一段時間後再恢復調整 - if (stable_timer > 50) toggle_cnt = 0; - } - else - { - // 距離目標尚遠:根據 stable_timer 決定快慢 - current_step = (stable_timer > 100) ? STEP_FAST : STEP_SLOW; - } - - // 4. 執行調整 - if (current_step > 0) - { - if (gpio == 1) - { - if (digital_vcomp + current_step <= digi_vcomp_max) - digital_vcomp += current_step; - } - else - { - if (digital_vcomp > (1000 + current_step)) - digital_vcomp -= current_step; - } - } - - // 5. 計算並更新 ARR (原本的邏輯) - uint32_t new_arr = LLC_PERIOD_MIN + (digital_vcomp >> LLC_COMP_GAIN_BIT); + if (vcomp_avg > 2000) + new_arr++; // vcomp 上升, arr ++ + else if (vcomp_avg < 1950) + new_arr--; // vcomp 下降, arr -- if (new_arr > LLC_PERIOD_MAX) new_arr = LLC_PERIOD_MAX; if (new_arr < LLC_PERIOD_MIN) new_arr = LLC_PERIOD_MIN; @@ -508,9 +469,9 @@ __INTERRUPT void isr_adc_handle(void) adc_trigger = 1; // get ADC value - vbus = ADC0->DAT4_b.DATA; // PA10, AIN4 - ipcs = ADC0->DAT9_b.DATA; // PA7, AIN9 - vcomp = ADC0->DAT7_b.DATA; // PA13, AIN7 + vbus = ADC0->DAT2_b.DATA; // PA8 AIN2 + ipcs = ADC0->DAT3_b.DATA; // PA9 AIN3 + vcomp = ADC0->DAT4_b.DATA; // PA10 AIN4 // if (cur_loop_fun_en) Cur_Loop_PFC_2P2Z(); // current loop /* @@ -584,8 +545,8 @@ void Handle_UART_Monitor(void) static uint32_t msg_timer2 = 0; if (sys_get_tick() - msg_timer2 >= 1000) { - printf("%d %d %d\n", power_on_cmd, sys_state, vbus_comp2); - // msg_timer2 = sys_get_tick(); + printf("%d %d %d\r\n", vbus, ipcs, vcomp); + msg_timer2 = sys_get_tick(); } } //============================================================================= @@ -629,8 +590,9 @@ int main(void) // 高速信號濾波 (簡易位移算法減少算力消耗) --- vbus_avg = (vbus_avg - (vbus_avg >> 3)) + (vbus >> 3); + ipcs_avg = (ipcs_avg - (ipcs_avg >> 3)) + (ipcs >> 3); vcomp_avg = (vcomp_avg - (vcomp_avg >> 3)) + (vcomp >> 3); - +#if 0 // vbus ovp, uvp, 超出工作電壓範圍就不工作 if (vbus_avg > vbus_ovp || vbus_avg < vbus_uvp) { @@ -640,6 +602,12 @@ int main(void) { if (sys_state == STATE_STOP) sys_state = STATE_SS; } +#endif + + if (power_on == 0) + sys_state = STATE_STOP; // power_on 控制回授工作或停止 + else + sys_state = STATE_RUN; #if 1 // --- 2. 核心狀態機邏輯 ----------------------------------------------------------------------- @@ -665,32 +633,17 @@ int main(void) if (llc_ss_cnt >= LLC_SS_COUNT) { sys_state = STATE_RUN; - // sys_state = STATE_PAUSE; // 測試用 - // 重要動作 ===================================== - // vbus_comp_1 = YN_MIN; // 假設從一個極小的係數開始 - // vbus_comp2 = (vbus_comp_1 >> 9); - // vbus_err_1 = 0; // 清除誤差歷史 - // iac_err_2 = 0; - // iac_err_1 = 0; - // iac_comp_2 = YN_MIN; - // iac_comp_1 = YN_MIN; - // msg("%d %d %d %d \r\n", power_on_cmd, sys_state, vbus_comp_1, vbus_comp2); - // 1 4 196608, = 12 << 14 - // E LOAD 抽太慢,導致 OVP ?? (是的) } break; case STATE_RUN: // 2 // 根據電壓環、電流環調整頻率 - /* + if (++v_loop_cnt >= 10) // 10KHZ { - Vol_Loop_PFC_1P1Z(); - // Vol_Loop_PFC_1P1Z(); + Vol_Loop_LLC(); v_loop_cnt = 0; } - */ - break; } // switch case #endif @@ -698,7 +651,7 @@ int main(void) } // if tim0_trigger // --- 3. 非即時任務 (UI、通訊、Data Log) --- - // Handle_UART_Monitor(); + Handle_UART_Monitor(); // Capture_Dump_IfReady(); // capture_continuous_task();