Implemented Constant Current mode
This commit is contained in:
parent
3ef6872e03
commit
97db9c24db
144
src/main.c
144
src/main.c
|
@ -21,6 +21,7 @@
|
||||||
enum OperState {
|
enum OperState {
|
||||||
Bootstrap,
|
Bootstrap,
|
||||||
ConvConstVoltage,
|
ConvConstVoltage,
|
||||||
|
ConvConstCurrent,
|
||||||
Idle,
|
Idle,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -203,21 +204,32 @@ int main(void)
|
||||||
char number[FXP_STR_MAXLEN];
|
char number[FXP_STR_MAXLEN];
|
||||||
uint8_t sentSomething = 0;
|
uint8_t sentSomething = 0;
|
||||||
|
|
||||||
|
int32_t pwm;
|
||||||
|
|
||||||
enum OperState operState = Bootstrap;
|
enum OperState operState = Bootstrap;
|
||||||
|
enum OperState nextState = ConvConstVoltage;
|
||||||
enum OperState lastState = operState;
|
enum OperState lastState = operState;
|
||||||
|
|
||||||
fxp_t vin, vout, current;
|
fxp_t vin, vout, current;
|
||||||
|
fxp_t vin_avg = 0, vout_avg = 0, current_avg = 0;
|
||||||
|
|
||||||
fxp_t pErr, iErr = 0;
|
fxp_t pErr, iErr = 0;
|
||||||
fxp_t controlAction;
|
fxp_t controlAction;
|
||||||
|
|
||||||
fxp_t PGAIN = fxp_from_float( 20.000f);
|
fxp_t PGAIN_CV = fxp_from_float( 50.000f);
|
||||||
fxp_t IGAIN = fxp_from_float( 1.000f);
|
fxp_t IGAIN_CV = fxp_from_float( 0.300f);
|
||||||
fxp_t IERR_LIMIT = fxp_from_int(10000);
|
fxp_t IERR_LIMIT = fxp_from_int(4000);
|
||||||
|
|
||||||
|
fxp_t PGAIN_CC = fxp_from_float( 50.000f);
|
||||||
|
fxp_t IGAIN_CC = fxp_from_float( 0.300f);
|
||||||
|
|
||||||
fxp_t CURRENT_THRESHOLD = fxp_from_float(0.05f);
|
fxp_t CURRENT_THRESHOLD = fxp_from_float(0.05f);
|
||||||
|
|
||||||
fxp_t maxVoltage = fxp_from_float(11.000f);
|
fxp_t AVG_FACT = fxp_from_float(0.10f);
|
||||||
|
fxp_t AVG_FACT_INV = fxp_sub(fxp_from_int(1), AVG_FACT);
|
||||||
|
|
||||||
|
fxp_t maxVoltage = fxp_from_float(12.000f);
|
||||||
|
fxp_t maxCurrent = fxp_from_float( 5.000f);
|
||||||
|
|
||||||
// Calculated values
|
// Calculated values
|
||||||
//fxp_t VIN_SCALE = fxp_from_float(3.3f * (100 + 12.4f) / 12.4f / 4095.0f);
|
//fxp_t VIN_SCALE = fxp_from_float(3.3f * (100 + 12.4f) / 12.4f / 4095.0f);
|
||||||
|
@ -229,6 +241,8 @@ int main(void)
|
||||||
fxp_t VOUT_SCALE = fxp_from_float(12.6f / 1620.0f);
|
fxp_t VOUT_SCALE = fxp_from_float(12.6f / 1620.0f);
|
||||||
fxp_t CURRENT_SCALE = fxp_from_float(9.01f / 4095.0f);
|
fxp_t CURRENT_SCALE = fxp_from_float(9.01f / 4095.0f);
|
||||||
|
|
||||||
|
fxp_t CURRENT_OFFSET = fxp_from_float(0.049);
|
||||||
|
|
||||||
init_clock();
|
init_clock();
|
||||||
init_gpio();
|
init_gpio();
|
||||||
init_adc();
|
init_adc();
|
||||||
|
@ -246,37 +260,6 @@ int main(void)
|
||||||
// let the ADC+DMA do its work
|
// let the ADC+DMA do its work
|
||||||
adc_start_conversion_regular(ADC1);
|
adc_start_conversion_regular(ADC1);
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
// Ramp up target voltage
|
|
||||||
if((targetVoltage < TARGET_VOLTAGE) && (voltRampUpCountdown-- == 0)) {
|
|
||||||
targetVoltage += 2.0f;
|
|
||||||
voltRampUpCountdown = VOLTAGE_UP_INTERVAL;
|
|
||||||
|
|
||||||
if(targetVoltage > TARGET_VOLTAGE) {
|
|
||||||
targetVoltage = TARGET_VOLTAGE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// read ADC value
|
|
||||||
while(!adc_eoc(ADC1));
|
|
||||||
adcval = adc_read_regular(ADC1);
|
|
||||||
|
|
||||||
// scale current measurement
|
|
||||||
curVoltage = VOLTAGE_MEAS_MAX * adcval / 4096.0f;
|
|
||||||
|
|
||||||
|
|
||||||
// calculate resulting PWM value
|
|
||||||
if(controlAction > MAX_DUTY_CYCLE) {
|
|
||||||
pwm_value = (int)(PWM_PERIOD * MAX_DUTY_CYCLE);
|
|
||||||
} else if(controlAction > 0) {
|
|
||||||
pwm_value = (int)(controlAction * PWM_PERIOD);
|
|
||||||
} else {
|
|
||||||
pwm_value = 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// *** Do some calculations while ADC converts ***
|
// *** Do some calculations while ADC converts ***
|
||||||
|
|
||||||
if(lcd_setup()) {
|
if(lcd_setup()) {
|
||||||
|
@ -287,13 +270,13 @@ int main(void)
|
||||||
|
|
||||||
lcd_set_cursor_pos(1, 0);
|
lcd_set_cursor_pos(1, 0);
|
||||||
|
|
||||||
fxp_format(vin, number, 1);
|
fxp_format(vin_avg, number, 1);
|
||||||
fxp_right_align(number, msg, 4, ' ');
|
fxp_right_align(number, msg, 4, ' ');
|
||||||
lcd_send_string("I:");
|
lcd_send_string("I:");
|
||||||
lcd_send_string(msg);
|
lcd_send_string(msg);
|
||||||
lcd_send_string("V ");
|
lcd_send_string("V ");
|
||||||
|
|
||||||
fxp_format(vout, number, 1);
|
fxp_format(vout_avg, number, 1);
|
||||||
fxp_right_align(number, msg, 4, ' ');
|
fxp_right_align(number, msg, 4, ' ');
|
||||||
lcd_send_string("O:");
|
lcd_send_string("O:");
|
||||||
lcd_send_string(msg);
|
lcd_send_string(msg);
|
||||||
|
@ -301,7 +284,7 @@ int main(void)
|
||||||
|
|
||||||
lcd_set_cursor_pos(0, 10);
|
lcd_set_cursor_pos(0, 10);
|
||||||
|
|
||||||
scaled_val = fxp_mult(current, fxp_from_int(1000)); // A -> mA
|
scaled_val = fxp_mult(current_avg, fxp_from_int(1000)); // A -> mA
|
||||||
fxp_format(scaled_val, number, 0);
|
fxp_format(scaled_val, number, 0);
|
||||||
fxp_right_align(number, msg, 4, ' ');
|
fxp_right_align(number, msg, 4, ' ');
|
||||||
lcd_send_string(msg);
|
lcd_send_string(msg);
|
||||||
|
@ -330,6 +313,11 @@ int main(void)
|
||||||
vin = fxp_mult(fxp_from_int(adc_values[0]), VIN_SCALE);
|
vin = fxp_mult(fxp_from_int(adc_values[0]), VIN_SCALE);
|
||||||
vout = fxp_mult(fxp_from_int(adc_values[1]), VOUT_SCALE);
|
vout = fxp_mult(fxp_from_int(adc_values[1]), VOUT_SCALE);
|
||||||
current = fxp_mult(fxp_from_int(adc_values[2]), CURRENT_SCALE);
|
current = fxp_mult(fxp_from_int(adc_values[2]), CURRENT_SCALE);
|
||||||
|
current = fxp_sub(current, CURRENT_OFFSET);
|
||||||
|
|
||||||
|
vin_avg = fxp_add(fxp_mult(vin, AVG_FACT), fxp_mult(vin_avg, AVG_FACT_INV));
|
||||||
|
vout_avg = fxp_add(fxp_mult(vout, AVG_FACT), fxp_mult(vout_avg, AVG_FACT_INV));
|
||||||
|
current_avg = fxp_add(fxp_mult(current, AVG_FACT), fxp_mult(current_avg, AVG_FACT_INV));
|
||||||
|
|
||||||
// Main FSM
|
// Main FSM
|
||||||
if(timebase_ms >= 1000) {
|
if(timebase_ms >= 1000) {
|
||||||
|
@ -342,7 +330,7 @@ int main(void)
|
||||||
|
|
||||||
if(time_in_state >= 5) { // bootstrap duration in ms
|
if(time_in_state >= 5) { // bootstrap duration in ms
|
||||||
iErr = fxp_from_int(500);
|
iErr = fxp_from_int(500);
|
||||||
operState = ConvConstVoltage;
|
operState = nextState;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -351,7 +339,7 @@ int main(void)
|
||||||
timer_set_oc_value(TIM1, TIM_CH_BOOTSTRAP, 0);
|
timer_set_oc_value(TIM1, TIM_CH_BOOTSTRAP, 0);
|
||||||
|
|
||||||
// calculate error values
|
// calculate error values
|
||||||
pErr = fxp_sub(maxVoltage, vout);
|
pErr = fxp_sub(maxVoltage, vout_avg);
|
||||||
iErr = fxp_add(iErr, pErr);
|
iErr = fxp_add(iErr, pErr);
|
||||||
|
|
||||||
// limit integral error range
|
// limit integral error range
|
||||||
|
@ -360,15 +348,10 @@ int main(void)
|
||||||
|
|
||||||
// calculate the controller output ("action")
|
// calculate the controller output ("action")
|
||||||
controlAction = fxp_add(
|
controlAction = fxp_add(
|
||||||
fxp_mult(pErr, PGAIN),
|
fxp_mult(pErr, PGAIN_CV),
|
||||||
fxp_mult(iErr, IGAIN));
|
fxp_mult(iErr, IGAIN_CV));
|
||||||
|
|
||||||
int32_t pwm = fxp_to_int(controlAction);
|
pwm = fxp_to_int(controlAction);
|
||||||
|
|
||||||
if(pwm > 5000 && current < CURRENT_THRESHOLD) {
|
|
||||||
operState = Bootstrap;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pwm >= CONV_PWM_MAX) {
|
if(pwm >= CONV_PWM_MAX) {
|
||||||
timer_set_oc_value(TIM1, TIM_CH_CONV, CONV_PWM_MAX);
|
timer_set_oc_value(TIM1, TIM_CH_CONV, CONV_PWM_MAX);
|
||||||
|
@ -377,6 +360,52 @@ int main(void)
|
||||||
} else {
|
} else {
|
||||||
timer_set_oc_value(TIM1, TIM_CH_CONV, 0);
|
timer_set_oc_value(TIM1, TIM_CH_CONV, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(time_in_state > 1000 && pwm > CONV_PWM_MAX && current < CURRENT_THRESHOLD) {
|
||||||
|
operState = Bootstrap;
|
||||||
|
nextState = ConvConstVoltage;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(current_avg > maxCurrent) {
|
||||||
|
operState = ConvConstCurrent;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ConvConstCurrent:
|
||||||
|
// bootstrap off
|
||||||
|
timer_set_oc_value(TIM1, TIM_CH_BOOTSTRAP, 0);
|
||||||
|
|
||||||
|
// calculate error values
|
||||||
|
pErr = fxp_sub(maxCurrent, current_avg);
|
||||||
|
iErr = fxp_add(iErr, pErr);
|
||||||
|
|
||||||
|
// limit integral error range
|
||||||
|
if (iErr > IERR_LIMIT) iErr = IERR_LIMIT;
|
||||||
|
else if(iErr < -IERR_LIMIT) iErr = -IERR_LIMIT;
|
||||||
|
|
||||||
|
// calculate the controller output ("action")
|
||||||
|
controlAction = fxp_add(
|
||||||
|
fxp_mult(pErr, PGAIN_CC),
|
||||||
|
fxp_mult(iErr, IGAIN_CC));
|
||||||
|
|
||||||
|
pwm = fxp_to_int(controlAction);
|
||||||
|
|
||||||
|
if(pwm >= CONV_PWM_MAX) {
|
||||||
|
timer_set_oc_value(TIM1, TIM_CH_CONV, CONV_PWM_MAX);
|
||||||
|
} else if(pwm > 0) {
|
||||||
|
timer_set_oc_value(TIM1, TIM_CH_CONV, pwm);
|
||||||
|
} else {
|
||||||
|
timer_set_oc_value(TIM1, TIM_CH_CONV, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(time_in_state > 1000 && pwm > CONV_PWM_MAX && current < CURRENT_THRESHOLD) {
|
||||||
|
operState = Bootstrap;
|
||||||
|
nextState = ConvConstCurrent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(vout_avg > maxVoltage) {
|
||||||
|
operState = ConvConstVoltage;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Idle:
|
case Idle:
|
||||||
|
@ -396,6 +425,25 @@ int main(void)
|
||||||
if(operState != lastState) {
|
if(operState != lastState) {
|
||||||
time_in_state = 0;
|
time_in_state = 0;
|
||||||
lastState = operState;
|
lastState = operState;
|
||||||
|
|
||||||
|
lcd_set_cursor_pos(0, 7);
|
||||||
|
switch(operState) {
|
||||||
|
case Idle:
|
||||||
|
lcd_send_string("ID");
|
||||||
|
break;
|
||||||
|
case Bootstrap:
|
||||||
|
lcd_send_string("BS");
|
||||||
|
break;
|
||||||
|
case ConvConstCurrent:
|
||||||
|
lcd_send_string("CC");
|
||||||
|
break;
|
||||||
|
case ConvConstVoltage:
|
||||||
|
lcd_send_string("CV");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
lcd_send_string("??");
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
time_in_state++;
|
time_in_state++;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue