Hello,
I'm trying to make a pulsing LED using the PWM feature of the msp430g2553. I am using up-mode with reset/set output mode. I use the TA0CCR0 CCIFG (TIMER0_A0_VECTOR interrupt) to change the TA0CCR1 value (giving the changing duty cycle). There are some #defines I made up for my own convenience so if a few things look strange I'm sorry for the confusion.
I am noticing the 'glitch' when the TA0CCR1 is being decremented. As the duty cycle is decreased I get a 'glitch' pulse that is larger than a 100% cycle pulse. I change my macros for period and step size and the glitch always appears as the TA0CCR1 is being decremented right before the TA0CCR1 value reaches 0. The glitch isn't present with all values of period and step sizes (my macros) but when it is present it is consistent. I can't figure out why. Any help will be greatly appreciated. Thanks :)
changing TA0CTL input divider from ID_2 to ID_1 the glitch travels further away from the TA0CCR1 = 0 value.
#include <msp430g2553.h> #define PERIOD 128 #define HALF_PERIOD 64 #define STEP 8 #define SMALL_STEP 1 void GPIO_init(void); void BCS_init(void); void TIMER0_A0_init(void); void main(void) { WDTCTL = WDTPW + WDTHOLD; GPIO_init(); BCS_init(); TIMER0_A0_init(); __bis_SR_register(GIE); LPM3; } void GPIO_init(void) { P1OUT = 0x07; // P1.0 = TA0CCR1++, P1.1 = TA0CCR1--, P1.3 = pulsing P1SEL = 0x40; P1DIR = 0xF8; P1REN = 0x07; P1IES = 0x07; P1IFG = 0x00; P1IE = 0x07; P2OUT = 0x00; P2SEL = 0xC0; P2DIR = 0xBF; P2REN = 0x00; P2IES = 0x00; P2IFG = 0x00; P2IE = 0x00; } void BCS_init(void) { do { // waiting for cyrstal to warm up IFG1 &= ~OFIFG; __delay_cycles(50); } while (IFG1 & OFIFG); IE1 |= OFIE; BCSCTL1 |= XT2OFF + DIVA_0; BCSCTL2 = SELM_2 + DIVM_0 + SELS_1 + DIVS_0; BCSCTL3 = XT2S_0 + LFXT1S_0 + XCAP_3; } void TIMER0_A0_init(void) { // up mode TA0CTL = TASSEL_1 + ID_2 + MC_1 + TACLR + TAID; // TAID = timer a interrupt disabled (0x0000) // reset @ TA0CCR1, set @ TA0CCR0 TA0CCTL1 = CM_0 + COM + OUTMOD_7; // COM = compare (0x0000) TA0CCR0 = PERIOD; TA0CCR1 = HALF_PERIOD; } #pragma vector = PORT1_VECTOR __interrupt void PORT1_ISR(void) { switch (P1IFG) { case BIT0: if (TA0CCR1 == PERIOD) // TA0CCR1++ TA0CCR1 = 0; else TA0CCR1 += STEP; P1IFG &= ~BIT0; break; case BIT1: if (TA0CCR1 == 0) // TA0CCR1-- TA0CCR1 = PERIOD; else TA0CCR1 -= STEP; P1IFG &= ~BIT1; break; case BIT2: TA0CCR1 = HALF_PERIOD; TA0CCTL0 |= CCIE; P1IFG &= ~BIT2; break; default: __never_executed(); } } #pragma vector = TIMER0_A0_VECTOR __interrupt void TIMER0_A0_ISR(void) { TA0CCR1 -= SMALL_STEP; if (TA0CCR1 == 0) TA0CCR1 = PERIOD; }