This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430F5438 Sine Wave Generator

Other Parts Discussed in Thread: MSP430F5438

Hello there.
I use a msp430f5438 and I try to generate a sine wave. Here is the code I want a 1 kHz sine but I got 300Hz. I do not know why. can you please tell me how to calculate the frequency of the sine.
THanks !

int   counter=0; 
int wave[36] = { 0,35,70,105,139,172,204,234,262,288,312,334,353,369,383,394,401,406,408,406,401,394,
383,369,353,334,312,288,262,234,204,172,139,105,70,35};

void Init_timer(){
TA0CCR0=408;  //PWM 44KHz
TA0CCTL2 |=OUTMOD_7|CCIE; 
TA0CCTL1 |=OUTMOD_7;//|CCIE;
TA0CCR1=wave[0];
TA0CCR2=wave[0];
TA0CTL |=TASSEL_2| ID_0 | MC_1 |TACLR|TAIE;  //SMCLK =18MHz, PWM=44KHz
}


#pragma vector=TIMER0_A1_VECTOR
__interrupt void TIMER0_A1_ISR(void){


switch(TA0IV){

case TA0IV_TA0CCR1:

break;

case TA0IV_TA0CCR2:

TA0CCR2= wave[counter];
counter ++;
 if ( counter == 36)
{
counter = 0;
}

break;
}

TA0CTL &=~TAIFG;

}

  • You shall run PWM at 50% duty cycle without any interrupt routine and using scope check that you are getting desired 44kHz PWM frequency. If your PWM cycle counter (CCR0) value is correct, then you possibly just lose interrupts which are coming too fast for CPU to keep up. Remember that there's not that much of ISR code you can execute 44000 times per second! I would use DMA to update CCR2 register rather than try to do it using CPU

    le testeur said:
    can you please tell me how to calculate the frequency of the sine.

    If your PWM coefficients "waveform" contain full sine wave then you simply divide sample rate (44 KHz) by sine waveform array size, in your case 37. Supposedly you sine frequency shall be 44000/37 Hz.

  • TAIE is overflow IRQ, as you don't use continues-up it should not trigger as that would be bad as I don't see that you case for it. but take it out just in case.

    no need to TA0CTL &=~TAIFG;  reading IV register clears IFG flag

    Is SMCLK really set up for 18MHz, check it.

    Then there will be the problems with software overhead and pulling the rug underneath
    the timer etc,you set CCR1 as 0 TAR but you are not using it for when it's time to changing CCR2 value.
    Changing the CCR2 value when it just triggered could cause you to see another triggering again as ~40 ticks higher value may have not happen yet. TimerB have latched-values as an option to not have this problem.

    And using the PWM value only once ( eg no oversampling)
    I don't the think the sine wave will be very clean looking even with good R-C filtering applied.

  • Tony Philipsson said:
    And using the PWM value only once ( eg no oversampling)
    I don't the think the sine wave will be very clean looking even with good R-C filtering applied.

    PWM oversampling? What you mean?  - How using PWM value more than one time can result in cleaner sine output?

  • >How using PWM value more than one time can

    If you for example speed up everything 4x and use the same pwm 4 times in a row.
    The R-C filter does not get a chance to wobble on it's analog output  
    As you are pumping it with intermittent lengths of 0v and 3.3v it will try to reach either one of those.

    PDM (Pulse density) instead of PWM does a better job of doing this, but hard to do on a msp430
    Using USCI and a lookup table that have 64bit PDM data instead, possible but you need 50+ MHz SMCLK.
    A 50% value is %010101010101010101010101..... you can see that the RC filter does not get a chance to wobble.
    instead of %11111111100000000  < pwm wobble

    But as 18MHz is as close as a msp430 can do, nothing you can really do anything about it.

  • Tony Philipsson said:
    If you for example speed up everything 4x 

    If you speed-up 18 MHz 4 times you run out of allowed freq range for msp430. If you speed up 4 times by changing period, you lose PWM resolution 4 times.

    Tony Philipsson said:
    and use the same pwm 4 times in a row.
    The R-C filter does not get a chance to wobble on it's analog output  

    This is something new. My PWM knowledge roots come from days when PWM was not generated by fancy digital timers but sawtooth generator and comparator. I do not see how repeating same length PWM pulses you can approximate sine better. Please explain (better)

    First google image that popped-up:

  • > I do not see how repeating same length PWM pulses you can approximate sine better.

    If you want a fast response (music data), using a higher cut-off freq on RC filter and spitting out the same
    value 4x faster and 4x in row is better
    Of course having 4x the number of real data is ever better, but storage is limited and speed may not be.
    Interpolation of data to "fake" the extra middle values is possible.

    1bit DAC CD players was all the rage at one time, some went from 16bit to 24bit but it turned out 1bit PDM may be better.

    But as I said a MSP at already 18MHz, not much can be done.

  • Tony Philipsson said:
    If you want a fast response (music data), using a higher cut-off freq on RC filter and spitting out the same
    value 4x faster and 4x in row is better

    Higher cut-off freq filter and higher resolution PWM of course gives smoother output :)

    Tony Philipsson said:
    Of course having 4x the number of real data is ever better, but storage is limited and speed may not be.

    Limited storage in not limiting factor in our case here, speed is:

    Tony Philipsson said:
    But as I said a MSP at already 18MHz, not much can be done.

    Agreed. Thou using 18MHz clock with PDM you mention could be good idea especially when higher freq sine needed

  • >Limited storage in not limiting factor in our case here, speed is:

    In this case as there is still plenty of Flash for larger table.

    But if you have a sound sample there is a limit of sample rate as to not run out of Flash
    Oversampling and/or interpolation will help with creating a better sound if you have the MCU power to do
    so In between getting a new data-byte from sample lookup table.

    A Music CD there is 700MB hard limit, but you can make the hardware DAC faster and oversample.

  • Ilmars said:

    Higher cut-off freq filter and higher resolution PWM of course gives smoother output :)

     I disagree, higher PWM frequency need a very complex digital part, higher resolution lower the PWM frequency and an higher cut off filter report more noise than signal....

     A better approach is to do higher frequency low resolution pwm interpolating value, but this case PDM or other conversion method are better. The Audio dac unibit converter use no PWM at all but just a 50MHz or more pattern generator.

  • Roberto Romano said:
     I disagree, higher PWM frequency need a very complex digital part, higher resolution lower the PWM frequency

    Look, higher resolution PWM could mean both - increased PWM frequency and granularity, I did mean both. Sorry about misunderstanding. Anyway our chit-chat does not help having msp430 timers as limiting factor here

  • Ilmars said:

     then you possibly just lose interrupts which are coming too fast for CPU to keep up. 

    you right. i think i lose interrupts...    SMCLK frequency is 18MHz, but MCLK frequency is 500KHz .may be it's the problem. now i'm trying to change MCLK frequency to 18MHz.  here is the code i use to modify smclk frequency. i thought that it would modify mclk frequency. but it didn't. (i took it on the net ....)

        P11SEL|= (BIT0|BIT2|BIT1);
        P11DIR|=(BIT0|BIT2|BIT1);
        P5SEL |= 0x0C;                            // Port select XT2
    
         UCSCTL6 &= ~XT2OFF;                       // Enable XT2
         UCSCTL3 |= SELREF_2;                      // FLLref = REFO
                                                   // Since LFXT1 is not used,
                                                   // sourcing FLL with LFXT1 can cause
                                                   // XT1OFFG flag to set
         UCSCTL4 |= SELA_2;                        // ACLK=REFO,SMCLK=DCO,MCLK=DCO
    
         // Loop until XT1,XT2 & DCO stabilizes
         do
         {
           UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG);
                                                   // Clear XT2,XT1,DCO fault flags
           SFRIFG1 &= ~OFIFG;                      // Clear fault flags
         }while (SFRIFG1&OFIFG);                   // Test oscillator fault flag
    
         UCSCTL6 &= ~XT2DRIVE0;                    // Decrease XT2 Drive according to
                                                   // expected frequency
         UCSCTL4 |= SELS_5 + SELM_5;               // SMCLK=MCLK=XT2
    

  • Ilmars said:
    Look, higher resolution PWM could mean both - increased PWM frequency and granularity, I did mean both. Sorry about misunderstanding. Anyway our chit-chat does not help having msp430 timers as limiting factor here

     The document refer to Piccolo C2000 series EPWM, EPWM has NOTHING to do with simple PWM of MSP430 nor other series. So having ps resolution for fractional duty cycle on pwm again is not a good solution at your writing of an higher frequency filter.. On this EPWM or PWM still same noise or "wobble" remain on output. The only way to filter noise is unibit (PDM) or an high frequency pwm modulated by a low frequency otherwise a good filter with many poles than higher frequency leaving all aliasing and noise from pwm.

    To generate precise clean waveform It is better use 18MHz SPI implementing rudimental SPD than using EPWM !!!!

     Again program presented for generating sine wave need use more than one sample on pwm cycle, lowering PWM resolution to have higher frequency can help filter noise in a sort of spreading spectrum on pwm cycle modulation... First analog filter integrate pwm to a curved high freq staircase, the low pass smooth out remaining ripple.

     Pwm of MSP430 are great and if used with knowledge are better than competitors (c2xxx series excluded).

  • le testeur said:
    TA0CTL |=TASSEL_2| ID_0 | MC_1 |TACLR|TAIE; //SMCLK =18MHz, PWM=44KHz

     Hi, TA0CTL is set to a known value before this line? If not try change |= to a simple =, otherwise spurios bit setting can alter this register resulting in a wrong operation or clock divider.

     If not used on other part int can be fine but is forever better declare counter as volatile or static in the interrupt handler.

**Attention** This is a public forum