|
|
|
@@ -1,5 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "main.h"
|
|
|
|
|
#include "app.h"
|
|
|
|
|
#include "init.h"
|
|
|
|
@@ -10,7 +9,7 @@
|
|
|
|
|
#define DATA_LOG 0
|
|
|
|
|
#define DATA_MONITOR 0
|
|
|
|
|
#define DEBOUNCE_TIME 20
|
|
|
|
|
#define BUF_SIZE 100 // > 300 記憶體不夠用(4組) > 700 記憶體不夠用(2組)
|
|
|
|
|
#define BUF_SIZE 300 // > 300 記憶體不夠用(4組) > 700 記憶體不夠用(2組)
|
|
|
|
|
|
|
|
|
|
#define CR_1P1Z_B0_Q14 6313
|
|
|
|
|
#define CR_1P1Z_B1_Q14 -5113
|
|
|
|
@@ -67,9 +66,10 @@ uint8_t llc_running = 0;
|
|
|
|
|
uint8_t pfc_running = 0;
|
|
|
|
|
static uint8_t last_is_zero_crossing = 0;
|
|
|
|
|
uint8_t is_brown_in = 0; // 0: 關機/保護中, 1: 正常工作
|
|
|
|
|
static uint8_t cur_loop_fun_en = 0;
|
|
|
|
|
|
|
|
|
|
static volatile int32_t print1, print2;
|
|
|
|
|
static volatile int64_t print3;
|
|
|
|
|
// static volatile int32_t print1, print2;
|
|
|
|
|
// static volatile int64_t print3;
|
|
|
|
|
|
|
|
|
|
static uint16_t iac = 0;
|
|
|
|
|
static uint16_t vac = 0;
|
|
|
|
@@ -111,18 +111,18 @@ uint8_t keyInput;
|
|
|
|
|
//-----------------------------------------------
|
|
|
|
|
uint8_t power_on_cmd = 0;
|
|
|
|
|
uint8_t temp_off = 0;
|
|
|
|
|
uint32_t msg_timer;
|
|
|
|
|
uint16_t vbus_volt, vac_volt;
|
|
|
|
|
int32_t tx_buf1[BUF_SIZE];
|
|
|
|
|
int64_t tx_buf2[BUF_SIZE];
|
|
|
|
|
int32_t tx_buf2[BUF_SIZE];
|
|
|
|
|
// uint16_t tx_buf3[BUF_SIZE];
|
|
|
|
|
// uint16_t tx_buf4[BUF_SIZE];
|
|
|
|
|
uint16_t buf_idx = 0;
|
|
|
|
|
uint8_t is_full = 0;
|
|
|
|
|
uint16_t count_down = 60000; // for data log
|
|
|
|
|
uint16_t count_down = 2000; // for data log
|
|
|
|
|
uint16_t i_ff;
|
|
|
|
|
uint32_t vac_avg1, vac_avg2, vac_avg3;
|
|
|
|
|
uint32_t vbus_avg = 0;
|
|
|
|
|
uint32_t vcr_avg;
|
|
|
|
|
static volatile uint16_t vac_pk1, vac_pk2;
|
|
|
|
|
uint8_t hi_line = 0; // 0=110V, 1=220V
|
|
|
|
|
uint8_t vbus_ready = 0;
|
|
|
|
@@ -133,6 +133,7 @@ uint16_t llc_period_ss = LLC_SS_MIN;
|
|
|
|
|
uint16_t llc_run_arr = LLC_PERIOD_MIN;
|
|
|
|
|
uint16_t llc_arr_cmp = 0;
|
|
|
|
|
uint8_t v_loop_cnt = 0;
|
|
|
|
|
uint8_t v_loop_cnt2 = 0;
|
|
|
|
|
uint16_t brownout_cnt = 0;
|
|
|
|
|
|
|
|
|
|
uint8_t volatile tim0_trigger = 0;
|
|
|
|
@@ -324,19 +325,22 @@ void Vol_Loop_PFC_1P1Z(void) // TEST OK
|
|
|
|
|
int32_t vbus_err_n = (int32_t)vbus_set - (int32_t)vbus_avg;
|
|
|
|
|
|
|
|
|
|
// --- 策略 A:動態增益調整 ---
|
|
|
|
|
int32_t b0 = 135;
|
|
|
|
|
int32_t b1 = -134;
|
|
|
|
|
// int32_t b0 = 135;
|
|
|
|
|
// int32_t b1 = -134;
|
|
|
|
|
int32_t b0 = 180;
|
|
|
|
|
int32_t b1 = -175;
|
|
|
|
|
|
|
|
|
|
if (vbus_err_n > 30 || vbus_err_n < -30)
|
|
|
|
|
// if (vbus_err_n > 30 || vbus_err_n < -30)
|
|
|
|
|
if (vbus_err_n > 80 || vbus_err_n < -80) // ~ 20V
|
|
|
|
|
{
|
|
|
|
|
// 大誤差時(通常是剛啟動或大跳載),強化參數加快反應
|
|
|
|
|
// b0 = 250;
|
|
|
|
|
// b1 = -240;
|
|
|
|
|
b0 = 180; // 稍微調降強增益的力道
|
|
|
|
|
b1 = -175;
|
|
|
|
|
b0 = 250;
|
|
|
|
|
b1 = -240;
|
|
|
|
|
// b0 = 180; // 稍微調降強增益的力道
|
|
|
|
|
// b1 = -175;
|
|
|
|
|
}
|
|
|
|
|
// --- 策略 B:接近目標時微調零點 (抗過衝) ---
|
|
|
|
|
else if (vbus_err_n < 20 && vbus_err_n > -20)
|
|
|
|
|
else if (vbus_err_n < 20 && vbus_err_n > -20) // ~ 5V
|
|
|
|
|
{
|
|
|
|
|
// 當誤差縮小時,稍微減小 b0 與 b1 的差值,降低積分衝力
|
|
|
|
|
b0 = 120;
|
|
|
|
@@ -350,27 +354,6 @@ void Vol_Loop_PFC_1P1Z(void) // TEST OK
|
|
|
|
|
|
|
|
|
|
int32_t y_n = (int32_t)acc;
|
|
|
|
|
|
|
|
|
|
#if 0 // 有問題
|
|
|
|
|
// --- 策略 C:軟限制抗過衝 (Soft Clamping) ---
|
|
|
|
|
// 預設最大限制 (Duty 300 << 14)
|
|
|
|
|
int32_t current_max_limit = 4915200; // duty 300
|
|
|
|
|
|
|
|
|
|
// 如果電壓誤差已經很小(例如剩 15V 就到達),甚至已經發生過衝 (err < 0)
|
|
|
|
|
// 我們強制壓低 Duty 的允許上限,防止積分器帶著大 Duty 衝過頭
|
|
|
|
|
if (vbus_err_n < 15)
|
|
|
|
|
{
|
|
|
|
|
// 這裡的 3276800 對應 Duty 200,您可以根據 800W 穩態時的 Duty 大約位置來設定
|
|
|
|
|
// 核心目標是:不讓 Duty 在接近目標時還維持在 300 這麼高
|
|
|
|
|
current_max_limit = 3276800; // duty 200
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果發生明顯過衝 (電壓高於目標 5V 以上)
|
|
|
|
|
if (vbus_err_n < -5)
|
|
|
|
|
{
|
|
|
|
|
current_max_limit = 1638400; // 強制壓低到 Duty 100 快速拉回
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// 3. 輸出限幅執行
|
|
|
|
|
if (y_n > YN_MAX)
|
|
|
|
|
y_n = YN_MAX;
|
|
|
|
@@ -382,43 +365,49 @@ void Vol_Loop_PFC_1P1Z(void) // TEST OK
|
|
|
|
|
vbus_comp_1 = y_n;
|
|
|
|
|
|
|
|
|
|
// 5. 輸出 Duty >> 14
|
|
|
|
|
if (sys_state == STATE_PFC_SOFT_START) // 緩啟動期間直接控制 DUTY
|
|
|
|
|
TIM2->CCR1 = (vbus_comp_1 >> 14); // 0~540
|
|
|
|
|
// if (sys_state == STATE_PFC_SOFT_START || sys_state == STATE_RUN_SKIP) // 緩啟動期間直接控制 DUTY
|
|
|
|
|
TIM2->CCR1 = (vbus_comp_1 >> 14); // 0 ~ 540
|
|
|
|
|
|
|
|
|
|
// 6. 輸出 comp >> 9 (變大 32 倍) (MAX ~ 18000) (540*32=17280)差不多,>> 9 應該是對的
|
|
|
|
|
if (sys_state == STATE_RUN_NORMAL) // 正常工作時間輸出 COMP 值
|
|
|
|
|
vbus_comp2 = (vbus_comp_1 >> 9);
|
|
|
|
|
// if (sys_state == STATE_RUN_NORMAL) // 正常工作時間輸出 COMP 值
|
|
|
|
|
vbus_comp2 = (vbus_comp_1 >> 9);
|
|
|
|
|
}
|
|
|
|
|
//==========================================================================
|
|
|
|
|
// Cr 1P1Z 回授,做負載驟變補償,執行頻率 10KHZ
|
|
|
|
|
// 抓取 vcr 的動態變化趨勢,並在穩態時回歸平靜
|
|
|
|
|
void Load_Loop_1P1Z(void)
|
|
|
|
|
//=============================================================
|
|
|
|
|
static void Vol_Loop_PFC_1P1Z_UI(void) // ZERO: 120HZ, POLE:0.1HZ, G:10
|
|
|
|
|
{
|
|
|
|
|
int32_t x0;
|
|
|
|
|
int64_t temp_y0; // 使用 64 位元暫存,完全避免 32 位元相乘時溢位
|
|
|
|
|
int32_t y0;
|
|
|
|
|
// 1. 計算誤差
|
|
|
|
|
int32_t vbus_err_0 = (int32_t)vbus_set - (int32_t)vbus_avg;
|
|
|
|
|
|
|
|
|
|
// 1. 讀取當前 vcr
|
|
|
|
|
x0 = vcr;
|
|
|
|
|
// 2. 2P2Z 運算 (Fixed-point Q14)
|
|
|
|
|
struct bode_plot_param_t *vloop_p = &pfc_vloop_bode_plot_param;
|
|
|
|
|
int64_t acc1 = (int64_t)vloop_p->b0 * vbus_err_0 + (int64_t)vloop_p->b1 * vbus_err_1;
|
|
|
|
|
|
|
|
|
|
// 2. 執行 1P1Z 差分方程計算:
|
|
|
|
|
temp_y0 = ((int64_t)CR_1P1Z_B0_Q14 * x0) + ((int64_t)CR_1P1Z_B1_Q14 * vcr_x1_q14) - ((int64_t)CR_1P1Z_A1_Q14 * vcr_y1_q14);
|
|
|
|
|
int64_t acc2 = (-((int64_t)vloop_p->a1 * vbus_comp_1)) >> 14;
|
|
|
|
|
|
|
|
|
|
// 將 Q28 格式還原回 Q14 格式(右移 14 位元
|
|
|
|
|
y0 = (int32_t)(temp_y0 >> 14);
|
|
|
|
|
acc1 += acc2;
|
|
|
|
|
int32_t y_n = acc1;
|
|
|
|
|
|
|
|
|
|
// 更新歷史狀態變數 (Q14 格式)
|
|
|
|
|
vcr_x1_q14 = x0;
|
|
|
|
|
vcr_y1_q14 = y0;
|
|
|
|
|
// 限制極限值
|
|
|
|
|
if (y_n > YN_MAX)
|
|
|
|
|
y_n = YN_MAX; // 540 << 14
|
|
|
|
|
else if (y_n < YN_MIN)
|
|
|
|
|
y_n = YN_MIN; // 12 << 14
|
|
|
|
|
|
|
|
|
|
// 定點數安全限幅 (Saturation)
|
|
|
|
|
if (y0 > CR_FF_MAX_Q14)
|
|
|
|
|
y0 = CR_FF_MAX_Q14; // 868352 = 53 duty
|
|
|
|
|
else if (y0 > -CR_FF_MIN_Q14)
|
|
|
|
|
y0 = -CR_FF_MIN_Q14;
|
|
|
|
|
// 更新狀態變數 (儲存原始計算值以保留積分能量)
|
|
|
|
|
vbus_err_1 = vbus_err_0;
|
|
|
|
|
|
|
|
|
|
cr_feed_forward_output_q14 = y0;
|
|
|
|
|
// 重要:vbus_comp_1 儲存 local_temp,確保下一個週期的 a1, a2 運算正確
|
|
|
|
|
vbus_comp_1 = y_n;
|
|
|
|
|
|
|
|
|
|
// 5. 輸出 Duty >> 14
|
|
|
|
|
// if (sys_state == STATE_PFC_SOFT_START || sys_state == STATE_RUN_SKIP) // 緩啟動期間直接控制 DUTY
|
|
|
|
|
TIM2->CCR1 = (vbus_comp_1 >> 14); // 0 ~ 540
|
|
|
|
|
|
|
|
|
|
// 6. 輸出 comp >> 9 (變大 32 倍) (MAX ~ 18000) (540*32=17280)差不多,>> 9 應該是對的
|
|
|
|
|
// if (sys_state == STATE_RUN_NORMAL) // 正常工作時間輸出 COMP 值
|
|
|
|
|
vbus_comp2 = (vbus_comp_1 >> 9);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
__attribute__((always_inline)) static inline void Cur_Loop_PFC_2P2Z(void) // 優化後 3.65us
|
|
|
|
|
{
|
|
|
|
@@ -588,9 +577,9 @@ __INTERRUPT void isr_adc_handle(void)
|
|
|
|
|
iac = ADC0->DAT9_b.DATA; // PA7, AIN9
|
|
|
|
|
vac = ADC0->DAT7_b.DATA; // PA13, AIN7
|
|
|
|
|
vbus = ADC0->DAT4_b.DATA; // PA10, AIN4
|
|
|
|
|
vcr = ADC0->DAT5_b.DATA; // PA11, AIN5
|
|
|
|
|
// vcr = ADC0->DAT5_b.DATA; // PA11, AIN5
|
|
|
|
|
|
|
|
|
|
Cur_Loop_PFC_2P2Z(); // current loop
|
|
|
|
|
if (cur_loop_fun_en) Cur_Loop_PFC_2P2Z(); // current loop
|
|
|
|
|
|
|
|
|
|
// GPIO_ResetBits(GPIOA, GPIO_Pin_06);
|
|
|
|
|
|
|
|
|
@@ -615,11 +604,12 @@ void reset_pid_parameters(void)
|
|
|
|
|
//==============================================================================
|
|
|
|
|
void Handle_UART_Monitor(void)
|
|
|
|
|
{
|
|
|
|
|
static uint32_t msg_timer = 0;
|
|
|
|
|
if (sys_get_tick() - msg_timer >= 1000) // msg_out = 1, print
|
|
|
|
|
{
|
|
|
|
|
// printf("%d %d %d\r\n", vac_pk1, vac_pk2, is_brown_in);
|
|
|
|
|
// printf("%d %d %d %d %d %d", power_on_cmd, sys_state, vbus_comp2, print1, print2, print3);
|
|
|
|
|
printf("%d %d %d", power_on_cmd, sys_state, vbus_comp2);
|
|
|
|
|
msg("%d %d %d %d\r\n", power_on_cmd, sys_state, vbus_comp2, vbus_avg);
|
|
|
|
|
// 電壓環輸出最大 COMP,但是電流環輸出最小 DUTY
|
|
|
|
|
msg_timer = sys_get_tick();
|
|
|
|
|
}
|
|
|
|
@@ -704,18 +694,201 @@ static void uart_rx_task(void)
|
|
|
|
|
int main(void)
|
|
|
|
|
{
|
|
|
|
|
struct bode_plot_param_t *bplot_p = &bode_plot_param;
|
|
|
|
|
struct bode_plot_param_t *vloop_p = &pfc_vloop_bode_plot_param;
|
|
|
|
|
|
|
|
|
|
// 基礎硬體底層設定 (HIRC 60MHz, GPIO, ADC 採樣率 1Msps) [cite: 55, 127, 184]
|
|
|
|
|
SYS_Config();
|
|
|
|
|
|
|
|
|
|
// PFC 電流環參數
|
|
|
|
|
bode_plot_param_read_from_flash(bplot_p, FLASH_PROG_ADDR_USER_CALI);
|
|
|
|
|
|
|
|
|
|
vbus_comp2 = 3000;
|
|
|
|
|
sys_state = STATE_RUN_NORMAL;
|
|
|
|
|
pfc_pwm_enable();
|
|
|
|
|
pfc_running = 1;
|
|
|
|
|
/*********************************************************************/
|
|
|
|
|
/* PFC 電壓環參數*/
|
|
|
|
|
vloop_p->a2 = 0;
|
|
|
|
|
vloop_p->b2 = 0;
|
|
|
|
|
|
|
|
|
|
// 120HZ, 0.1Hz, 100G
|
|
|
|
|
vloop_p->b0 = 139;
|
|
|
|
|
vloop_p->b1 = -129;
|
|
|
|
|
vloop_p->a1 = -16383;
|
|
|
|
|
/*********************************************************************/
|
|
|
|
|
/* PFC 電流環參數*/
|
|
|
|
|
// bplot_p->b0 = 12368803;
|
|
|
|
|
// bplot_p->b1 = -19162610;
|
|
|
|
|
// bplot_p->b2 = 7037429;
|
|
|
|
|
// bplot_p->a1 = -20921;
|
|
|
|
|
// bplot_p->a2 = 4545;
|
|
|
|
|
/*********************************************************************/
|
|
|
|
|
|
|
|
|
|
#if 1 // 單測 PFC 電壓環 (OK)
|
|
|
|
|
|
|
|
|
|
cur_loop_fun_en = 0; // 關閉電流環,專測電壓環
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
uart_rx_task();
|
|
|
|
|
|
|
|
|
|
if (tim0_trigger == 1) // 100KHZ
|
|
|
|
|
{
|
|
|
|
|
tim0_trigger = 0;
|
|
|
|
|
// --- 1. 高速信號濾波 (簡易位移算法減少算力消耗) ---
|
|
|
|
|
vac_avg1 = (vac_avg1 - (vac_avg1 >> 3)) + (vac >> 3); // for current loop
|
|
|
|
|
vbus_avg = (vbus_avg - (vbus_avg >> 4)) + (vbus >> 4); // for voltage loop
|
|
|
|
|
vcr_avg = (vcr_avg - (vcr_avg >> 3)) + (vcr >> 3);
|
|
|
|
|
if (vbus > vbus_ovp) Power_Off(); // ovp
|
|
|
|
|
|
|
|
|
|
Vac_Peak_Detector();
|
|
|
|
|
|
|
|
|
|
if (power_on_cmd == 1)
|
|
|
|
|
{
|
|
|
|
|
if (pfc_running == 0)
|
|
|
|
|
{
|
|
|
|
|
pfc_pwm_enable();
|
|
|
|
|
pfc_running = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (++v_loop_cnt >= 10) // 10KHZ
|
|
|
|
|
{
|
|
|
|
|
Vol_Loop_PFC_1P1Z_UI();
|
|
|
|
|
// Vol_Loop_PFC_1P1Z();
|
|
|
|
|
v_loop_cnt = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Key1_Scan();
|
|
|
|
|
|
|
|
|
|
// Handle_UART_Monitor();
|
|
|
|
|
|
|
|
|
|
if (is_full == 1)
|
|
|
|
|
{
|
|
|
|
|
sys_delay(10);
|
|
|
|
|
Handle_UART_Log();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if 0 // 單測 PFC 電流環 (OK)
|
|
|
|
|
cur_loop_fun_en = 1; // 開啟電流環,專測電流環
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
uart_rx_task();
|
|
|
|
|
if (tim0_trigger == 1) // 100KHZ
|
|
|
|
|
{
|
|
|
|
|
tim0_trigger = 0;
|
|
|
|
|
// --- 1. 高速信號濾波 (簡易位移算法減少算力消耗) ---
|
|
|
|
|
vac_avg1 = (vac_avg1 - (vac_avg1 >> 3)) + (vac >> 3); // for current loop
|
|
|
|
|
vbus_avg = (vbus_avg - (vbus_avg >> 4)) + (vbus >> 4); // for voltage loop
|
|
|
|
|
// vcr_avg = (vcr_avg - (vcr_avg >> 3)) + (vcr >> 3);
|
|
|
|
|
if (vbus > vbus_ovp) Power_Off(); // ovp
|
|
|
|
|
|
|
|
|
|
Vac_Peak_Detector();
|
|
|
|
|
|
|
|
|
|
if (power_on_cmd == 1)
|
|
|
|
|
{
|
|
|
|
|
if (is_zero_crossing == 1)
|
|
|
|
|
{
|
|
|
|
|
sys_state = STATE_RUN_NORMAL;
|
|
|
|
|
// --- 關鍵修正:重新初始化電壓環內部狀態 ---
|
|
|
|
|
// 給予一個極小的初始 COMP 值,讓它從輕載慢慢往上爬
|
|
|
|
|
// vbus_comp_1 = (10 << 14); // 假設從一個極小的係數開始
|
|
|
|
|
vbus_err_1 = 0; // 清除誤差歷史
|
|
|
|
|
// vbus_comp2 = (vbus_comp_1 >> 9); // 讓電流環拿到的初始值是 10
|
|
|
|
|
vbus_comp2 = 3000;
|
|
|
|
|
// vset / 5700
|
|
|
|
|
// vbus_comp2: 3000, 275V / 0.25A = 68W
|
|
|
|
|
// vbus_comp2: 4000, 314V / 0.25A = 78W
|
|
|
|
|
// vbus_comp2: 5000, 360V / 0.25A = 90W
|
|
|
|
|
// vset >> 13 ( / 8192)
|
|
|
|
|
// vbus_comp2: 3000, 256V / 0.25A = 64W
|
|
|
|
|
// vbus_comp2: 4000, 267V / 0.25A = 66W
|
|
|
|
|
// vbus_comp2: 5000, 293V / 0.25A = 73W
|
|
|
|
|
|
|
|
|
|
// vbus_comp2: 2000, 298V / 0.25A = 75W ?? 波形不對
|
|
|
|
|
// vbus_comp2: 1000, 398V / 0.25A = 75W ??
|
|
|
|
|
}
|
|
|
|
|
else if (sys_state == STATE_RUN_NORMAL)
|
|
|
|
|
{
|
|
|
|
|
if (pfc_running == 0)
|
|
|
|
|
{
|
|
|
|
|
pfc_pwm_enable();
|
|
|
|
|
pfc_running = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Key1_Scan();
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if 0 // 測試 PFC 電壓環 + 電流環 (OK)
|
|
|
|
|
TIM2->CCR1 = 12; // min duty
|
|
|
|
|
sys_state = STATE_PFC_SOFT_START;
|
|
|
|
|
|
|
|
|
|
Vac_Peak_Detector();
|
|
|
|
|
pfc_running = 0;
|
|
|
|
|
|
|
|
|
|
cur_loop_fun_en = 1; // 開啟電流環,專測電流環
|
|
|
|
|
|
|
|
|
|
while(1)
|
|
|
|
|
{
|
|
|
|
|
if (tim0_trigger == 1) // 100KHZ
|
|
|
|
|
{
|
|
|
|
|
tim0_trigger = 0;
|
|
|
|
|
// --- 1. 高速信號濾波 (簡易位移算法減少算力消耗) ---
|
|
|
|
|
vac_avg1 = (vac_avg1 - (vac_avg1 >> 3)) + (vac >> 3); // for current loop
|
|
|
|
|
vbus_avg = (vbus_avg - (vbus_avg >> 4)) + (vbus >> 4); // for voltage loop
|
|
|
|
|
if (vbus > vbus_ovp) Power_Off(); // ovp
|
|
|
|
|
|
|
|
|
|
Vac_Peak_Detector();
|
|
|
|
|
|
|
|
|
|
if (power_on_cmd == 1)
|
|
|
|
|
{
|
|
|
|
|
if (sys_state == STATE_PFC_SOFT_START)
|
|
|
|
|
{
|
|
|
|
|
if (pfc_running == 0) {
|
|
|
|
|
pfc_pwm_enable();
|
|
|
|
|
pfc_running = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (++v_loop_cnt >= 10) // 10KHZ
|
|
|
|
|
{
|
|
|
|
|
Vol_Loop_PFC_1P1Z_UI();
|
|
|
|
|
v_loop_cnt = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (vbus_avg > vbus_set_l && is_zero_crossing == 1)
|
|
|
|
|
{
|
|
|
|
|
sys_state = STATE_RUN_NORMAL;
|
|
|
|
|
// --- 關鍵修正:重新初始化電壓環內部狀態 ---
|
|
|
|
|
// 給予一個極小的初始 COMP 值,讓它從輕載慢慢往上爬
|
|
|
|
|
vbus_comp_1 = (10 << 14); // 假設從一個極小的係數開始
|
|
|
|
|
vbus_err_1 = 0; // 清除誤差歷史
|
|
|
|
|
vbus_comp2 = (vbus_comp_1 >> 9); // 讓電流環拿到的初始值是 10
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if (sys_state == STATE_RUN_NORMAL)
|
|
|
|
|
{
|
|
|
|
|
if (pfc_running == 0) {
|
|
|
|
|
pfc_pwm_enable();
|
|
|
|
|
pfc_running = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (++v_loop_cnt >= 10) // 10KHZ
|
|
|
|
|
{
|
|
|
|
|
Vol_Loop_PFC_1P1Z_UI();
|
|
|
|
|
v_loop_cnt = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Key1_Scan();
|
|
|
|
|
//Handle_UART_Monitor();
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// main loop
|
|
|
|
|
cur_loop_fun_en = 1; // 開啟電流環,專測電流環
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
uart_rx_task();
|
|
|
|
@@ -754,36 +927,36 @@ int main(void)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
// --- 2. 核心狀態機邏輯 -----------------------------------------------------------------------
|
|
|
|
|
switch (sys_state)
|
|
|
|
|
{
|
|
|
|
|
case STATE_INIT: // 0
|
|
|
|
|
// 等待約 100ms,並按下按鍵
|
|
|
|
|
// --- 2. 核心狀態機邏輯 -----------------------------------------------------------------------
|
|
|
|
|
switch (sys_state)
|
|
|
|
|
{
|
|
|
|
|
case STATE_INIT: // 0
|
|
|
|
|
// 等待約 100ms,並按下按鍵
|
|
|
|
|
if (sys_get_tick() > 100 && power_on_cmd == 1) {
|
|
|
|
|
sys_state = STATE_STANDBY;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
sys_state = STATE_STANDBY;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case STATE_STANDBY: // 1
|
|
|
|
|
// Brown-in 判斷
|
|
|
|
|
case STATE_STANDBY: // 1
|
|
|
|
|
// Brown-in 判斷
|
|
|
|
|
if (is_brown_in == 1) {
|
|
|
|
|
sys_state = STATE_PFC_SOFT_START; // 先進 PFC SS
|
|
|
|
|
TIM2->CCR1 = PFC_DUTY_MIN;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
sys_state = STATE_PFC_SOFT_START; // 先進 PFC SS
|
|
|
|
|
TIM2->CCR1 = PFC_DUTY_MIN;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case STATE_PFC_SOFT_START: // 2
|
|
|
|
|
case STATE_PFC_SOFT_START: // 2
|
|
|
|
|
// 若 vbus < 320 做 pre-charge
|
|
|
|
|
if (vbus_avg < vbus_set_l)
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
if (pfc_running == 0) {
|
|
|
|
|
pfc_pwm_enable();
|
|
|
|
|
pfc_running = 1;
|
|
|
|
|
}
|
|
|
|
|
pfc_pwm_enable();
|
|
|
|
|
pfc_running = 1;
|
|
|
|
|
}
|
|
|
|
|
if (++v_loop_cnt >= 10) {
|
|
|
|
|
Vol_Loop_PFC_1P1Z();
|
|
|
|
|
v_loop_cnt = 0;
|
|
|
|
|
}
|
|
|
|
|
v_loop_cnt = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@@ -798,74 +971,74 @@ int main(void)
|
|
|
|
|
// 重要動作
|
|
|
|
|
vbus_comp_1 = (10 << 14); // 假設從一個極小的係數開始
|
|
|
|
|
vbus_err_1 = 0; // 清除誤差歷史
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case STATE_RUN_NORMAL: // 4
|
|
|
|
|
case STATE_RUN_NORMAL: // 4
|
|
|
|
|
//if (pfc_running == 0) {
|
|
|
|
|
// pfc_pwm_enable();
|
|
|
|
|
// pfc_running = 1;
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
if (++v_loop_cnt >= 10) {
|
|
|
|
|
// 先算前饋,再算主環,最後疊加
|
|
|
|
|
// 先算前饋,再算主環,最後疊加
|
|
|
|
|
//Load_Loop_1P1Z(); // Cr 前饋
|
|
|
|
|
Vol_Loop_PFC_1P1Z(); // PFC 電壓環
|
|
|
|
|
//Vol_Loop_PFC();
|
|
|
|
|
//Vol_Loop_LLC(); // LLC 電壓環
|
|
|
|
|
v_loop_cnt = 0;
|
|
|
|
|
}
|
|
|
|
|
v_loop_cnt = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case STATE_RUN_SKIP: // 5
|
|
|
|
|
case STATE_RUN_SKIP: // 5
|
|
|
|
|
// 電壓外環計算 (10kHz)
|
|
|
|
|
if (++v_loop_cnt >= 10) {
|
|
|
|
|
//Vol_Loop_PFC(); // KP / KI 要快
|
|
|
|
|
//Vol_Loop_LLC();
|
|
|
|
|
v_loop_cnt = 0;
|
|
|
|
|
}
|
|
|
|
|
/* 有問題
|
|
|
|
|
// Brown-out 判斷
|
|
|
|
|
if (vac_pk2 < VAC_BROWN_OUT) {
|
|
|
|
|
brownout_cnt++;
|
|
|
|
|
if (brownout_cnt > BROWNOUT_DELAY) {
|
|
|
|
|
Power_Off();
|
|
|
|
|
sys_state = STATE_STANDBY;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
brownout_cnt = 0;
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
/* 先不做
|
|
|
|
|
// --- BURST / SKIP 邏輯 (帶滯後區間) ---
|
|
|
|
|
// 只在過零點判斷
|
|
|
|
|
if (is_zero_crossing == 1) {
|
|
|
|
|
if (vbus_avg > vbus_set_h) { // 上限觸發停機
|
|
|
|
|
pfc_pwm_disable();
|
|
|
|
|
burst_mode_active = 1;
|
|
|
|
|
}
|
|
|
|
|
else if (vbus_avg < vbus_set_l && burst_mode_active == 1) { // 下限觸發回復
|
|
|
|
|
reset_pid_parameters();
|
|
|
|
|
pfc_pwm_enable();
|
|
|
|
|
burst_mode_active = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
break;
|
|
|
|
|
v_loop_cnt = 0;
|
|
|
|
|
}
|
|
|
|
|
/* 有問題
|
|
|
|
|
// Brown-out 判斷
|
|
|
|
|
if (vac_pk2 < VAC_BROWN_OUT) {
|
|
|
|
|
brownout_cnt++;
|
|
|
|
|
if (brownout_cnt > BROWNOUT_DELAY) {
|
|
|
|
|
Power_Off();
|
|
|
|
|
sys_state = STATE_STANDBY;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
brownout_cnt = 0;
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
/* 先不做
|
|
|
|
|
// --- BURST / SKIP 邏輯 (帶滯後區間) ---
|
|
|
|
|
// 只在過零點判斷
|
|
|
|
|
if (is_zero_crossing == 1) {
|
|
|
|
|
if (vbus_avg > vbus_set_h) { // 上限觸發停機
|
|
|
|
|
pfc_pwm_disable();
|
|
|
|
|
burst_mode_active = 1;
|
|
|
|
|
}
|
|
|
|
|
else if (vbus_avg < vbus_set_l && burst_mode_active == 1) { // 下限觸發回復
|
|
|
|
|
reset_pid_parameters();
|
|
|
|
|
pfc_pwm_enable();
|
|
|
|
|
burst_mode_active = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case STATE_FAULT: // 5
|
|
|
|
|
// 立即封鎖所有輸出
|
|
|
|
|
pfc_pwm_disable();
|
|
|
|
|
llc_pwm_disable();
|
|
|
|
|
// 記錄故障代碼,等待手動重置
|
|
|
|
|
break;
|
|
|
|
|
// 立即封鎖所有輸出
|
|
|
|
|
pfc_pwm_disable();
|
|
|
|
|
llc_pwm_disable();
|
|
|
|
|
// 記錄故障代碼,等待手動重置
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case STATE_PAUSE: // 6
|
|
|
|
|
break;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
} // switch case
|
|
|
|
|
} // switch case
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
} // if tim0_trigger
|
|
|
|
|