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

📄 voice_recorder.c

📁 该程序在IAR Embedded Workbench for MSP4303.41A环境下编写
💻 C
📖 第 1 页 / 共 2 页
字号:
//******************************************************************************
//  MSP430FG4618/F2013 Experimenter's Board - Voice Recorder Demo
//
//  This software demonstrates voice recording and playback using an
//  MSP430FG4618 MCU. Audio is recorded and stored using in-system self-
//  programming into Flash memory until the entire device memory is
//  filled with audio data. Both recording and playback are implemented
//  using the DMA controller - allowing the CPU to be switched off (LPM0)
//  during this entire process.
//
//  ACLK = 32.768kHz, MCLK = SMCLK = DCO = default FLL = 1.048576MHz
//
//                             MSP430FG4618
//                           ------------------
//                       /|\|               XIN|-
//                        | |                  | 32kHz
//                        --|RST           XOUT|-
//                          |                  |
//              Audio Out<--|P6.5/OA2O     P5.1|-->LED
//    Sallen-Key         <--|P6.7/DAC1         |
//    Low-Pass Filter    <--|P6.3/OA1O       S4|-->  +-------------+
//    Circuitry          -->|P6.4/OA1I0     ...|-->  | LCD DISPLAY |
//                          |               S25|-->  +-------------+
//                VCC_Mic<--|P2.3              |
//    Microphone         -->|P6.0/OA0I0    P1.0|<--SW1 (Record Button)
//    Circuitry          -->|P6.2/OA0I1    P1.1|<--SW2 (Playback Button)
//                       <--|P6.1/OA0O         |
//
//    NOTE: Refer to the MSP430FG4618/F2013 Experimenter's Board schematic
//          for details on the external circuitry.
//
//  A. Dannenberg
//  Texas Instruments Inc.
//  Ver 1.00 - October 2006
//  Built with IAR Embedded Workbench Version: 3.42A
//******************************************************************************
#include "msp430xG46x.h"
//------------------------------------------------------------------------------
// Voice-recorder memory definitions
//
// Two memory ranges are defined for voice recording. The MSP430FG4618 device
// memory is split into to regions as the device's interrupt vectors are
// located in the middle of the MSP430FG4618 Flash memory and must not be
// overwritten.
//
// ATTN: Care must be taken not to conflict with memory used by the program
//       code. Also both addresses need to be integer multipliers of 0x0200
//       due to the Flash memory segmenting.
//------------------------------------------------------------------------------
#define Memstart             0x6000         // Memory range to be filled with
#define Memend               0xfc00         // sampled data for voice recorder

#define Memstart2            0x10000        // Memory range to be filled with
#define Memend2              0x20000        // sampled data for voice recorder

#define SamplePrd            118            // Record&playback sample period
                                            // SampleR = 1MHz / SamplePrd
//------------------------------------------------------------------------------
// LCD segment definitions
//------------------------------------------------------------------------------
#define SEG_A                0x01
#define SEG_B                0x02
#define SEG_C                0x04
#define SEG_D                0x08
#define SEG_E                0x40
#define SEG_F                0x10
#define SEG_G                0x20
#define SEG_H                0x80
//------------------------------------------------------------------------------
// The following two variables contain the control register settings for DMA2
// for the record and playback. DMA1 is used to transfer these control register
// values into the control register of DMA2 to start the DMA2 operation.
//
// Note that the value for record is kept in RAM to allow accessing it while
// a Flash write operation is pending. This is not needed for playback.
// Also, the modifier '__root' is used to prevent any compiler optimization.
//------------------------------------------------------------------------------
__root unsigned int DMA2CTL_Const_R = DMADSTINCR_3 + DMAEN + DMAIE;
                                            // Single transfer,
                                            // increment dest. address,
                                            // leave source address unchanged,
                                            // src and dst are words size,
                                            // edge sensitive DMA trigger,
                                            // enable DMA, enable DMA int

__root const unsigned int DMA2CTL_Const_P = DMASRCINCR_3 + DMAEN + DMAIE;
                                            // Single transfer,
                                            // leave dest. address unchanged,
                                            // increment source address,
                                            // src and dst are words size,
                                            // edge sensitive DMA trigger,
                                            // enable DMA, enable DMA int
//------------------------------------------------------------------------------
// Function prototypes
//------------------------------------------------------------------------------
void Record(void);
void Playback(void);
void Erase(void);
//------------------------------------------------------------------------------
void main(void)
{
  volatile unsigned int i;

  // WDT+ & LFXT1
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  FLL_CTL0 |= XCAP14PF;                     // Configure load caps

  // LFXT1 startup delay
  do
  {
    IFG1 &= ~OFIFG;                         // Clear OSCFault flag
    for (i = 0x47FF; i > 0; i--);           // Time for flag to set
  }
  while (IFG1 & OFIFG);                     // OSCFault flag still set?

  // Ports
  P1OUT = 0;                                // All P1.x reset
  P1IE = 0x03;                              // P1.0, P1.1 Interrupt enabled
  P1IES = 0x03;                             // P1.0, P1.1 hi/low edge
  P1DIR = 0xFC;                             // P1.0/1 = input (switches)
  P2OUT = 0;                                // All P2.x reset
  P2DIR = 0xDF;                             // UCA0RXD = inp
  P3OUT = 0x20;                             // All P3.x reset (3.5 = buzzer)
  P3DIR = 0xF9;                             // I2C pins = inp
  P4OUT = 0;                                // All P4.x reset
  P4DIR = 0xFF;                             // All P4.x outputs
  P5OUT = 0;                                // All P5.x reset
  P5SEL = 0x1C;                             // P5.2/3/4 = LCD COM lines
  P5DIR = 0xFF;                             // All P5.x outputs
  P6OUT = 0;                                // All P6.x reset
  P6SEL = 0xBF;                             // All but P6.6 analog funct.
  P6DIR = 0xFF;                             // All P6.x outputs
  P7OUT = 0;                                // All P7.x reset
  P7DIR = 0xFF;                             // All P7.x outputs
  P8OUT = 0;                                // All P8.x reset
  P8DIR = 0xFF;                             // All P8.x outputs
  P9OUT = 0;                                // All P9.x reset
  P9DIR = 0xFF;                             // All P9.x outputs
  P10OUT = 0;                               // All P10.x reset
  P10DIR = 0xFF;                            // All P10.x outputs

  // LCD_A
  for (i = 19; i > 0; i--) LCDMEM[i] = 0;   // Clear LCD
  LCDACTL = LCDON + LCD4MUX + LCDFREQ_128;  // 4mux LCD, ACLK/128
  LCDAPCTL0 = 0x7E;                         // Segments 4-27

  while (1)                                 // Repeat forever
  {
    P1IFG &= ~0x03;                         // Clear pending button interrupts
    P1IE |= 0x03;                           // Enable interrupts for buttons

    // Wait for event, hold CPU in low-power mode 4
    __bis_SR_register(LPM4_bits + GIE);
    __disable_interrupt();

    // Process key-press event
    if (P1IFG & 0x02)                       // Record button SW2 pressed?
      Record();
    else if (P1IFG & 0x01)                  // Playback button SW1 pressed?
      Playback();
  }
}
//------------------------------------------------------------------------------
// Record audio data and store into Flash memory using the ADC12 module and
// the integrated DMA controller.
//------------------------------------------------------------------------------
void Record(void)
{
  // Power-up external hardware
  P5OUT |= 0x02;                            // LED#4 on
  P2OUT |= 0x08;                            // Mic supply on

  // Setup OA0 = Microphone pre-amplifier
  // OA0+ = P6.2/OA0I1
  // OA0- = P6.0/OA0I0
  // OA0OUT = P6.1/OA0O, A1 (internal)
  OA0CTL0 = OAP_1 + OAPM_3;                 // Select inputs, power mode
  OA0CTL1 = OARRIP;                         // General purp., rail-to-rail inp.

  // Setup ADC12 module
  ADC12CTL0 = ADC12ON;                      // Turn on ADC12, S&H in sample
                                            // ADC12 Clock=ADC12OSC
  ADC12CTL1 = SHS_3 + CONSEQ_2;             // S&H src select: Timer_B.OUT1,
                                            // rep. single channel
  ADC12IFG = 0x00;                          // Clear ADC12 interrupt flag reg
  ADC12MCTL0 = 0x0001;                      // Input channel A1
  ADC12CTL0 |= ENC;                         // Enable conversion

  // Steps executed for automated ADC12-to-Flash transfer
  // everything without CPU intervention
  //
  // (1) Timer_B.OUT1 triggers ADC12 conversion
  // (2) ADC12IFGx triggers DMA transfer
  // (3) Goto (1) until DMA0SZ = 0

  // Setup Timer_B for recording
  TBCTL = TBSSEL_2;                         // Use SMCLK as Timer_B source
  TBR = 0;
  TBCCR0 = SamplePrd;                       // Initialize TBCCR0
  TBCCR1 = SamplePrd - 20;                  // Trigger for ADC12 SC
  TBCCTL1 = OUTMOD_7;                       // Reset OUT1 on EQU1, set on EQU0

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

  // Configure DMA triggers first
  DMACTL0 = DMA2TSEL_6 +                    // ADC12IFGx triggers DMA2
            DMA1TSEL_14 +                   // DMA0IFG triggers DMA1
            DMA0TSEL_6;                     // ADC12IFGx triggers DMA0

  // Setup DMA0 for recording to first memory block
  DMA0SA = (unsigned int)&ADC12MEM0;        // Src address = ADC12 module
  DMA0DA = Memstart;                        // Dst address = Flash memory
  DMA0SZ = (Memend - Memstart) >> 1;        // Size in words
  DMA0CTL = DMADSTINCR1 + DMADSTINCR0 + DMAEN;
                                            // Single transfer,
                                            // increment dest. address,
                                            // leave source address unchanged,
                                            // src and dst are words size,
                                            // edge sensitive DMA trigger,
                                            // enable DMA

  // Setup DMA1 for activating DMA2
  DMA1SA = (unsigned int)&DMA2CTL_Const_R;  // 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 recording to second memory block
  DMA2SA = (unsigned int)&ADC12MEM0;        // Src address = ADC12 module

⌨️ 快捷键说明

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