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

📄 msp430f2012playbackwav.c

📁 Audio app to store an audio file in internal memory of the device
💻 C
字号:
//******************************************************************************
//  MSP430F2012PlaybackWAV.c - This software is designed for eZ430-Speech
//                             hardware for audio Playback using PWM and
//                             external SPI-Flash
//
//                   MSP430F20xx
//                -----------------
//            /|\|                 |
//             | |                 |
//             --|RST              |
//               |                 |
//               |     TA1/TXD/P1.2|--------> PWM voice output
//               |                 |
//               |                 |
//               |             P1.0|---->/HOLD M25P64
//               |                 |
//               |             P1.3|---->/S (Chip Select) M25P64
//               |                 |
//               |        P1.5/SCLK|-------->
//               |         P1.6/SDO|-------->  SPI master
//               |         P1.7/SDI|<--------
//               |                 |
//               |             P1.0|--------> LED
//               |                 |
//               |             P1.4|<-------- button
//               |                 |
//
//
//  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 SCLK      0x20                      // SCLK on P1.5
#define SDO       0x40                      // SDO on P1.6
#define SDI       0x80                      // SDO on P1.7

#define FlashSelPOUT P1OUT
#define FlashSelPDIR P1DIR
#define FlashSelBIT  BIT3                   // P1.3 is M25P64 SELECT

#define LEDPOUT      P1OUT
#define LEDPDIR      P1DIR
#define LEDBIT       BIT0                   // 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    BIT4                   // P1.4 is button input

#define PWM_POUT     P1OUT
#define PWM_PDIR     P1DIR
#define PWM_PSEL     P1SEL
#define PWM_BIT      BIT2

unsigned char TXDataUSI;
unsigned char RXDataUSI;
unsigned char USIcompleteRX;

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

unsigned char AudioFileNr;

void TX_USI (void);

#include  <msp430x20x2.h>

void main (void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer

  __bis_SR_register(OSCOFF);                // Turn LFXT1 off
  P2SEL &= ~(BIT6 | BIT7);                  // LFXT1 pins are GPIOs
  P2DIR |= BIT6 | BIT7;                     // LFXT1 GPIOs are outputs for low power!

// Control signals of external Flash
  FlashSelPOUT |= FlashSelBIT;
  FlashSelPDIR |= FlashSelBIT;              // SPI-Flash SELECT = HIGH
  LEDPOUT      &= ~LEDBIT;
  LEDPDIR      |= LEDBIT;                   // LED turned off
  ButtonPDIR   &= ~ButtonBIT;
  ButtonPOUT   |= ButtonBIT;
  ButtonPREN   |= ButtonBIT;                // Button input with pull-up
  ButtonPIES   |= ButtonBIT;                // Interrupt on rising edge
  ButtonPIE    &= ~ButtonBIT;               // Interrupt on rising edge

// Initialize Timer_A for PWM output
  TACTL = TASSEL_2 | ID_1 | TACLR;          // clock = SMCLK /2 = 16 MHz / 2
                                            // overflow interrupt enabled
  TACCTL1 = 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

// Initialize SPI master with USI
  USICTL0 |= USIPE7 +  USIPE6 + USIPE5 + USIMST + USIOE; // Init I/Os, SPI master
  USICTL1 |= USICKPH;                       // sample on rising edge
  USICKCTL = USIDIV_2 + USISSEL_2;          // USICLK = SMCLK / 4 = 4MHz
  USICTL0 &= ~USISWRST;                     // USI released for operation
  USIcompleteRX = 0;                        // No RX transmission result

  __delay_cycles(40000);                    // Time for VCC to rise to 3.3V
  if ((CALDCO_16MHZ == 0xFF) || (CALBC1_16MHZ == 0xFF))
  {
    while(1)                                // Blink LED if calibration data
    {                                       // missing
      LEDPOUT ^= LEDBIT;                    // Toggle LED
      __delay_cycles(60000);
    }
  }
  DCOCTL = CALDCO_16MHZ;                    // DCO = 16MHz calibrated
  BCSCTL1 = CALBC1_16MHZ;                   // DCO = 16MHz calibrated

  __bis_SR_register(GIE);                   // Enable Interupts GIE

  FlashSelPOUT &= ~FlashSelBIT;             // SPI-Flash SELECT = LOW
  TXDataUSI = 0x9F;                         // 0x9F: read ID
  TX_USI();                                 // send TXDataUSI through SPI
  while (USIcompleteRX == 0);
  TXDataUSI = 0x00;                         // 0x9F: read ID
  TX_USI();                                 // send TXDataUSI through SPI
  while (USIcompleteRX == 0);
  TX_USI();                                 // send TXDataUSI through SPI
  while (USIcompleteRX == 0);
  TX_USI();                                 // send TXDataUSI through SPI
  while (USIcompleteRX == 0);
  FlashSelPOUT |= FlashSelBIT;              // SPI-Flash SELECT = HIGH
  __delay_cycles(40000);                    // keep SEL a minimum time low

// Mainloop
  AudioFileNr = 0;
  while (1)
  {
    LEDPOUT  |= LEDBIT;                     // LED turned on

    FlashSelPOUT &= ~FlashSelBIT;           // SPI-Flash SELECT = LOW
    TXDataUSI = 0xAB;                       // 0x0AB: release from Deep Power-Down
    TX_USI();                               // send instruction 0x03
    FlashSelPOUT |= FlashSelBIT;            // SPI-Flash SELECT = HIGH
    __delay_cycles(2500);                   // keep SEL a minimum time HIGH
    FlashSelPOUT &= ~FlashSelBIT;           // SPI-Flash SELECT = LOW
    TXDataUSI = 0x03;                       // 0x03: read data bytes
    TX_USI();                               // send instruction 0x03
    while (USIcompleteRX == 0);
    TXDataUSI = AudioFileNr;                // SPI-Flash start addr = 0xNR0000
    TX_USI();                               // send address byte 1
    while (USIcompleteRX == 0);
    TXDataUSI = 0x00;                       // SPI-Flash start addr = 0xNR0000
    TX_USI();                               // send address byte 2
    while (USIcompleteRX == 0);
    TX_USI();                               // send address byte 3
    while (USIcompleteRX == 0);
    TX_USI();                               // send dummy byte to receive data
    while (USIcompleteRX == 0);
    TX_USI();                               // receive: size byte 0
    *(((char*)(&lAudioSampleLength))+0) = RXDataUSI;
    while (USIcompleteRX == 0);
    TX_USI();                               // receive: size byte 1
    *(((char*)(&lAudioSampleLength))+1) = RXDataUSI;
    while (USIcompleteRX == 0);
    TX_USI();                               // receive: size byte 2
    *(((char*)(&lAudioSampleLength))+2) = RXDataUSI;
    while (USIcompleteRX == 0);
    TX_USI();                               // receive: size byte 3
    *(((char*)(&lAudioSampleLength))+3) = RXDataUSI;
    while (USIcompleteRX == 0);
    TX_USI();                               // receive: first audio sample
    while (USIcompleteRX == 0);
    uAudioSample1 = RXDataUSI;
    TX_USI();                               // receive: second audio sample
    while (USIcompleteRX == 0);
    uAudioSample2 = RXDataUSI;

    TACCTL1 &= ~(OUTMOD_7 | OUT);           // PWM output = LOW
    PWM_PDIR |= PWM_BIT;                    // P1.2/TA1/A2 is output
    PWM_PSEL |= PWM_BIT;                    // P1.2/TA1/A2 is TA1 output
    TACCTL1 |= OUTMOD_7;                    // outpode = 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
      TX_USI();                             // receive: next audio sample
      while (USIcompleteRX == 0);
      uAudioSample1 = uAudioSample2;
      uAudioSample2 = RXDataUSI;
    }

    TACTL    &= ~MC_0;                      // Stop Timer_A
    TACCTL1  &= ~(OUTMOD_7 | OUT);          // PWM output = LOW
    PWM_POUT &= ~PWM_BIT;                   // PWM GPIO-Pin = LOW
    PWM_PDIR &= ~PWM_BIT;                   // P1.2/TA1/A2 is input
    PWM_PSEL &= ~PWM_BIT;                   // P1.2/TA1/A2 is P1.2 input

    FlashSelPOUT |= FlashSelBIT;            // SPI-Flash SELECT = HIGH
    FlashSelPOUT &= ~FlashSelBIT;           // SPI-Flash SELECT = LOW
    TXDataUSI = 0xB9;                       // 0xB9: go to Deep Power-Down
    TX_USI();                               // send instruction 0xB9
    FlashSelPOUT |= FlashSelBIT;            // SPI-Flash SELECT = HIGH
    __delay_cycles(2500);                   // keep SEL a minimum time HIGH

    AudioFileNr++;                          // point to next Audio File
    AudioFileNr &= 0x03;                    // AudioFileNr Modulo 4

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

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

//******************************************************************************
// Transmit byte with USI in SPI mode
//******************************************************************************
void TX_USI (void)
{
  USISRL = TXDataUSI;                       // init-load data
  USIcompleteRX = 0;                        // indicate transmission in progress
  USICNT = 8;                               // init-load counter
  USICTL1 |= USIIE;                         // Counter interrupt, flag remains set
}

//******************************************************************************
// 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:                                 // Vector 2: TACCR1
            iAudioSampleDifference = (int) uAudioSample2 - (int) uAudioSample1;
            if (iAudioSampleDifference > 68)
            {
              TACTL   &= ~TAIFG;            // clear overflow flag TAIFG IFG
              TACTL   |= TAIE;              // enable overflow interrupt TAIFG
              TACCTL1 &= ~CCIE;             // turn off TACCR1 IFG
            }
            switch (__even_in_range(uAvgCntr,6))
            {
              case 0: TACCR1 = (uAudioSample1
                               + uAudioSample1
                               + uAudioSample1
                               + uAudioSample2) >> 2;
                      break;

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

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

              case 6: TACCR1 = 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 4:                                 // Vector 4: TACCR2
            break;
    case 10:                                // Vector 10: TAIFG Flag
            TACCTL1 &= ~CCIFG;              // clear TACCR1 IFG
            TACCTL1 |= CCIE;                // enable TACCR1 IFG
            TACTL   &= ~TAIE;               // turn off overflow interrupt TAIFG
            break;
  }
} // __interrupt void TimerA1 (void)

//******************************************************************************
// USI interrupt service routine
//******************************************************************************
#pragma vector=USI_VECTOR
__interrupt void universal_serial_interface(void)
{
  USICTL1 &= ~USIIE;                        // Disable USI interrupts
  RXDataUSI = USISRL;                       // store received data
  USIcompleteRX = 1;                        // RX transmission result available
}

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

⌨️ 快捷键说明

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