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

📄 msp430fg4618playbackwav.c

📁 Audio app to store an audio file in internal memory of the device
💻 C
字号:
//******************************************************************************
//  MSP430FG4618 Demo - Playback audio with PWM and internal Flash
//  Written for the MSP-EXP430FG4618 board
//
//                   MSP430F20xx
//                -----------------
//            /|\|                 |
//             | |                 |
//             --|RST              |
//               |                 |pin 79
//               |         TA2/P2.0|--------> PWM voice output
//               |                 |          MSP-EXP430FG4618
//               |                 |          H4 pin 1
//               |                 |          H4 pins 2,3,4 = Low => ~0V
//               |                 |
//               |                 |
//               |             P2.1|--------> LED
//               |                 |
//               |             P1.0|<-------- button S1
//               |                 |
//
//
// Necessary CCE Project Settings:
//
// Device Variant = MSP430FG4618
//
// Add to linker-command file a data section in high memory:
//   Open file lnk_msp430fg4618.cmd
//   In the areaSECTIONS add the following line:
//     .const2    : {} > FLASH2             /* CONSTANT DATA IN HIGH MEMORY      */
//
// Select large memory model and CPUX:
//   Project > Properties
//   > C/C++ Build
//   > Tool Settings
//   > MSP430 Compiler v3.0
//   > Runtime Model Options:
//   > Use large-data memory model (--large_memory_model)
//   Silicon version (--silicon_version) mspx
//
// Adapt run-time library to large-data-model :
//   Project > Properties
//   > C/C++ Build
//   > Tool Settings
//   > MSP430 Linker v3.0
//   > File Search Path:
//   > Include library file or command file as input (--library) = rts430xl.lib OR rts430xl_eh.lib
//
//   Libraries are in:
//   C:\Program Files\Texas Instruments\CCE v3.2.1.4 Professional\tools\compiler\MSP430\lib\
//
//
// Necessary IAR Project Settings:
//   If adding Audio to higher memory in CPUX.
//   > Project
//   > Options
//   > Data Model - Large
//   Make a new custom command linker file out of lnk430Fxxx.xcl and assign IAR
//   to use it.
//   > Project
//   > Options
//   > Linker
//   > Config
//   > Check box Override Default for Command Linker File
//   Under constant data, add the following line
//   // Constant data
//      -Z(CONST)DATA20_C2=10000-1FFFF
//
//  P. Forstner
//  Texas Instruments Inc.
//  January 2009
//  Built with IAR Embedded Workbench Version: v4.11
//  Built with CCE Version: 3.1 Build 3.2.3.6.4
//******************************************************************************

#define LEDPOUT      P2OUT
#define LEDPDIR      P2DIR
#define LEDBIT       BIT1                   // LED indicator

#define ButtonPIN    P1IN
#define ButtonPOUT   P1OUT
#define ButtonPDIR   P1DIR
#define ButtonPIFG   P1IFG
#define ButtonPIES   P1IES
#define ButtonPIE    P1IE
#define ButtonPSEL   P1SEL
#define ButtonPREN   P1REN

#define ButtonBIT    BIT0                   // P1.0 is button input

#define PWM_POUT     P2OUT
#define PWM_PDIR     P2DIR
#define PWM_PSEL     P2SEL
#define PWM_BIT      BIT0

char * pAudio;

unsigned int uAvgCntr;
unsigned int uAudioSample1;
unsigned int uAudioSample2;
int iAudioSampleDifference;
unsigned long lAudioSampleCnt;
unsigned long lAudioSampleLength;

unsigned char AudioFileNr;

#include "msp430xG46x.h"
#include "Audio1.h"
#include "Audio2.h"

void main (void)
{
  volatile int temp;

  WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer

  P1DIR = 0xFC; P1OUT = 0x00;               // P1 is output-low for low power
  P2DIR = 0xDF; P2OUT = 0x00;               // P2 is output-low for low power
  P3DIR = 0xDF; P3OUT = 0x00;               // P3 is output-low for low power
  P4DIR = 0xFF; P4OUT = 0x00;               // P4 is output-low for low power
  P5DIR = 0xFF; P5OUT = 0x00;               // P5 is output-low for low power
  P6DIR = 0xFF; P6OUT = 0x00;               // P6 is output-low for low power
  P7DIR = 0xFF; P7OUT = 0x00;               // P7 is output-low for low power
  P8DIR = 0xFF; P8OUT = 0x00;               // P8 is output-low for low power
  P9DIR = 0xFF; P9OUT = 0x00;               // P9 is output-low for low power
  P10DIR = 0xFF; P10OUT = 0x00;             // P10 is output-low for low power

// configure GPIOs
  LEDPOUT      |= LEDBIT;
  LEDPDIR      |= LEDBIT;                   // LED turned on
  ButtonPDIR   &= ~ButtonBIT;
  ButtonPOUT   |= ButtonBIT;
  ButtonPIES   |= ButtonBIT;                // Interrupt on rising edge
  ButtonPIE    |= ButtonBIT;                // Enable Port Interrupt

// configure clock
  FLL_CTL0 |= DCOPLUS | XCAP14PF;           // Configure load caps
                                            // f(MCL)&f(SMCLK) = f(DCO)
  do                                        // stabilize
  {
    IFG1 &= ~OFIFG;                         // Clear osc fault flag
    __delay_cycles(50000);                  // Delay for osc to stabilize
  } while(IFG1 & OFIFG);                    // Check to see if osc flag is set
  SCFI0 |= FLLD_1 | FN_2;                   // range for DCO 1.3 - 12.1 MHz
                                            // feedback /2
  SCFQCTL = 122-1;                          // f(DCO) = (122 * 2) x 32768Hz = 8MHz

  LEDPOUT &= ~LEDBIT;                       // LED turned off
                                            // to indicate stable xtal

// Initialize Timer_A for PWM output
  TACTL = TASSEL_2 | ID_0 | TACLR;          // clock = SMCLK = 8 MHz
                                            // overflow interrupt enabled
  TACCTL2 = CM_0 | OUTMOD_0 | CCIE;         // CM_0: Compare mode (no capture mode)
                                            // OUTMOD_0 & BIT=0 : output=0
                                            // CCIE: Compare Interrupt Enabled
  TACCR0 = 0xFF;                            // 8-bit counter from 00h to FFh

  __bis_SR_register(GIE);                   // Enable Interupts GIE

// Mainloop
  AudioFileNr = 0;
  while (1)
  {
    ButtonPIE &= ~ButtonBIT;                // Disable button S1
    LEDPOUT  |= LEDBIT;                     // LED turned on

    switch (AudioFileNr)
    {
      case 0:  pAudio = (char *) &Audio2;   // set pointer to Audio2 data byte
               break;
      default: pAudio = (char *) &Audio1;   // set pointer to Audio1 data byte
    }
    *(((char*)(&lAudioSampleLength))+0) = *(pAudio++);
    *(((char*)(&lAudioSampleLength))+1) = *(pAudio++);
    *(((char*)(&lAudioSampleLength))+2) = *(pAudio++);
    *(((char*)(&lAudioSampleLength))+3) = *(pAudio++);
    uAudioSample1 =  *(pAudio++);           // read first audio sample
    uAudioSample2 =  *(pAudio++);           // read second audio sample

    TACCTL2 &= ~(OUTMOD_7 | OUT);           // PWM output = LOW
    PWM_PDIR |= PWM_BIT;                    // TA2/P2.0 is output
    PWM_PSEL |= PWM_BIT;                    // TA2/P2.0 is TA2 output
    TACCTL2 |= OUTMOD_7;                    // outmode = RESET/SET

    uAvgCntr = 0;
    TACTL |= MC_1;                          // Start Timer_A in "up-mode"

    for (lAudioSampleCnt = lAudioSampleLength-1; lAudioSampleCnt > 0; lAudioSampleCnt--)
    {
       __bis_SR_register(LPM0_bits + GIE);  // LPM0: keep DCO running
       uAudioSample1 = uAudioSample2;
       uAudioSample2 =  *(pAudio++);        // read next audio sample
    }

    TACTL     &= ~MC_0;                     // Stop Timer_A
    TACCTL2   &= ~(OUTMOD_7 | OUT);         // PWM output = LOW
    PWM_POUT  &= ~PWM_BIT;                  // PWM GPIO-Pin = LOW
    PWM_PDIR  &= ~PWM_BIT;                  // TA2/P2.0 is input
    PWM_PSEL  &= ~PWM_BIT;                  // TA2/P2.0 is P2.0 input

    AudioFileNr++;                          // point to next Audio File
    AudioFileNr &= 0x01;                    // AudioFileNr Modulo 2

    LEDPOUT &= ~LEDBIT;                     // LED turned off
    ButtonPIFG &= ~ButtonBIT;               // Clear pending button Interrupt
    ButtonPIE |= ButtonBIT;                 // Enable button S1 Interrupts

    __bis_SR_register(LPM4_bits + GIE);     // LPM3: turn off
                                            // and wait until putton pressed
  }
}

//******************************************************************************
// Timer A1 interrupt service routine
//******************************************************************************
#pragma vector=TIMERA1_VECTOR
__interrupt void Timer_A1_ISR (void)
{                                           // Timer interupt (PWM, one sample)
  switch (__even_in_range(TAIV,10))
  {
    case 2:
            break;                          // Vector 2: TACCR1
    case 4:                                 // Vector 4: TACCR2
            __no_operation();
            iAudioSampleDifference = (int) uAudioSample2 - (int) uAudioSample1;
            if (iAudioSampleDifference > 68)
            {
              TACTL   &= ~TAIFG;            // clear overflow flag TAIFG IFG
              TACTL   |= TAIE;              // enable overflow interrupt TAIFG
              TACCTL2 &= ~CCIE;             // turn off TACCR2 IFG
            }
            switch (__even_in_range(uAvgCntr,6))
            {
              case 0: TACCR2 = (uAudioSample1
                               + uAudioSample1
                               + uAudioSample1
                               + uAudioSample2) >> 2;
                       break;

              case 2: TACCR2 = (uAudioSample1
                               + uAudioSample2) >> 1;
                       break;

              case 4: TACCR2 = (uAudioSample1
                               + uAudioSample2
                               + uAudioSample2
                               + uAudioSample2) >> 2;
                       break;

              case 6: TACCR2 = uAudioSample2;
                      __bic_SR_register_on_exit(LPM4_bits);
                                            // Clear all LPM bits from 0(SR)
                                            // this restarts audio output loop
                                            // and read next audio sample from
                                            // SPI-Flash memory
                       break;
            }
            uAvgCntr+=2;                    // increment averaging counter (always by 2)
            uAvgCntr = uAvgCntr & 0x06;     // averaging counter range: 0, 2, 4, 6
            break;
    case 6:                                 // Vector 4: TACCR3
            break;
    case 8:                                 // Vector 8: TACCR4
            break;
    case 10:                                // Vector 10: TAIFG Flag
            TACCTL2 &= ~CCIFG;              // clear TACCR2 IFG
            TACCTL2 |= CCIE;                // enable TACCR2 IFG
            TACTL   &= ~TAIE;               // turn off overflow interrupt TAIFG
            break;
  }
} // __interrupt void TimerA1 (void)

//******************************************************************************
// P1 interrupt service routine
//******************************************************************************
#pragma vector=PORT1_VECTOR
__interrupt void Port1 (void)
{
  P1IFG = 0x00;                             // reset all interupt flags
  ButtonPIE &= ~ButtonBIT;                  // Disable Port Interrupt
  __bic_SR_register_on_exit(LPM4_bits);     // Clear all LPM bits from 0(SR)
                                            // this restarts main loop and
                                            // starts next audio playback
}

⌨️ 快捷键说明

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