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 {
|
||||
Bootstrap,
|
||||
ConvConstVoltage,
|
||||
ConvConstCurrent,
|
||||
Idle,
|
||||
};
|
||||
|
||||
|
@ -203,21 +204,32 @@ int main(void)
|
|||
char number[FXP_STR_MAXLEN];
|
||||
uint8_t sentSomething = 0;
|
||||
|
||||
int32_t pwm;
|
||||
|
||||
enum OperState operState = Bootstrap;
|
||||
enum OperState nextState = ConvConstVoltage;
|
||||
enum OperState lastState = operState;
|
||||
|
||||
fxp_t vin, vout, current;
|
||||
fxp_t vin_avg = 0, vout_avg = 0, current_avg = 0;
|
||||
|
||||
fxp_t pErr, iErr = 0;
|
||||
fxp_t controlAction;
|
||||
|
||||
fxp_t PGAIN = fxp_from_float( 20.000f);
|
||||
fxp_t IGAIN = fxp_from_float( 1.000f);
|
||||
fxp_t IERR_LIMIT = fxp_from_int(10000);
|
||||
fxp_t PGAIN_CV = fxp_from_float( 50.000f);
|
||||
fxp_t IGAIN_CV = fxp_from_float( 0.300f);
|
||||
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 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
|
||||
//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 CURRENT_SCALE = fxp_from_float(9.01f / 4095.0f);
|
||||
|
||||
fxp_t CURRENT_OFFSET = fxp_from_float(0.049);
|
||||
|
||||
init_clock();
|
||||
init_gpio();
|
||||
init_adc();
|
||||
|
@ -246,37 +260,6 @@ int main(void)
|
|||
// let the ADC+DMA do its work
|
||||
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 ***
|
||||
|
||||
if(lcd_setup()) {
|
||||
|
@ -287,13 +270,13 @@ int main(void)
|
|||
|
||||
lcd_set_cursor_pos(1, 0);
|
||||
|
||||
fxp_format(vin, number, 1);
|
||||
fxp_format(vin_avg, number, 1);
|
||||
fxp_right_align(number, msg, 4, ' ');
|
||||
lcd_send_string("I:");
|
||||
lcd_send_string(msg);
|
||||
lcd_send_string("V ");
|
||||
|
||||
fxp_format(vout, number, 1);
|
||||
fxp_format(vout_avg, number, 1);
|
||||
fxp_right_align(number, msg, 4, ' ');
|
||||
lcd_send_string("O:");
|
||||
lcd_send_string(msg);
|
||||
|
@ -301,7 +284,7 @@ int main(void)
|
|||
|
||||
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_right_align(number, msg, 4, ' ');
|
||||
lcd_send_string(msg);
|
||||
|
@ -330,6 +313,11 @@ int main(void)
|
|||
vin = fxp_mult(fxp_from_int(adc_values[0]), VIN_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_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
|
||||
if(timebase_ms >= 1000) {
|
||||
|
@ -342,7 +330,7 @@ int main(void)
|
|||
|
||||
if(time_in_state >= 5) { // bootstrap duration in ms
|
||||
iErr = fxp_from_int(500);
|
||||
operState = ConvConstVoltage;
|
||||
operState = nextState;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -351,7 +339,7 @@ int main(void)
|
|||
timer_set_oc_value(TIM1, TIM_CH_BOOTSTRAP, 0);
|
||||
|
||||
// calculate error values
|
||||
pErr = fxp_sub(maxVoltage, vout);
|
||||
pErr = fxp_sub(maxVoltage, vout_avg);
|
||||
iErr = fxp_add(iErr, pErr);
|
||||
|
||||
// limit integral error range
|
||||
|
@ -360,15 +348,10 @@ int main(void)
|
|||
|
||||
// calculate the controller output ("action")
|
||||
controlAction = fxp_add(
|
||||
fxp_mult(pErr, PGAIN),
|
||||
fxp_mult(iErr, IGAIN));
|
||||
fxp_mult(pErr, PGAIN_CV),
|
||||
fxp_mult(iErr, IGAIN_CV));
|
||||
|
||||
int32_t pwm = fxp_to_int(controlAction);
|
||||
|
||||
if(pwm > 5000 && current < CURRENT_THRESHOLD) {
|
||||
operState = Bootstrap;
|
||||
break;
|
||||
}
|
||||
pwm = fxp_to_int(controlAction);
|
||||
|
||||
if(pwm >= CONV_PWM_MAX) {
|
||||
timer_set_oc_value(TIM1, TIM_CH_CONV, CONV_PWM_MAX);
|
||||
|
@ -377,6 +360,52 @@ int main(void)
|
|||
} 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 = 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;
|
||||
|
||||
case Idle:
|
||||
|
@ -396,6 +425,25 @@ int main(void)
|
|||
if(operState != lastState) {
|
||||
time_in_state = 0;
|
||||
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 {
|
||||
time_in_state++;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue