This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430F5172: Float variables in closed loop compensator

Part Number: MSP430F5172


Hello, 

I am using MSP430F5172 microcontroller to run a buck converter. I tested my closed loop controller in PLECs. However, I am having trouble with closed loop regulation in the microcontroller. I noticed that using float variables drastically reduces my execution time and ADC sampling frequency. I tried playing around with both integer and float values for the compensator variables but haven't been successful yet. Is there a way to optimize the code execution time when using float variables? Is there also a way to use integer variables and still make the code work? My switching frequency is 500kHz and below is the snippet of the code in main. Thank you. 

float kp=1;
float ki=0.1;
float Vbuckout_ref=214;
float D_buckH=0,D_buckL=0; // buck duty cycle
float Vbuckout_err=0,Vbuckout_err1=0; // previous and current error
float sum=0,sum_1=0;
float sum_max=19000;
float dbuck_max=190;

void main(void) {


WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer

// Configure PWM channels
P1SEL |= BIT7; // Set P1.7 to output direction - High BUCK
P1DIR |= BIT7;

P3SEL |= BIT0; // Set P3.0 to output direction - BAT_GD_EN
P3DIR |= BIT0;

P2SEL |= BIT0; // Set P2.0 to output direction - Low BUCK
P2DIR |= BIT0;

P2SEL |= BIT2; // Set P2.2 to output direction - High BOOST
P2DIR |= BIT2;

P2SEL |= BIT3; // Set P2.3 to output direction - Low BOOST
P2DIR |= BIT3;

P2SEL |= BIT6; // Set P2.6 to output direction - Vgate BAT
P2DIR |= BIT6;

// configure ADC pins
PMAPPWD = 0x02D52; // Enable Write-access to modify port mapping registers
PMAPCTL = PMAPRECFG; // Allow reconfiguration during runtime
P1MAP0|= PM_ANALOG; // Modify all PxMAPy registers - A0
P1MAP1|= PM_ANALOG; // Modify all PxMAPy registers - A1
P1MAP2|= PM_ANALOG; // Modify all PxMAPy registers - A2
P1MAP3|= PM_ANALOG; // Modify all PxMAPy registers - A3
P1MAP4|= PM_ANALOG; // Modify all PxMAPy registers - A4
P1MAP5|= PM_ANALOG; // Modify all PxMAPy registers - A5
P3MAP5|= PM_ANALOG; // Modify all PxMAPy registers - A8
P3MAP6|= PM_ANALOG; // Modify all PxMAPy registers - A7
PMAPPWD = 0; // Disable Write-Access to modify port mapping registers by writing incorrect key
P1SEL |=BIT5+BIT4+BIT3+BIT2+BIT1+BIT0; // setting the port mapping register PxMAPy to PM_ANALOG together with PxSEL.y=1 when applying analog signals
P3SEL |=BIT6+BIT5;

// Increase Vcore setting to level3 to support fsystem=25MHz
// NOTE: Change core voltage one level at a time.

SetVcoreUp (0x01);
SetVcoreUp (0x02);
SetVcoreUp (0x03);

// Initialize DCO to 25MHz
__bis_SR_register(SCG0); // Disable the FLL control loop - set SCG0
UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx
UCSCTL1 = DCORSEL_6; // Select DCO range 4.6MHz-88MHz operation
UCSCTL2 = FLLD_1+763; // Set DCO Multiplier for 25MHz
// (N + 1) * FLLRef = Fdco
// (762 + 1) * 32768 = 25MHz
// Set FLL Div = fDCOCLK/2

__bic_SR_register(SCG0); // Enable the FLL control loop - clear SCG0

// Worst-case settling time for the DCO when the DCO range bits have been
// changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
// UG for optimization.
// 32 x 32 x 25 MHz / 32,768 Hz = 781250 = MCLK cycles for DCO to settle
//__delay_cycles(781250);
__delay_cycles(782000);

SetADC();
SetDMA();
SetPWM(T_buck, T_boost);
__delay_cycles(100); // Delay between sequence convs

// P1DIR |= BIT0; // Set P1.0 to output direction

for(;;){

// ADC sampling frequency =8kHz
//P1OUT ^= BIT0; // Toggle P1.0 using exclusive-OR

while (ADC10CTL1 & BUSY); // Wait if ADC10 core is active
ADC10CTL0 |= ADC10ENC + ADC10SC; // Sampling and conversion ready
__bis_SR_register(CPUOFF + GIE); // LPM0, ADC10_ISR will force exit

Iin_temp =(int)ADC_Result [8];
Vin_temp= (int)ADC_Result [1];
Vbuckout_temp=(int) ADC_Result[7];

Vbuckout_err=(Vbuckout_ref-(float)Vbuckout_temp);

sum =kp*Vbuckout_err+ (sum + ki*(Vbuckout_err+Vbuckout_err1));
D_buckH= sum/1000;
if (sum>sum_max){
sum=19000;
D_buckH=190;
}
else if(sum<0){
sum=0;
}
D_buckL= D_buckH+1;
SetDuty_Buck (D_buckH, D_buckL);

Vbuckout_err1 = Vbuckout_err;
}
__bis_SR_register(LPM0_bits); // Enter LPM0
}

**Attention** This is a public forum