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

📄 voice_recorder.c

📁 该程序在IAR Embedded Workbench for MSP4303.41A环境下编写
💻 C
📖 第 1 页 / 共 2 页
字号:
  __data16_write_addr((unsigned short)&DMA2DA, Memstart2);
                                            // Dst address = Flash memory,
                                            // Use intrinsic to ensure single-
                                            // access to control register
  DMA2SZ = (Memend2 - Memstart2) >> 1;      // Size in words

  // Setup and erase Flash memory
  // (Rem.: This time is also used to wait for
  //        the voltages getting stabilized)
  FCTL2 = FWKEY + FSSEL1 + FN1;             // SMCLK/3 = ~333kHz
  FCTL3 = FWKEY;                            // Unlock Flash memory for write
  Erase();                                  // Call Flash erase subroutine
  FCTL1 = FWKEY + WRT;                      // Enable Flash write for recording

  // Update LCD
  LCDM8 = SEG_A + SEG_B + SEG_C + SEG_E + SEG_F + SEG_G;  // "R"
  LCDM7 = SEG_A + SEG_D + SEG_E + SEG_F + SEG_G;          // "E"
  LCDM6 = SEG_A + SEG_D + SEG_E + SEG_F;                  // "C"
  LCDM5 = 0x00;                             // " "
  LCDM4 = 0x00;                             // " "

  // Start recording
  P1OUT |= 0x01;                            // LED#4 on
  TBCTL |= MC0;                             // Start Timer_B in UP mode
                                            // (counts up to TBCL0)

  // Activate LPM during DMA recording, wake-up when finished
  __bis_SR_register(LPM0_bits + GIE);       // Enable interrupts, enter LPM0
  __disable_interrupt();                    // Disable interrupts

  // Deactivate Flash memory write access
  FCTL1 = FWKEY;                            // Disable Flash write
  FCTL3 = FWKEY + LOCK;                     // Lock Flash memory

  // Power-down MSP430 modules
  ADC12CTL1 &= ~CONSEQ_2;                   // Stop conversion immediately
  ADC12CTL0 &= ~ENC;                        // disable ADC12 conversion
  ADC12CTL0 = 0;                            // Switch off ADC12 & ref voltage
  TBCTL = 0;                                // Disable Timer_B
  OA0CTL0 = 0;                              // Disable OA0

  P2OUT &= ~0x08;                           // Mic supply off
  P5OUT &= ~0x02;                           // LED#4 off

  // Update LCD
  LCDM8 = 0x00;                             // " "
  LCDM7 = 0x00;                             // " "
  LCDM6 = 0x00;                             // " "
}
//------------------------------------------------------------------------------
// Playback audio data stored in Flash memory using the integrated
// DMA controller and DAC12 module.
//------------------------------------------------------------------------------
void Playback(void)
{
  volatile unsigned int i;

  // Update LCD
  LCDM8 = SEG_A + SEG_B + SEG_E + SEG_F + SEG_G;          // "P"
  LCDM7 = SEG_D + SEG_E + SEG_F;                          // "L"
  LCDM6 = SEG_A + SEG_B + SEG_C + SEG_E + SEG_F + SEG_G;  // "A"
  LCDM5 = SEG_B + SEG_C + SEG_F + SEG_G;                  // "Y"
  LCDM4 = 0x00;                             // " "

  // Power-up external hardware
  P5OUT |= 0x02;                            // LED#4 on

  // Setup DAC12_0 = Offset for OA2 gain state
  DAC12_0CTL = DAC12IR + DAC12AMP_2 + DAC12ENC + DAC12OPS;
  DAC12_0DAT = 0x057F;                      // Offset level

  // Setup OA1 = S-K Output filter for DAC12_1
  // OA1+ = P6.4/OA1I0
  // OA1- = R_Bottom (internal)
  // OA1OUT = P6.3/A3/OA1O, R_Bottom (internal)
  OA1CTL0 = OAPM_3 + OAADC1;                // Select inputs, power mode
  OA1CTL1 = OAFC_1 + OARRIP;                // Unity Gain, rail-to-rail inputs

  // Setup OA2 = Gain stage
  // OA2+ = DAC12_0OUT
  // OA2- = OA1OUT
  // OA2OUT = P6.5/OA2O
  OA2CTL0 = OAN_2 + OAP_2 + OAPM_3 + OAADC1;// Select inputs, power mode
  OA2CTL1 = OAFC_6 + OAFBR_2 + OARRIP;      // Invert. PGA, OAFBRx sets gain

  // Setup DAC12_1 module
  ADC12CTL0 = REFON + REF2_5V;              // ADC12 ref needed for DAC12s
  DAC12_1CTL = DAC12IR + DAC12AMP_7 + DAC12LSEL_3 + DAC12ENC;
                                            // Configure DAC12
                                            // latch data on pos. Timer_B.OUT2

  for (i = 0; i < 0x3fff; i++);             // Wait until voltages have stab.

  // Steps executed for automated Flash-to-DAC12 transfer
  // everything without CPU intervention
  //
  // (1) Timer_B.CCIFG2 triggers DMA transfer
  // (2) Timer_B.OUT2 triggers DAC12 data latch
  // (3) Goto (1) until DMA0SZ = 0

  // Setup Timer_B for playback
  TBCTL = TBSSEL_2;                         // Use SMCLK as Timer_B source
  TBCCR0 = SamplePrd;                       // Initialize TBCCR0 w/ sample prd
  TBCCR2 = SamplePrd >> 1;                  // EQU2 will trigger DMA
  TBCCTL2 = OUTMOD_7;                       // Reset OUT2 on EQU2, set on EQU0

  // Setup the DMA controller
  //
  // To allow for playback from the whole device memory without CPU
  // interaction, all three DMA channels are used in a daisy-chained fashion.
  //
  // (1) DMA0 reads one block of MSP430 Flash memory
  // (2) After this, DMA1 loads the control register of DMA2
  // (3) DMA2 reads another block of MSP430 Flash memory

  // Configure DMA triggers first
  DMACTL0 = DMA2TSEL_2 +                    // Timer_B.CCIFG2 triggers DMA2
            DMA1TSEL_14 +                   // DMA0IFG triggers DMA1
            DMA0TSEL_2;                     // Timer_B.CCIFG2 triggers DMA0

  // Setup DMA0 for playback from first memory block
  DMA0SA = Memstart;                        // Src address = Flash memory
  DMA0DA = (unsigned int)&DAC12_1DAT;       // Dst address = DAC12 module
  DMA0SZ = (Memend - Memstart) >> 1;        // DMA block size
  DMA0CTL = DMASRCINCR1 + DMASRCINCR0 + DMAEN;
                                            // Single transfer,
                                            // increment source address,
                                            // leave dest. address unchanged,
                                            // src and dst are words size,
                                            // edge sensitive DMA trigger,
                                            // enable DMA

  // Setup DMA1 for activating DMA2
  DMA1SA = (unsigned int)&DMA2CTL_Const_P;  // Src address = contents to load
  DMA1DA = (unsigned int)&DMA2CTL;          // Dst address = into DMA2CTL
  DMA1SZ = 1;                               // 1 Transfer
  DMA1CTL = DMAEN;                          // Single transfer, enable DMA

  // Setup DMA2 for playback from second memory block
  __data16_write_addr((unsigned short)&DMA2SA, Memstart2);
                                            // Src address = Flash memory
                                            // Use intrinsic to ensure single-
                                            // access to control register
  DMA2DA = (unsigned int)&DAC12_1DAT;       // Dst address = DAC12 module
  DMA2SZ = (Memend2 - Memstart2) >> 1;      // DMA block size

  // Start playback
  TBCTL |= MC0;                             // Start Timer_B in UP mode
                                            // (counts up to TBCCR0)

  // Activate LPM during DMA playback, wake-up when finished
  __bis_SR_register(LPM0_bits + GIE);       // Enable interrupts, enter LPM0
  __disable_interrupt();                    // Disable interrupts

  // Power-down MSP430 modules
  TBCTL = 0;                                // Disable Timer_B
  ADC12CTL0 = 0;                            // Switch off ADC12 ref voltage
  DAC12_0CTL &= ~DAC12ENC;                  // Disable DAC12 conversion
  DAC12_0CTL = 0;                           // Switch off DAC12
  DAC12_1CTL &= ~DAC12ENC;                  // Disable DAC12 conversion
  DAC12_1CTL = 0;                           // Switch off DAC12
  OA1CTL0 = 0;                              // Disable OA1
  OA2CTL0 = 0;                              // Disable OA2

  P5OUT &= ~0x02;                           // LED#4 off

  // Update LCD
  LCDM8 = 0x00;                             // " "
  LCDM7 = 0x00;                             // " "
  LCDM6 = 0x00;                             // " "
  LCDM5 = 0x00;                             // " "
}
//------------------------------------------------------------------------------
// Erase Flash memory for new recording
//------------------------------------------------------------------------------
void Erase(void)
{
  unsigned int Ptr = Memstart;              // Start of record memory array
  unsigned long FarPtr = Memstart2;

  // Update LCD
  LCDM8 = SEG_A + SEG_D + SEG_E + SEG_F + SEG_G;          // "E"
  LCDM7 = SEG_E + SEG_G;                                  // "R"
  LCDM6 = SEG_A + SEG_B + SEG_C + SEG_E + SEG_F + SEG_G;  // "A"
  LCDM5 = SEG_A + SEG_C + SEG_D + SEG_F + SEG_G;          // "S"
  LCDM4 = SEG_A + SEG_D + SEG_E + SEG_F + SEG_G;          // "E"

  // Erase memory block from 'Memstart' to 'Memend'
  do
  {
    if (Ptr & 0x1000)                       // Use bit 12 to toggle LED#4
      P5OUT |= 0x02;
    else
      P5OUT &= ~0x02;

    FCTL1 = FWKEY + ERASE;
    *(unsigned char *)Ptr = 0x00;           // Dummy write to activate
                                            // segment erase
    Ptr += 0x0200;                          // Point to next segment
  } while (Ptr < Memend);

  // Erase memory block from 'Memstart2' to 'Memend2'
  do
  {
    if (FarPtr & 0x1000)                    // Use bit 12 to toggle LED#4
      P5OUT |= 0x02;
    else
      P5OUT &= ~0x02;

    FCTL1 = FWKEY + ERASE;
    __data20_write_char(FarPtr, 0x00);      // Dummy write to activate
                                            // segment erase
    FarPtr += 0x0200;                       // Point to next segment
  } while (FarPtr < Memend2);
}
//------------------------------------------------------------------------------
// PORT1 interrupt handler
//------------------------------------------------------------------------------
#pragma vector=PORT1_VECTOR
__interrupt void Port1_ISR (void)
{
  P1IE &= ~0x03;                            // Disable button interrupts
  __bic_SR_register_on_exit(LPM4_bits);     // Exit LPM4 on reti to
                                            // Activate voice recorder
}
//------------------------------------------------------------------------------
// DMA interrupt handler
//------------------------------------------------------------------------------
#pragma vector=DMA_VECTOR
__interrupt void DMA_ISR(void)
{
  DMA2CTL &= ~DMAIFG;                       // Clear DMA2 interrupt flag
  __bic_SR_register_on_exit(LPM0_bits);     // Exit LPM0 on reti
}
//------------------------------------------------------------------------------

⌨️ 快捷键说明

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