MSP430F169_Demo.c
上传用户:taicent
上传日期:2021-01-27
资源大小:32k
文件大小:13k
源码类别:

语音压缩

开发平台:

Visual C++

  1. /*****************************************************************************/
  2. /*   Voice Recorder Demo using IMA ADPCM compression                         */
  3. /*   using MSP430F169                                                        */
  4. /*                                                                           */
  5. /*   Texas Instruments Deutschland GmbH                                      */
  6. /*   July 2007, Christian Hernitscheck                                       */
  7. /*   Built with IAR Embedded Workbench Version 3.42A                         */
  8. /*                                                                           */
  9. /*                                                                           */
  10. /*                                                                           */
  11. /*                                                                           */ 
  12. /*   It is assumed that two push button switches are connected to the Port   */
  13. /*   Pins P2.6 and P2.7 trigger Record and Playback respectively             */
  14. /*                                                                           */
  15. /*                                                                           */
  16. /*                                                                           */
  17. /*                            MSP430F169                                     */ 
  18. /*                         _________________                                 */
  19. /*                        |              XIN|-                               */ 
  20. /*                        |                 | 32kHz                          */
  21. /*             Audio IN-->|P6.0/A0      XOUT|-                               */   
  22. /*                        |                 |                                */ 
  23. /*                        |      P6.6/A6/DAC0|-->AUDIO OUT                   */ 
  24. /*              RECORD -->|P2.6             |                                */       
  25. /*                PLAY--->|P2.7             |                                */ 
  26. /*                        |_________________|                                */
  27. /*                                                                           */
  28. /*                                                                           */
  29. /*                                                                           */
  30. /*****************************************************************************/
  31. #include "MSP430x16x.h"
  32. #include "ADPCM.h"
  33. #define SamplePrd            375       // record and playback sample period:
  34.                                        // SampleRate = 3,000,000/SamplePrd
  35.                                        // SamplePrd=375 => SampleRate=8kHz
  36. #define MemStart             0x2000    // memory range to be filled with
  37. #define MemEnd               0xfe00    // sampled data
  38. unsigned char *pMemory = (unsigned char *)MemStart;
  39.                                        // start of record memory array
  40. unsigned char TempMemory;
  41. unsigned int decodedValue;
  42. unsigned char Mode;
  43. //-----------------------------------------------------------------------------
  44. // declaration of functions
  45. void Erase(void);
  46. void Init(void);
  47. void Record(void);
  48. void Playback(void);
  49. void Delay(void);
  50. //-----------------------------------------------------------------------------
  51. // Main Program
  52. void main(void)
  53. { WDTCTL = WDTPW+WDTHOLD;  // disable Watchdog
  54.   BCSCTL1 |= 0x07;         // SMCLK=MCLK~3MHz
  55.   Mode = 0x00;
  56.   Init();
  57.   //*** power-down external hardware ***
  58.  // P2OUT &= ~0x08;          // disable audio input stage
  59.  // P2OUT |= 0x10;           // disable audio output stage
  60.   //P6OUT &= ~0x04;          // enable charge pump snooze mode
  61.   while (1)                       // repeat forever
  62.   { //P2IES |= 0xC0;                // interrupt on falling edge
  63.     //P2IFG &= ~0xc0;               // clear all button interrupt flags
  64.     //P2IE |= 0xc0; // enable interrupt for buttons
  65.    // _EINT();                      // enable interrupts
  66.     //_BIS_SR(LPM3_bits);           // enter LPM3
  67.     //--- wait for key-press event, hold CPU in low-power mode ---
  68.    // _DINT();                      // disable interrupts
  69.     //P2IE &= ~0x40;                // disable interrupts for buttons
  70.     pMemory = (unsigned char *)MemStart; // start address of data memory
  71.     ADPCM_Init();
  72.   P2DIR=0x01;
  73.     P2OUT=0X00;
  74.     //*** process key-press event ***
  75.     if (!(P2IN & 0x10))           // record button pressed?
  76.       Record();                   // yes, -> start recording
  77.     if(!(P2IN&0x20))                         // no, -> must be playback button
  78.       Playback();
  79.   }
  80. }
  81. void Init(void)
  82. {
  83.   P2DIR=0x01;
  84.     P2OUT=0X00;
  85.   //P2OUT=0x00;    // termination of unused pins
  86.   //P2DIR=0x3F;    // P2.0=LED#1, P2.1=LED#2, P2.6=Button#1, P2.7=Button#2
  87.   //P2OUT=0x00;
  88.   //P2DIR=0xFF;
  89.   //P3OUT=0x00;
  90.   //P3DIR=0xFF;
  91.   //P4OUT=0x00;
  92.   //P4DIR=0xFF;
  93.   //P5OUT=0x00;
  94.  // P5DIR=0xFF;
  95.   P6OUT=0x00;
  96.   P6DIR=0xBE;
  97.   P2IES=0xC0;
  98.   P2IE=0xC0;
  99.   P6SEL = 0xc1;   // select ADC12 A0 inp, DAC0&1 outp
  100.   P5SEL |= 0x20;  // P5.5 = SMCLK
  101. }
  102. void Record(void)
  103. { Mode = 0x01;
  104.   //*** power-up external hardware ***
  105.  // P2OUT |= 0x09;  // LED#1 & audio input stage on
  106.   //P6OUT |= 0x04;  // disable charge pump snooze mode
  107.   //*** setup ADC12 module ***
  108.   ADC12CTL0 = SHT0_7+SHT1_7+ADC12ON+REF2_5V+REFON;
  109.                                   // turn on ADC12, S&H in sample
  110.                                   // ADC12 Clock=ADC12OSC
  111.   ADC12CTL1 = SHS_0 + CONSEQ_0;   // S&H src select: ADC12SC bit
  112.                                   // single channel, single conversion
  113.   ADC12IFG = 0x00;                // clear ADC12 interrupt flag reg
  114.   ADC12CTL0 |= ENC;               // enable conversion
  115.   ADC12IE |= 0x0001;
  116.   ADC12MCTL0 = SREF_1;
  117.   Delay();                        // allow reference to settle
  118.   Delay();
  119.   //*** setup Timer_B for recording ***
  120.   TBCTL = TBSSEL1;                // use SMCLK as Timer_B source
  121.   TBR = 0;
  122.   TBCCR0 = SamplePrd;             // initialize TBCCR0
  123.   TBCCR1 = SamplePrd-1;           // trigger for conversion start (ADC12SC)
  124.   TBCCTL1 = OUTMOD_7;             // reset OUT1 on EQU1, set on EQU0
  125.   TBCCTL0 = CCIE;
  126.   //*** setup and erase Flash memory ***
  127.   // (Rem.: This time is also used to wait for the voltages getting stabilized)
  128.   FCTL2 = FWKEY + FSSEL_2 + FN0;  // clk src = SMCLK / 2 (~440KHz)
  129.   FCTL3 = FWKEY;                  // unlock Flash memory for write
  130.   Erase();                        // call Flash erase subroutine
  131.   FCTL1 = FWKEY + WRT;            // enable Flash write for recording
  132.   //*** start recording ***
  133.  // P2OUT |= 0x01;                  // LED#1 on
  134.   TBCTL |= MC0;                   // start Timer_B in UP mode
  135.                                   // (counts up to TBCL0)
  136.   //*** activate LPM during DMA recording, wake-up when finished ***
  137.   _EINT();                        // enable interrupts
  138.   _BIS_SR(LPM0);                  // enter LPM0
  139.   _DINT();                        // disable interrupts
  140.   //*** deactivate Flash memory write access ***
  141.   FCTL1 = FWKEY;                  // disable Flash write
  142.   FCTL3 = FWKEY + LOCK;           // lock Flash memory
  143.   //*** power-down MSP430 modules ***
  144.   ADC12CTL1 &= ~CONSEQ_2;         // stop conversion immidiately
  145.   ADC12CTL0 &= ~ENC;              // disable ADC12 conversion
  146.   ADC12CTL0 = 0;                  // switch off ADC12 & ref voltage
  147.   TBCTL = 0;                      // disable Timer_B
  148.   //*** power-down external hardware ***
  149.   //P2OUT &= ~0x09;                 // disable LED#1 & audio input stage
  150.  // P6OUT &= 0x04;                  // enable charge pump snooze mode
  151. }
  152. void Playback(void)
  153. { Mode = 0x02;
  154.   decodedValue=0x00;              // initial DAC12 value
  155.   //*** power-up external hardware ***
  156.  // P2OUT |= 0x02;                  // LED#2 on
  157.  // P2OUT &= ~0x10;                 // enable audio output stage
  158.  // P6OUT |= 0x04;                  // disable charge pump snooze mode
  159.   //*** setup DAC12 module ***
  160.   ADC12CTL0 = REFON + REF2_5V;    // ADC12 ref needed for DAC12
  161.   DAC12_0CTL = DAC12IR + DAC12AMP_7 + DAC12LSEL_0 + DAC12ENC;
  162.   Delay();                        // wait until voltages have stab.
  163.   Delay();                        // wait until voltages have stab.
  164.   //*** setup Timer_B for playback ***
  165.   TBCTL = TBSSEL1;                // use SMCLK as Timer_B source
  166.   TBCCR0 = SamplePrd;             // initialize TBCCR0 with sample prd
  167.   TBCCTL0 = CCIE;                 // enable interrupt
  168.   //*** start playback ***
  169.   TBCTL |= MC0;                   // start TimerB in UP mode
  170.                                   // (counts up to TBCL0)
  171.   //*** activate LPM during DMA playback, wake-up when finished ***
  172.   _EINT();                        // enable interrupts
  173.   _BIS_SR(LPM0);                  // enter LPM0
  174.   _DINT();                        // disable interrupts
  175.   //*** power-down MSP430 modules ***
  176.   TBCTL = 0;                      // disable Timer_B
  177.   ADC12CTL0 = 0;                  // switch off ADC12 ref voltage
  178.   DAC12_0CTL &= ~DAC12ENC;        // disable DAC12 conversion
  179.   DAC12_0CTL = 0;                 // switch off DAC12
  180.   //*** power-down external hardware ***
  181.   //P2OUT |= 0x10;                  // disable audio output stage
  182.  // P6OUT &= ~0x04;                 // enable charge pump snooze mode
  183.   //P2OUT &= ~0x02;                 // LED#2 off
  184. }
  185. //-----------------------------------------------------------------------------
  186. // software delay, ~100,000 CPU cycles
  187. void Delay(void)
  188. { unsigned int i;
  189.   for (i = 0; i < 0x3fff; i++);
  190. }
  191. //-----------------------------------------------------------------------------
  192. // erase Flash memory for new recording
  193. void Erase(void)
  194. { unsigned int *pMemory = (unsigned int *)MemStart;
  195.                                   // start of record memory array
  196.   while (FCTL3 & BUSY);           // loop till not busy
  197.   do
  198.   { if ((unsigned int)pMemory & 0x1000) // use bit 12 to toggle LED#1
  199.       P2OUT |= 0x01;
  200.     else
  201.       P2OUT &= ~0x01;
  202.     FCTL1 = FWKEY + ERASE;
  203.     *pMemory = 0x00;              // dummy write to activate segment erase
  204.     while (FCTL3 & BUSY);         // loop till not busy
  205.     pMemory += 0x0100;            // point to next segment
  206.   } while (pMemory < (unsigned int *)MemEnd);
  207. }
  208. //-----------------------------------------------------------------------------
  209. // Port P2 Interrupt Sevice Routine: Push-button was pressed
  210. //#pragma vector=PORT1_VECTOR
  211. //__interrupt void ISR_Port1(void)
  212. //{ P2IFG &= ~0xc0;                 // clear all button interrupt flags
  213.  // _BIC_SR_IRQ(LPM3_bits);         // exit LPM3 on reti
  214. //}
  215. //-----------------------------------------------------------------------------
  216. // Timer Interrupt Sevice Routine: Audio Sample Time for record and playback
  217. #pragma vector=TIMERB0_VECTOR
  218. __interrupt void ISR_Timer(void)
  219. { TBCCTL0 &= ~CCIFG; // clear interrupt flag
  220.   switch(Mode)
  221.   { case 0x00:
  222.     case 0x01:       // Record Mode
  223.     { ADC12CTL0 |= ADC12SC;       // start conversion
  224.       ADC12CTL0 &= ~ADC12SC;
  225.       break;
  226.     }
  227.     case 0x02:       // Playback Mode (bit 7-4 of stored data)
  228.     { DAC12_0DAT = decodedValue; // take care that the DAC register loading is
  229.                                  // done without timing variations between
  230.                                  // different ISRs
  231.       decodedValue = ADPCM_Decoder((*pMemory>>4)& 0x0F);
  232.                  // ADPCM_Decoder() execution time varies depending on the
  233.                  // ADPCM code. This is the reaosn why the value is stored in
  234.                  // a variable and during the next ISR call the DAC register
  235.                  // is loaded.
  236.       Mode=0x04;
  237.       break;
  238.     }
  239.     case 0x04:        // Playback Mode (bit 3-0 of stored data)
  240.     { DAC12_0DAT = decodedValue; // take care that the DAC register loading is
  241.                                  // done without timing variations between
  242.                                  // different ISRs
  243.       decodedValue = ADPCM_Decoder(*pMemory&0x0F);
  244.                  // ADPCM_Decoder() execution time varies depending on the
  245.                  // ADPCM code. This is the reaosn why the value is stored in
  246.                  // a variable and during the next ISR call the DAC register
  247.                  // is loaded.
  248.       pMemory=pMemory+1;
  249.       if ((unsigned int)pMemory >= (unsigned int) MemEnd)
  250.       {  P2OUT &= ~0x01;
  251.          _BIC_SR_IRQ(LPM0_bits);  // exit LPM0 on reti
  252.       }
  253.       Mode=0x02;
  254.       break;
  255.     }
  256.   }
  257. }
  258. //-----------------------------------------------------------------------------
  259. // ADC ISR: record mode only, encode and store conversion result
  260. #pragma vector=ADC_VECTOR
  261. __interrupt void ISR_ADC(void)
  262. { if (Mode == 0x01)
  263.   { TempMemory = ADPCM_Encoder(ADC12MEM0)<<4; // ADPCM code (bit 7-4)
  264.     Mode=0x00;
  265.   }
  266.   else
  267.   { TempMemory = TempMemory +ADPCM_Encoder(ADC12MEM0); // ADPCM code (bit 3-0)
  268.     *pMemory = TempMemory;
  269.     pMemory=pMemory+1;            // next byte address
  270.     Mode=0x01;
  271.   }
  272.   if ((unsigned int)pMemory >= (unsigned int) MemEnd)  // memory full?
  273.   {  TACCTL2=0x00;
  274.      ADC12CTL0=0x000;
  275.      _BIC_SR_IRQ(LPM0_bits);      // exit LPM0 on reti
  276.   }
  277. }