MSP430G2452 PWM example

With the TI  MSP430G2452 you can use the internal timer to generate a PWM modulated output. Not all the IO pins can be used as an timer output for PWM, so you need to check the datasheet for the MSP430 uC for the pin description.

In this example the TimerA0 is running in count-up mode counting up to TACCR0. Every time the TimerA0 counts to TACCR1 the specified output pin is set to high until the counter reaches TACCR0 where the output pin is set to low again.
So with the modification of TACCR0 and TACCR1 you can modify the duty cycle of the PWM signal on the output pin. The duty cycle is the ratio of signal high time to signal low time and equal to TACCR1/TACCR0.
The complete periode time of the PWM signal is set with the TACCR0 value.

To show how different duty cycles effect the output pin, the button on the launchpad is configured as an input for increasing the duty cycle by 10% on each button push.

(This example code is for the msp-gcc4 compiler. If you use a different compiler you need to check the interrupt vector names in your msp430g2452.h file for the correct vector names)

#include <msp430g2452.h>
#include <legacymsp430.h>
/*
 Ratio for this PWM test ist TACCR1/TACCR0 (duty cycle)
 Select low values for both registers for higher sampling frequency
 */
int main(void)
{
 WDTCTL = WDTPW + WDTHOLD;

 DCOCTL= 0;
 BCSCTL1= CALBC1_1MHZ;
 DCOCTL= CALDCO_1MHZ;

 P1DIR = BIT6 | BIT0 | BIT4;
 P1OUT &= ~(BIT6 | BIT0 | BIT4);

 P1DIR &= ~BIT3;

 P1IE |= BIT3; // P1.3 interrupt enable
 P1IFG &= ~BIT3; // P1.3 IFG cleared
 P1REN |= BIT3; // P1.3 Resistor enable (Pull up or Pull down)

 // set sub-system clock divider to 8
 BCSCTL2 |= DIVS_3;

 // set TACCRO register -> count to
 TACCR0 = 100;
 // select TimerA source SMCLK, set mode to up-counting
 TACTL = TASSEL_2 | MC_1;

 // set ouput to Port P1.6
 P1SEL |= BIT6;

 // select timer compare mode 
 TACCTL1 = OUTMOD_7 | CCIE;
 // Interrupt called when counter reaches TACCR1
 // set up counter_limit for interrupt TIMER0_A1_VECTOR
 TACCR1 = 0;
// enable all interrupts
 __enable_interrupt();

 // endless loop 
 for (;;) { 
 }

 return 0;
}
// This will be called when timer counts to TACCR1.
interrupt(TIMER0_A1_VECTOR) ta1_isr(void)
{
 // clear interrupt flag
 TACCTL1 &= ~CCIFG;
}
interrupt(PORT1_VECTOR) p1_isr(void) {
 if (P1IN & BIT3) {
 TACCR1 = (TACCR1 +10)%100;
 }
 P1OUT ^= BIT0;
 P1IFG &= ~BIT3; // P1.3 IFG cleared
 P1IES ^= BIT3;
}

 

Leave a Reply

Your email address will not be published. Required fields are marked *


− five = 0

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>