I am using the MSP430G2553 to control the switching of a half-bridge inverter, using Timer1 A3 in up/down mode. However, I am noticing that occasionally the output will either stay on or falsely turn on causing shoot through in my system. I am operating with a DCO of 8 MHz, and I am updating the TA1CCRx using a timer interrupt. Below is an oscilloscope capture of 1 occurrence. Below is also a snippet of the code used. Need assistance to resolve this issue.
#define MCU_CLOCK = 8000000; // MCU Clock Frequency [8 MHz]
int SW_Freq = 160; // MCU Switching Period [MCU CLOCK/SW Freq] [25 kHz]
unsigned int n = 0; // Lookup Table array index
unsigned int z = 0; // Counter
int DUTY_1 = 80;
int DUTY_2 = 75;
/*** SINE WAVE LOOKUP TABLE ***/
static const unsigned int Sin_lookup[84] =
{ 80, 83, 87, 90, 93, 96, 100, 103, 105, 108,
111, 113, 115, 117, 119, 121, 122, 123, 124, 124,
125, 125, 125, 124, 124, 123, 121, 120, 118, 117,
115, 112, 110, 107, 104, 102, 99, 95, 92, 89,
85, 82, 79, 75, 72, 69, 65, 62, 59, 56,
54, 51, 48, 46, 44, 42, 40, 39, 38, 37,
36, 35, 35, 35, 35, 36, 37, 38, 39, 40,
42, 44, 46, 48, 51, 54, 56, 59, 62, 65,
69, 72, 75, 79};
/**********************************************/
/* main.c
**********************************************/
void main(void)
{
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
DCOCTL = 0; // Select lowest DCOx and MODx
BCSCTL1 = CALBC1_8MHZ; // Set range
DCOCTL = CALDCO_8MHZ; // Set DCO step + modulation
/*** GPIO SETUP ***/
P2DIR |= BIT2; // Set P2.3 as output [TA1.3]
P2SEL |= BIT2; // Select P2.2 for special fcn Timer A3
P2SEL2 &= ~BIT2; // Select P2.2 for special fcn Timer A3
P2DIR |= BIT4; // Select P2.4 as Output
P2SEL |= BIT4; // Select P2.4 for special fcn Timer A3
P2SEL2 &= ~BIT4; // Select P2.4 for special fcn Timer A3
P1DIR &= ~BIT1; // Set P1.1 as input [A1]
P1SEL &= ~BIT1; // Select P1.1 for general I/O [A1]
P1SEL2 &= ~BIT1; // Select P1.1 for general I/O [A1]
/*** Timer A1 SETUP ***/
TA1CCR0 = SW_Freq-1; // PWM Control Period
//TA1CCTL0 |= CCIE;
TA1CCTL1 |= OUTMOD_6; // TA1CCR1 output mode = Toggle/Set
TA1CCTL2 |= OUTMOD_2; // TA1CCR2 output mode = Toggle/Reset
TA1CCR1 = DUTY_1; // TA1CCR1 initial PWM Duty Cycle
TA1CCR2 = DUTY_2; // TA1CCR2 initial PWM Duty Cycle
TA1CTL |= TASSEL_2 + ID_0 + MC_3 + TAIE; // SMCLK, Divided by 1, Up/Down Mode (Counts to TA1CCR0), & enable interrupts
_BIS_SR (CPUOFF + GIE); // Enter LPM0 + enable global interrupts
while (1); // Endless loop
}
/*** Timer_1_A3 Interrupt Service Routine ***/
#pragma vector =unused_interrupts
__interrupt void Timer1_A3_ISR (void)
{
z++; // Increment Counter
if (z == 5) // Counter z == 5, (~200 us); 5 sawtooth cycles, (320 *5) @ 8 MHz
{
n++; // increment look-up table index
if (n >=84) // check if index value is outside array length
{n=0;} // If true, reset index value
DUTY_1 = Sin_lookup[n]; // Change look-up table value
DUTY_2 = Sin_lookup[n]-15; // Change look-up table value - ~600 ns dead time
TA1CCR2 = DUTY_2; // TA1CCR1 PWM Duty Cycle updates
TA1CCR1 = DUTY_1; // TA1CCR2 PWM Duty Cycle updates
z = 0; // Reset counter
}
TA1CTL &= ~TAIFG; // Clear interrupt flag
}