Jump to content
43oh

Setting up PWM on launchpad


Recommended Posts

Hi, everybody. I'm trying to get a simple PWM signal to output and I'm having trouble, even making TI's example code work. Here's my current program:

 

void main(void)
{
 BCSCTL1 = 0x80; 
 BCSCTL2 |= 0x04; 
 WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
 P1DIR |= BIT1;                            // P1.1 output
 P1SEL |= BIT1;                            // P1.1 option select

 CCTL0 = OUTMOD_7;                         // CCR0 reset/set mode  
 CCR0 = 100-1;                             // PWM period
 CCR1 = 25;                                // PWM duty cycle

 TACTL = TASSEL_2 + MC_1;                  // SMCLK, upmode

 _BIS_SR(CPUOFF);                          // CPU off
}

 

According to the TI docs, output mode 7 is reset/set, so the period from timer=0 to CCR1 should have output=1, and from timer=CCR1 to CCR0 should have output=0. But I'm getting a 100% duty cycle, no matter what I put in for CCR1. It's like it's ignoring the output mode or something.

 

Any ideas? I'm completely stumped.

 

-Paul

Link to post
Share on other sites

Hi, gordon. I've looked at the slau144h document, and I believe I'm doing everything it says.

 

CCTL0 = OUTMOD_7;                         // CCR0 reset/set mode 

 

Output mode 7 should reset (output==1) from zero to CCR1, and set (output==0) from CCR1 to CCR0, thus giving me the desired PWM duty cycle:

 

CCR0 = 100-1;                             // PWM period
CCR1 = 25;                                // PWM duty cycle

 

The diagram in the PDF shows this very clearly on the mode 7 line for up-mode; the output is high from zero to CCR1 and low from CCR1 to CCR0.

 

Of course, TI's documentation often uses slightly different register names than the C headers -- ex. TACCR0 instead of CCR0. That's why I'm thinking I may have missed something, despite using TI's own examples as a starting point.

 

Do you have some working PWM code that I can use a starting point? I found this page where somebody describes how to do PWM on the 430, and they're using the same method as I am. Could I have a busted 430 or something?

 

(sigh...spam-bot detection won't let me post the URL)

Link to post
Share on other sites

With some more tinkering I was able to get PWM working as expected, and I was able to output PWM to arbitrary pins (though I settled on P1.6 since it's got an LED hooked up already).

 

I wrote this simple little program to ensure I understood how to incorporate interrupts (from a pin, not a timer) along with a PWM output...maybe this will be useful to somebody. This code runs on a MSP430G2231, but I suspect it'll run on any of the 430's...

 


//******************************************************************************
//  Description: Toggle P1.0 using interrupt routine. Timer_A is configured
//  for up mode with CCR0 defining period, TA0 also output on P1.6.  P1.6
//  will pulse up (brighter) by default.  Toggle P1.3 (S2) and the direction will
//  change, making P1.6 pulse down (dimmer) as well as toggling P1.0 (indicating
//  direction).
//  ACLK = n/a, SMCLK = MCLK = TACLK = default DCO
//
//            MSP430G2xx1
//         -----------------
//     /|\|              XIN|-
//      | |                 |
//      --|RST          XOUT|-
//        |                 |
//  S2 -->|P1.3         P1.0|--> LED1
//        |                 |
//        |         P1.6/TAO|--> LED2/PWM out
//******************************************************************************

#include  

unsigned int pwm_duty=1;
int dir = 1;

void main(void)
{
 unsigned int x;

 WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
 P1OUT &= 0x0;                             // Drop all outputs to zero by default
 P1DIR |= ~BIT3;                           // P1.3 input, all others output
 P1IE  |= BIT3;                            // P1.3 interrupt enable
 P1IFG &= ~BIT3;                           // Clear the P1.3 interrupt

 P1SEL |= BIT6;                            // P1.6 option select (enables timer output)  
 CCR0 = 1000-1;                            // PWM period
 CCTL1 = OUTMOD_7;                         // Timer_A output reset/set mode 
 CCR1 = pwm_duty;                          // PWM duty cycle

 TACTL = TASSEL_2 + MC_1;                  // use SMCLK, up mode 

 _BIS_SR(GIE);                             // Enable interrupts

 while(1) {
 	// Increment or decrement the PWM duty
pwm_duty = pwm_duty + dir;
if(pwm_duty > 998) {
	pwm_duty = 1;
}
if(pwm_duty < 1) {
	pwm_duty = 999;
}

// Set the duty cycle
CCR1 = pwm_duty;
// Pause to give a nice pulse speed
for(x=0; x<100; x++);
 }	
}

// Port 1 interrupt service routine
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
   dir *= -1;      // change pulse direction
   P1OUT ^= BIT0;  // toggle P1.0
P1IFG &= ~BIT3; // clear interrupt
}

Link to post
Share on other sites
Othe register for controlling the output mode of TIMER_A is CCTL1, not CCTL0

 

This is quite far from the truth. Timer_A is not one specific concrete timer instance, but is the generic name for the peripheral. There is no such thing as "the register controlling Timer_A". What there is is "the register controlling Timer_A0", "the register controlling "Timer_A1", etc.

 

there seems to be some limitations on which output pins you can use.

 

This however is quite true. That's what the device pinout sections, terminal functions sections and (to some extent or especially, depends on how you look at it) the port schematics sections of the device-specific data sheets describe in painful detail.

 

The timer peripherals of the '430 are reasonably complicated things (well, until you get the hang of it, at least). I suggest to read and re-read and re-re-read Chapter 12 of the family guide (or possibly one of the fine dead tree books out there) and try things out until they make sense. Don't rush it, and especially don't skip a single word, graph or diagram -- been there, done that, didn't work out...

Link to post
Share on other sites

So the particular model of the 430 I'm using may only have a Timer_A1, and that's why it's behaving like this? Or possibly the A1 timer is hooked up to different output pins than Timer_A0?

 

::sigh:: clearly I've got some more reading to do...

 

My only complaint with the TI docs is that they seem to have been written by different people than those who wrote the C header files -- the subtle differences in the various names is a pretty frequent stumbling block for me...

Link to post
Share on other sites
So the particular model of the 430 I'm using may only have a Timer_A1, and that's why it's behaving like this?

It's unlikely that it has A1, but doesn't have A0. The reason it's behaving like this is spelled out in section 13.2.5.1 (made a typo in my original reply, sorry -- not 12.2.5.1) of SLAU144:

13.2.5.1 Output Modes

 

The output modes are defined by the OUTMODx bits and are described in Table 13-4. The OUTx signal is changed with the rising edge of the timer clock for all modes except mode 0. Output modes 2, 3, 6, and 7 are not useful for output unit 0 because EQUx = EQU0.

Or possibly the A1 timer is hooked up to different output pins than Timer_A0?

It is. Pin functions are detailed in the device pinout sections, terminal functions sections and the port schematics sections of the device-specific data sheets.

My only complaint with the TI docs is that they seem to have been written by different people than those who wrote the C header files -- the subtle differences in the various names is a pretty frequent stumbling block for me...

Yeah, it is confusing at first, but not too bad. You'll learn to translate between them on the fly :).

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...