1

I am trying to do simple PWM with MSP430. Working with timer I am facing one issue. I have noticed that clock divider doesn't make any sence eather I set ID_3 that suppose divide clock by 8, or I set ID_1 or ID_2. The output frequency that I am seeing with the scope is 130Hz. Is there any mistakes?

#include "msp430g2553.h"  

  volatile unsigned long i;
  volatile unsigned int D1=50;

void main(void)
{
  i=0;
  WDTCTL = WDTPW + WDTHOLD;         // Stop WDT  
  CCTL0 = CCIE;                     // CCR0 interrupt enabled
  TACTL = TASSEL_2 + MC_1 + ID_1;          // SMCLK, upmode MC1
  CCR0 =  5;                       // Timer should count up to CCR) and reset   
  P1OUT &= 0x00;                    // Shut down everything
  P1DIR &= 0x00;               
  P1DIR |= BIT0;                    // P1.0 pin output 
  _BIS_SR(CPUOFF + GIE);            // Enter LPM0 w/ interrupt 
  while(1)                          //Loop forever, we work with interrupts!
  {}
} 

// Timer A0 interrupt service routine 
#pragma vector=TIMER0_A0_VECTOR 
__interrupt void Timer_A (void) 
{   
   i=i+1;
   if (i>=100) {i=0;}
   if (i<=D1) {P1OUT = BIT0;}                          
   if (i>D1) {P1OUT &= 0x00;}
} 
Audrius M
  • 21
  • 3

1 Answers1

1

By default, SMCLK and the CPU run at the same frequency (about 1.1 MHz). The interrupt handler needs much longer than five cycles to run, so the output speed is determined not by how you configure the timer but by how fast the code in Timer_A() can run.

You could try to optimize the interrupt handler (i does not need to have 32 bits, etc.) and to use a longer timer interval. But it might be a better idea to configure the timer for hardware PWM.

CL.
  • 173,858
  • 17
  • 217
  • 259
  • Agree on hardware PWM – kfx May 04 '17 at 11:16
  • Thank you for comment. Basically I need 4 PWMs with different duty cycles, so using hardware I can't do this with hardware PWM. I will try to use your tip to choose different type of i. For me it looks like incrementing shouldn't take too much cycles, especially when I am letting timer to run at 1.1MHz. – Audrius M May 04 '17 at 19:37
  • The CPU *cannot* increment a 32-bit variable; this must be painstakingly emulated in software. And consider increasing the DCO frequency. – CL. May 05 '17 at 07:05
  • Thanks for suggestions guys. I have optimised my pwm parameters and now start to use 3 pwm signals: volatile unsigned char i=0; volatile unsigned char D1=127; volatile unsigned char D2=10; volatile unsigned char D3=230; now processor should work only with char that is 8 bit. Now I imagine that it should take very short time for timer interrupt to be finished, but now I have only 66Hz. My timer interrupt code below, why it takes so much time for MSP430? – Audrius M May 05 '17 at 09:56
  • `// Timer A0 interrupt service routine #pragma vector=TIMER0_A0_VECTOR __interrupt void Timer_A (void) { i=i+1; if (i>=255) {i=0;} if (i<=D1) {P1OUT |= 0x01;} else {P1OUT &= ~0x01;} if (i<=D2) {P1OUT |= 0x40;} else {P1OUT &= ~0x40;} if (i<=D3) {P1OUT |= 0x04;} else {P1OUT &= ~0x04;} }` – Audrius M May 05 '17 at 09:57
  • As well I have try to do the fastest thing try only toggle LED in timer interrupt and the fastest I can go is 32kHz while setting divider to no divider and CCR0 = 2. This means that Subsystem Master clock is much slower than 1.1MHz. Any ideas. From my point of view is SMCLK is 1.1MHz i should divide it by 2 due to CCR0 and divide by 2 due to flip flop. That should be around 275kHz. Any ideas? – Audrius M May 05 '17 at 10:15
  • You must increase CCR0 to at least a hundred or so. (It must be larger than the number of cycles needed by the interrupt handler.) – CL. May 05 '17 at 10:37