Page 1 of 1

audio ADC noisy conversion MSP430

Posted: Thu Oct 22, 2015 6:49 am
by Dodz
Hello,
I´m trying to sampling data from a microphone but even if i try to do an oversampling I get always a noisy sound.
I´m actually sampling at 80kHz I tryed to use some reference voltage to increase the sound quality but I´m getting always the same results. The sound is not clear.
Code: Select all
#include "msp430.h"
void SetVcoreUp (unsigned int level);//to work with high freq
int volatile audioread;
unsigned char overflow;
    void PORT_Init()
    {
      //LED PORTS AS OUTPUT
      P10DIR = P10DIR | 0xC0;
      //XT2 Oscilator PORTS
      P5SEL = P5SEL | 0x0C;                   //set XT2 pins as alternate function
      P5DIR = P5DIR | 0x0C;                   //set XIN/XOUT as output

      //Clock PORTS
      P11SEL = P11SEL | 0x07;                 //P11.0/P11.1/P11.2 set as alternate functions
      P11DIR = P11DIR | 0x07;                 //P11.0/P11.1/P11.2 set as output
	
      //ADC PORTS
      P8SEL = P8SEL | 0x02;                   //PP8.1 --> ADC (ADC_OUT - remake) function
      P6SEL = P6SEL | 0x80;                   //P6.7 --> ADC function
      P8DIR = P8DIR | 0x02;                   //P8.1 (ADC_OUT - remake) set as output
      P6DIR = P6DIR & 0x7F;                   //PORT6.7 (ADC_IN)  set as input
      P6DIR|= BIT6;                           //PORT6.6 for frequency ceck
    }

      void CLOCK_XT2_Init()
    {
      int timeout = 5000;
      P11DIR = P11DIR | 0x02 | 0x04;            //set P11.1 & P11.2 as output
      P11SEL = P11SEL | 0x02 | 0x04;            //set P11.1 & P11.2 as MCLK/SMCLK function
      P5SEL = P5SEL | 0x04 | 0x08;              //set P5.2 & P5.3 as XT2IN/XT2OUT

      UCSCTL6 = UCSCTL6 & (~XT2OFF);            //set XT2OFF=0 enable XT2
      UCSCTL6 |=XT2DRIVE_3;
      UCSCTL6|=XCAP_3;
      UCSCTL3 = UCSCTL3 | 0x20;                 //set SELREF = 010 --> FLL clock source = REFOCLK
      UCSCTL4 = UCSCTL4 | 0x200;                //set SELA = 010 --> ACLK=REFO
      do
      {
        if (!(UCSCTL7 & 0x08)) break;
        UCSCTL7 = UCSCTL7 & ~(0x0F);            // Clear XT2,XT1,DCO fault flags
        SFRIFG1 = SFRIFG1 & ~(0x02);            // Clear fault flags (SFRIFG1.OFIFG = 0)
        timeout--;
      }
      while ((SFRIFG1 & 0x02) && timeout);      // Test oscillator fault flag
      UCSCTL4 = SELA_5 + SELS_5 + SELM_5;//SMCLK=MCLK=ACLK=XT2
      UCSCTL5 = DIVS_1 + DIVM_0 + DIVA_0;//SMCLK/2=16MHz;MCLK/32;ACLK/1
    }

    void ADC12_Init()
    {
        ADC12CTL0 &= ~ADC12ENC;
        ADC12CTL0 =  ADC12ON + //Turn on ADC12
      		       ADC12SHT0_1+// 32 cycles per sample (Sampling time)
  				   ADC12MSC + //multiple sample
				   ADC12REFON; //enable int ref

        ADC12CTL1 = ADC12SHP + //pulse mode
      		      ADC12CONSEQ_2 +//single channel single conversion
  			      ADC12SSEL_3 + //clock source SMCLK
  			      ADC12CSTARTADD_0;//select first (in order) register (7)
        ADC12CTL2 = ADC12RES_0 + ADC12REFBURST;      // 8bit res, 9 clock cycles to convert,Reference buffer on only during sample-and-conversion
        ADC12CTL2 &= ~(ADC12DF);        //ADC12DF=0   --> unsigned format
        ADC12MCTL0 = ADC12SREF_7 +
        		     ADC12EOS +
				     ADC12INCH_7; //End of Sequence --> Bit7 = 1; ADC12SREF = 0b111; ADC12INCH = 0b0111;
        __delay_cycles(75);                       // 35us delay to allow Ref to settle
                                                  // based on default DCO frequency.
                                                  // See Datasheet for typical settle
                                                  // time.
        ADC12CTL0 |= ADC12ENC;                    // Enable conversions

    }

    unsigned int ADC12_Receive()
    {
      ADC12IE = 0x01;;                  // Enable ADC12IFG.0
      ADC12CTL0 |= ADC12SC;           //start conversion ON
      P6OUT^=BIT6;
      __bis_SR_register(LPM3_bits + GIE);  //wait for interrupt
//      while (ADC12CTL1 & 0x01);  //wait while BUSY
      return ADC12MEM0;

    }

    void TIMER_A_Init()
    {
      TA0CTL = TASSEL_1 + MC_1 ; //TimerA clock source is ACLK (bit8=0, bit9=1),Mode Control set to UP mode (MC bits = 0b01)
      TA0CCTL0 = OUTMOD_1;           //OUTMODE0 = 0b001 (set mode)
      TA0CCTL1 = OUTMOD_3;           //OUTMODE1 = 0b110 (set/reset mode)
      TA0CCR0 = 0x00;                         //turn off timer
    }
    void TIMER_B_Init()
    {
    	  TB0CCTL0 = CCIE;                          // CCR0 interrupt enabled
    	  TB0CCR0 = 34 -1;//--->                           Fs=4MHz/2*45~ 44.4KHz
    	  TB0CTL = TASSEL_2 + MC_1 + TBCLR;         // SMCLK=4Mhz, upmode, clear TAR
    	  __bis_SR_register(LPM3_bits + GIE);       // Enter LPM3, enable interrupts
    	  __no_operation();                         // For debugger
    }
int main(void)
{
  int del;

  WDTCTL = WDTPW + WDTHOLD;// Stop watchdog timer to prevent time out reset
  SetVcoreUp(PMMCOREV_3);                    // Set VCore to 1.8MHz for 20MHz
  /* Initialize the shared reference module */
 // REFCTL0 |= REFMSTR + REFVSEL_0 + REFON + REFTCOFF; // Enable internal 2V reference
  REFCTL0 &= ~REFMSTR;//disable ref
  PORT_Init();
  CLOCK_XT2_Init();
  ADC12_Init();
  TIMER_B_Init();
  TIMER_A_Init();
  TA0CCR0 =255;//(2^8-1=256-1)
	  while(1)
	  {
	     __bis_SR_register(LPM3_bits+GIE);//enter LPM0 waiting interrupt
	      if(overflow)
	   {  overflow=0;
	      TA0CCR1 = ADC12_Receive();
	      __bis_SR_register(CPUOFF);// ADC_ISR force exit
 }
  }
}
void SetVcoreUp (unsigned int level)
{
  // Open PMM registers for write
  PMMCTL0_H = PMMPW_H;
  // Set SVS/SVM high side new level
  SVSMHCTL = SVSHE + SVSHRVL0 * level + SVMHE + SVSMHRRL0 * level;
  // Set SVM low side to new level
  SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * level;
  // Wait till SVM is settled
  while ((PMMIFG & SVSMLDLYIFG) == 0);
  // Clear already set flags
  PMMIFG &= ~(SVMLVLRIFG + SVMLIFG);
  // Set VCore to new level
  PMMCTL0_L = PMMCOREV0 * level;
  // Wait till new level reached
  if ((PMMIFG & SVMLIFG))
    while ((PMMIFG & SVMLVLRIFG) == 0);
  // Set SVS/SVM low side to new level
  SVSMLCTL = SVSLE + SVSLRVL0 * level + SVMLE + SVSMLRRL0 * level;
  // Lock PMM registers for write access
  PMMCTL0_H = 0x00;
}
#pragma vector=TIMER0_B0_VECTOR
__interrupt void TIMER0B0ISR(void)
{
	overflow=1;
	__bic_SR_register_on_exit(CPUOFF);
}
// Timer A0 interrupt service routine
#pragma vector=ADC12_VECTOR
__interrupt void ADC12ISR (void)
{
  ADC12IE = 0;
  __bic_SR_register_on_exit(CPUOFF);   // Exit active CPU, SET BREAKPOINT HERE
  }