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.

Class-D Audio Amplifier with MSP430 (MSP430FG4617) - create the optimal Audio PWM

Other Parts Discussed in Thread: MSP430FG4617

Hi 

In University we have a project with the task to set up a simple Class D Audio Amplifier (with PWM Output)

The CPU Hardware is specified: MSP430FG4617 - goal is to get out the most with the given hardware

The first  concept is:

  • Use the ADC12 to Sample Audio
  • Scale and output PWM on TimerB
  • calculate a moving average of ADC12 measurements while PWM period  (done)
  • Update PWM after one period (with Interrupt)  (done)
With the maximum PWM Speed I  can set TBCCR0 to have a output with 44,8 kHz and get a maximum reselution.
The question I have is how to set up the clock of the MSP430 correctly.
How do I get the optimal Audio PWM (TimerB)? How to generate the maximum possible TimerB frequency?
 
  --- I thought about using the FFL+ clock module to generate a fast SMCLK for the PWM, but I'm not sure how to set it up correctly and what is the maximum timer frequency is. 
 
How do I have to programm my INIT_CLOCK()?  
 
(Of cause i have to adjust my Input divider of the adc12 (see below))
Sorry - This is the first time I programm a MSP in C ;)

void INIT_ADC(void) //______________________________________________________________________________________
{
P6SEL |= 0x03; // Enable A/D inputs

ADC12CTL0 = SHT0_0 + SHT1_0 + ADC12ON + REFON + REF2_5V + MSC; // S&H 4 ADC12CLK cycles, ADC on, Referenceon, Ref=2,5V, Multiple sample and conversion
ADC12CTL1 = SHP + ADC12SSEL_2 + ADC12DIV_3 + CONSEQ_3; // use sampling timer, MCLK, Divider=4, repeat sequence of channels

ADC12MCTL0 = INCH_0 + SREF_1; 
ADC12MCTL1 = INCH_1 + SREF_1;
ADC12MCTL2 = INCH_0 + SREF_1;
ADC12MCTL3 = INCH_1 + SREF_1;
ADC12MCTL4 = INCH_0 + SREF_1;
ADC12MCTL5 = INCH_1 + SREF_1 + EOS;
ADC12IE = 0x08; // Interrupt at MCTL3 - moving average is calculated

ADC12IFG = 0x00;

ADC12CTL0 |= ENC;
_NOP();
_NOP();
ADC12CTL |= ADC12SC;
}

void INIT_PWM(void) //______________________________________________________________________________________

{
// Configure Outputs
P2DIR |= BIT1 + BIT2 // Set Pin 1 and 2 as output
P2SEL |= BIT1 + BIT2 // Selsct Special Function on Pin 1 and 2

TBCTL |= TBIE + MC_1 + TBSSEL_SMCLK +ID0; // Enable Interrupt, Up Mode, SMCLK, Input_Divider=0 -
TBIFG = 0x00;
TBCCTL0 |= CCIE; // Enable Interrupt for CCR0
TBCCR0 = 179; // this is for 8 Mhz - can i get faster?

// Configure Left Chanel PWM
TBCCTL1=OUTMOD7
TBCCR1=0x00
// Configure Right Chanel PWM
TBCCTL2=OUTMOD7
TBCCR2=0x00
}

  • For 12 bit resolution and 44.8kHz signal, you'll need a timer frequency of 44800*4096 = 183.500.800 Hz. Quite a bit above the specs. With below 8MHz clock, you won't get more than 7 bit resolution at this frequency.

    Also, the FLL (or the DCO) isn't the best frequency source, as the FLL-generated output frequency is only a long-time average frequency. The DCO itself has a jitter, depending on modulation, adn the FLL continuously adjusts the frequency after a few clock cycles. So the high frequency resolution of 44kHz as well as any larger amplitude resolution would be worthless if you don't have a stable jitter-free clock.

    You can't have everything at once, so you'll have to find out what is highest priority for you and step back on the other parameters.

**Attention** This is a public forum