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.
#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
}