⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audio.c

📁 msp430 test code and examples for using a 5438
💻 C
字号:
/**********************************************************************//**
 * @file audio.c
 * 
 * Copyright 2008 Texas Instruments, Inc.
***************************************************************************/
#define AUDIO_TEST_MODE   0
#define AUDIO_DEMO_MODE   1
#define SamplePrd         2048
#define Memstart          0x10000
#define Memend            0x45BFF
#define MemstartTest      0x40000
#define ADC12MEM0_        0x720
 

static unsigned long AUDIO_MEM_START[] = {0x10000, 0x20000, 0x30000, 0x40000, 0x46000};
unsigned long PlaybackPtr;
extern unsigned long lastAudioByteFlash;
unsigned long lastAudioByte = 0;


static void setupRecord(void); 
static void shutdownRecord(void);
static void record(void);

void saveSettings();                        // Definition in menuSetting.c

/**********************************************************************//**
 * @brief  Initializes the microphone, ADC, and DMA for recording.
 * 
 * @param  none
 * 
 * @return none
 *************************************************************************/
static void setupRecord(void)
{
  LED_PORT_OUT |= LED_1;                    // Turn on LED
  AUDIO_PORT_OUT |= MIC_POWER_PIN;
  AUDIO_PORT_OUT &= ~MIC_INPUT_PIN;
  AUDIO_PORT_SEL |= MIC_INPUT_PIN;
  
  lcdBackLightLevelSettingLOCAL = halLcdGetBackLight();
  if (lcdBackLightLevelSettingLOCAL < 5)
    halLcdSetBackLight(0);
  else
    halLcdSetBackLight(16);
  
  TBCTL = TBSSEL_2;                         // Use SMCLK as Timer_B source
  TBR = 0;
  TBCCR0 = 2047;                            // Initialize TBCCR0
  TBCCR1= 2047- 100;
  TBCCTL1 = OUTMOD_7;      
  
  UCSCTL8 |= MODOSCREQEN;
  ADC12CTL2 = ADC12RES_0;                   // Select 8-bit resolution
  ADC12CTL0 = ADC12ON + ADC12SHT02 ;  
  ADC12CTL1 = ADC12SHP + ADC12CONSEQ_2 + ADC12SSEL_2 + ADC12SHS_3;     
  //Sequence of channels, once
  ADC12MCTL0 = MIC_INPUT_CHAN | ADC12EOS  ; //VeREF+ and VeREF-
  ADC12CTL0 |= ADC12ENC;                    //Enable
  ADC12CTL0 |= ADC12SC;                     //Start conversion
  
  DMACTL0 = DMA0TSEL_24;                    // ADC12IFGx triggers DMA0
  DMA0SA = (void (*)())ADC12MEM0_;          // Src address = ADC12 module
  
  halButtonsInterruptDisable( BUTTON_S1 );
}

/**********************************************************************//**
 * @brief  Disables the recording peripherals and the microphone.
 * 
 * @param  none
 * 
 * @return none
 *************************************************************************/
static void shutdownRecord(void)
{ 
  halLcdSetBackLight(lcdBackLightLevelSettingLOCAL);
  
  TBCTL &= ~MC0;
  ADC12CTL0 &= ~( ADC12ENC + ADC12ON );
  
  FCTL1 = FWKEY;                            // Disable Flash write
  FCTL3 = FWKEY + LOCK;                     // Lock Flash memory
  
  // Power-down MSP430 modules
  ADC12CTL1 &= ~ADC12CONSEQ_2;              // Stop conversion immediately
  ADC12CTL0 &= ~ADC12ENC;                   // Disable ADC12 conversion
  ADC12CTL0 = 0;                            // Switch off ADC12 & ref voltage
  
  TBCTL = 0;                                // Disable Timer_B
  LED_PORT_OUT &= ~LED_1;                   // Turn off LED  

  AUDIO_PORT_OUT &= ~MIC_POWER_PIN;         // Turn of MIC   
  AUDIO_PORT_SEL &= ~MIC_INPUT_PIN;   

  saveSettings();                           // Store lastAudioByte to Flash

  halLcdPrintLine("    DONE    ",  6, INVERT_TEXT | OVERWRITE_TEXT);  
  halLcdPrintLineCol("Record",  8, 1,  OVERWRITE_TEXT);
  halLcdPrintLineCol("Play",  8, 12,  OVERWRITE_TEXT);
  buttonsPressed = 0;

  halButtonsInterruptEnable( BUTTON_S1);
}

/**********************************************************************//**
 * @brief  Executes the record. 
 * 
 * - Unlocks the Flash and initialize to long-word write mode 
 * - Initializes the Timer to trigger ADC12 samples
 * - When the operation is done, locks the flash, disables the DMA, and stops
 *   the timer
 * 
 * @param  none
 * 
 * @return none
 *************************************************************************/
static void record(void)
{  
  halLcdPrintLine("  Recording ", 6, INVERT_TEXT | OVERWRITE_TEXT);
  halLcdPrintLineCol("Stop", 8, 12,  OVERWRITE_TEXT);  

  FCTL3 = FWKEY;                            // Unlock the flash for write
  FCTL1 = FWKEY + BLKWRT;                        
  
  DMA0CTL = DMADSTINCR_3 + DMAEN + DMADSTBYTE +  DMASRCBYTE + DMAIE;
  // Enable Long-Word write, all 32 bits will be written once 
  // 4 bytes are loaded
  
  TBCCTL1 &= ~CCIFG;
  TBCTL |= MC0;                             
  
  __bis_SR_register(LPM0_bits + GIE);       // Enable interrupts, enter LPM0  
  __no_operation(); 
  
  TBCTL &= ~MC0;
  DMA0CTL &= ~( DMAEN + DMAIE);
  
  FCTL3 = FWKEY + LOCK;                     // Lock the flash from write 
}

/**********************************************************************//**
 * @brief  Global API call to record audio on the mike. 
 * 
 * - Initializes the record using setupRecord()
 * - Erases the memory reserved for audio recording
 * - Records until the memory is full using record()
 * - Shuts down the record using shutdownRecord()
 * 
 * @param  mode The mode of audio record 
 * 
 * - AUDIO_TEST_MODE ...for production test
 * - AUDIO_DEMO_MODE ...called for user sample code
 * 
 * @return none
 *************************************************************************/
void audioRecord(unsigned char mode)
{
  unsigned char i;
    
  setupRecord(); 

  halLcdPrintLine("   Erasing  ", 6, INVERT_TEXT | OVERWRITE_TEXT);  
  halLcdPrintLineCol("----", 8, 12,  OVERWRITE_TEXT);
  
  // Not used in User Experience sample code 
  if (mode == AUDIO_TEST_MODE)
  {
    flashErase(MemstartTest, Memend);
    DMA0DA = (void (*)())MemstartTest;      
    DMA0SZ = (long) (Memend - MemstartTest);
    
    record();
    
    if (DMA0SZ != ( long) (Memend - MemstartTest))
      lastAudioByte = Memend - DMA0SZ;
    else
      lastAudioByte = Memend;
  }
  // Always used in User Experience sample code 
  else
  {
    flashEraseBank(AUDIO_MEM_START[0]);
    flashEraseBank(AUDIO_MEM_START[1]);
    flashEraseBank(AUDIO_MEM_START[2]);
    flashErase(AUDIO_MEM_START[3], AUDIO_MEM_START[4]);    
    
    for (i=0;i<3;i++)
    {  
      DMA0DA = (void (*)())AUDIO_MEM_START[i];               
      DMA0SZ = AUDIO_MEM_START[i+1] - AUDIO_MEM_START[i] - 1;
      
      record();
      
      if (DMA0SZ != AUDIO_MEM_START[i+1] - AUDIO_MEM_START[i] - 1)
      {
        lastAudioByte = AUDIO_MEM_START[i+1] - DMA0SZ;
        break;
      }
      else lastAudioByte = AUDIO_MEM_START[i+1]-1;      
    }
  }
  
  shutdownRecord();
}

/**********************************************************************//**
 * @brief  Plays back the audio data stored in Flash memory using 
 *         the integrated DMA controller and the DAC12 module.
 * 
 * @param  mode The mode of audio record 
 * 
 * - AUDIO_TEST_MODE ...for production test
 * - AUDIO_DEMO_MODE ...called for user sample code
 * 
 * @return none
 *************************************************************************/
void audioPlayBack(unsigned char mode)
{  
  // Power-up external hardware
  AUDIO_PORT_DIR |= AUDIO_OUT_PWR_PIN;
  AUDIO_PORT_OUT &= ~AUDIO_OUT_PWR_PIN;
  AUDIO_OUT_SEL |= AUDIO_OUT_PIN;           // P4.4 = TB4  
  LED_PORT_OUT |= LED_1;                    // Turn on LED  

  if (mode == AUDIO_TEST_MODE)
    PlaybackPtr = (unsigned long)(MemstartTest);
  else
    PlaybackPtr = (unsigned long)(Memstart);
 
  PlaybackPtr ++;
  
  /* Setup Timer0_A for playback */
  // Use SMCLK as Timer0_A source, enable overflow interrupt
  TBCTL = TBSSEL_2 + TBIE;                  
  // Set output resolution (8 bit. Add 10 counts of headroom for loading TBCCR1  
  TBCCR0 = 255 ;                              
  TBCCR4 = 255 >> 1;                        // Default output ~Vcc/2
  // Reset OUT1 on EQU1, set on EQU0. Load TBCCR1 when TBR counts to 0.
  TBCCTL4 = OUTMOD_7 + CLLD_1;              
  // Start Timer_B in UP mode (counts up to TBCCR0)
  TBCTL |= MC0;                             
  
  halLcdPrintLine("   Playing  ", 6, INVERT_TEXT | OVERWRITE_TEXT);
  halLcdPrintLineCol(" Stop ", 8, 1,  OVERWRITE_TEXT);
  halButtonsInterruptDisable( BUTTON_S2 );
  
  // Activate LPM during DMA playback, wake-up when finished
  __bis_SR_register(LPM0_bits + GIE);       // Enable interrupts, enter LPM0
  __no_operation(); 
  
  halLcdPrintLine("    DONE    ", 6, INVERT_TEXT | OVERWRITE_TEXT); 
  halButtonsInterruptEnable( BUTTON_S2 );
  halLcdPrintLineCol("Record", 8, 1,  OVERWRITE_TEXT);
  halLcdPrintLineCol("Play", 8, 12,  OVERWRITE_TEXT);
  
  // Power-down MSP430 modules
  TBCTL = 0;                                // Disable Timer_B PWM generation  
  AUDIO_OUT_SEL &= ~AUDIO_OUT_PIN;          // P4.4 = TB4
  LED_PORT_OUT &= ~LED_1;                   // Turn off LED
  buttonsPressed = 0;
}

/**********************************************************************//**
 * @brief  Calls the audioRecord function with the AUDIO_TEST_MODE as the
 *         parameter.         
 * 
 * @param  none
 * 
 * @return none
 *************************************************************************/
void audioRecordTest(void)
{
  audioRecord( AUDIO_TEST_MODE );  	
}

/**********************************************************************//**
 * @brief  Calls the audioPlayBack function with the AUDIO_TEST_MODE as the
 *         parameter.         
 * 
 * @param  none
 * 
 * @return none
 *************************************************************************/
void audioPlayBackTest(void)
{
  audioPlayBack( AUDIO_TEST_MODE );	
}

/**********************************************************************//**
 * @brief  Executes the "Voice Rec" menu option in the User Experience
 *         example code. Calls the necessary functions according to the
 *         user selection of "Record", "Play", or Exit (center D-pad btn press)
 * 
 * - Initializes the LCD to display the "Record" and "Play" selections
 * - Enters LPM3 to be awoken and continue code execution after a button press
 * - According to the user selection records audio, plays audio, or exits 
 * 
 * @param  none
 * 
 * @return none
 *************************************************************************/
void audio(void)
{
  unsigned char quit = 0;
  
  halLcdClearScreen();
  
  while (!quit)
  {
    buttonsPressed = 0;   
    halLcdPrintLineCol("Record", 8, 1,  OVERWRITE_TEXT);
    halLcdPrintLineCol("Play", 8, 12,  OVERWRITE_TEXT);
    
    __bis_SR_register(LPM3_bits + GIE);   //Returns if button pressed        
    __no_operation(); 
    
    if (buttonsPressed & BUTTON_S1)
    {
      halLcdPrintLineCol("Record", 8, 1, INVERT_TEXT | OVERWRITE_TEXT);
      audioRecord( AUDIO_DEMO_MODE );
      halLcdPrintLineCol("Record", 8, 1,  OVERWRITE_TEXT);
    }
    if (buttonsPressed & BUTTON_S2)
    {
      halLcdPrintLineCol("Play", 8, 12, INVERT_TEXT | OVERWRITE_TEXT);
      audioPlayBack( AUDIO_DEMO_MODE );
      halLcdPrintLineCol("Play", 8, 12,  OVERWRITE_TEXT);
    }
    if (buttonsPressed & BUTTON_SELECT)
      quit = 1;
  }
}

/********************************************************************/
#pragma vector=DMA_VECTOR
__interrupt void DMA_ISR(void)
{
	DMA0CTL &= ~ DMAIFG;
	__bic_SR_register_on_exit(LPM0_bits);    // Exit LPM0 on reti
}

#pragma vector=TIMERB1_VECTOR      
__interrupt void TIMERB1_ISR(void)
{
  static int counter  = 0;
  
  switch (TBIV)
  {
    case 14 :
    if (++counter == 8)
    {
      counter  = 0;
      TBCCR4 = (*((unsigned char*)PlaybackPtr));
      PlaybackPtr++;
  
      if ((unsigned long) PlaybackPtr >= (lastAudioByte))      
      {
        TBCTL = 0;
        __bic_SR_register_on_exit(LPM0_bits);   
      } 
    }
    default: break; 
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -