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

📄 exercise-7.c

📁 TI MSP430针对cap sense 按键的源码, 可实现单击或滑动键, 如IPOD上的人机接口.
💻 C
字号:
/* Exercise 7

   An extension of the simple voice recorder from exercise 6, to use DMA for the record and replay.
   The DMA code is based on the following examples:
        fet430_dma_03.c
        fet430_dma_07.c
*/
#include <stdint.h>
#include <msp430xG43x.h>

#define AUDIO_MEM_START     0x2000
#define AUDIO_MEM_END       0xFE00

void record(void)
{
    long int i;
    int16_t *ptr;

    /* Set up timer A to kick the ADC at 6.5536kHz, which will be our audio
     * sampling rate. */
    TAR = 0;
    TACCR0 = 5 - 1;
    TACCR1 = 5 - 2;
    TACCTL0 = 0;
    TACCTL1 = OUTMOD_3;
    TACTL = TACLR | MC_1 | TASSEL_1;

    /* Make the earpiece pins outputs driven to 0, to power the mic */
    P6SEL &= ~(BIT5 | BIT3);
    P6DIR |= (BIT5 | BIT3);
    P6OUT &= ~(BIT5 | BIT3);

    /* Set up the mic amp */
    /* Input 0 is the mic signal.
     * Output goes to the feedback resistor.
     * We want a general purpose amp.
     * We want DAC1 to bias the +ve input of the amp.
     * We want the amp in high performance mode. */
    P6SEL |= (BIT1 | BIT0);
    OA0CTL0 = OAN_0 | OAP_3 | OAPM_3 | OAADC1;
    OA0CTL1 = OAFC_0;
    /* Second amplifier stage */
    OA1CTL0 = OAN_2 | OAP_3 | OAPM_3 | OAADC0;              // -ve=OA1I0, +ve=DAC1
    OA1CTL1 = OAFC_6 | OAFBR_4;

    /* Must disable conversion while reprogramming the ADC */
    ADC12CTL0 &= ~ENC;
    ADC12CTL0 = ADC12ON | SHT0_4 | REFON | REF2_5V;         // Turn on the ADC12, and set the sampling time
    ADC12CTL1 = SHP | SHS_1 | CONSEQ_2;                     // Use sampling timer, single sample repeating, TA1 trigger
    ADC12MCTL0 = INCH_13 | SREF_1;                          // ref += Vref, channel = A13 = OA1
    ADC12IE = 0;
    ADC12IFG = 0x00;

    /* Configure DAC 1 to provide bias for the mic amplifier */
    P6SEL |= BIT7;
    DAC12_1CTL = DAC12CALON | DAC12IR | DAC12AMP_7 | DAC12ENC;
    DAC12_1DAT = 0x800;

    /* Based on example fet430_dma_07.c - getting ADC data to flash
       Change the memory address and the transfer length. */
    DMA0SA = (int) &ADC12MEM0;                              // Src address = ADC12 module
    DMA0DA = (int) AUDIO_MEM_START;                         // Dst address = Flash memory
    DMA0SZ = (AUDIO_MEM_END - AUDIO_MEM_START) >> 1;        // Size in words
    DMACTL0 = DMA0TSEL_6;                                   // ADC12IFGx triggers DMA0
    DMACTL1 = DMAONFETCH;                                   // Required for proper Flash write
    DMA0CTL = DMADSTINCR_3 | DMAIE | DMAEN;                 // Config

    for (ptr = (int16_t *) AUDIO_MEM_START;  ptr != (int16_t *) AUDIO_MEM_END;  ptr += 0x100)
    {
        FCTL3 = FWKEY;                  /* Lock = 0 */
        FCTL1 = FWKEY | ERASE;
        *ptr = 0;                       /* Erase flash segment */
        FCTL1 = FWKEY;                  /* Erase, write = 0 */
        FCTL3 = FWKEY | LOCK;
    }

    /* Set the flash clock to a sensible value for the DMA writes to work properly */
    FCTL2 = FWKEY | FSSEL_2 | 23;      /* Clk src = SMCLK / 24 (~350KHz) */

    /* Wait for the mic amp to settle */
    for (i = 150000;  i > 0;  i--)
        _NOP();

    /* Unlock the flash memory for writing */
    FCTL3 = FWKEY;
    FCTL1 = FWKEY | WRT;

    /* Set the recording off, and wait in LPM0 for it to complete */
    _EINT();
    P1OUT |= BIT0;                      /* Turn on the LED */
    ADC12CTL0 |= ENC;
    _BIS_SR(LPM0_bits);
    ADC12CTL0 &= ~ENC;
    P1OUT &= ~BIT0;                     /* Turn off the LED */

    /* Lock the flash memory for writing */
    FCTL1 = FWKEY;
    FCTL3 = FWKEY | LOCK;
    _DINT();
}

void play(void)
{
    /* Ensure the ADC12 is not running, but is providing the reference
       voltage for the DAC12. */
    ADC12CTL0 &= ~ENC;
    ADC12CTL0 = ADC12ON | REFON | REF2_5V;
    ADC12IE = 0;
    ADC12CTL0 |= ENC;

    /* Set up timer A to kick the DAC at 6.5536kHz, which will be our audio
       sampling rate. */
    TAR = 0;
    TACCR0 = 5 - 1;
    TACCR1 = 5 - 2;
    TACCTL0 = 0;
    TACCTL1 = OUTMOD_3;
    TACTL = TACLR | MC_1 | TASSEL_1;

    /* Make a differential drive for the earpiece */
    P6SEL |= (BIT5 | BIT3);
    /* Chain two amps to make an inverting buffer with a gain of one */
    OA0CTL0 = OAP_2 | OAPM_3;
    OA0CTL1 = OAFC_1;
    OA1CTL0 = OAN_2 | OAP_3 | OAPM_3 | OAADC1;
    OA1CTL1 = OAFC_6 | OAFBR_2;
    /* Use the third amp as a non-inverting buffer with a gain of one */
    OA2CTL0 = OAP_2 | OAPM_3 | OAADC1;
    OA2CTL1 = OAFC_1;

    /* Configure DAC0 to provide the audio signal for the earpiece amp.
       The data will be latched by TACCR1 */
    DAC12_0CTL = DAC12CALON | DAC12IR | DAC12AMP_7 | DAC12ENC | DAC12LSEL_2;
    DAC12_0DAT = 0x800;
    /* Configure DAC1 to provide a bias signal for the inverting PGA */
    DAC12_1CTL = DAC12CALON | DAC12IR | DAC12AMP_7 | DAC12ENC;
    DAC12_1DAT = 0x800;

    /* Based on example fet430_dma_03.c - feeding a string to a USART port.
       Changed to use TACCR0 instead of TACCR2
       Changed to use word-to-word operations
       Changed to use the relevant memory and device addresses */
    DMA0SA = (int) AUDIO_MEM_START;                         // Source audio address
    DMA0DA = (int) &DAC12_0DAT;                             // Destination single address
    DMA0SZ = (AUDIO_MEM_END - AUDIO_MEM_START) >> 1;
    DMACTL0 = DMA0TSEL_7;                                   // TACCR0 is the trigger
    DMA0CTL = DMADT_4 | DMASRCINCR_3 | DMASWDW | DMAEN;     // Rpt, inc src

    /* Don't bother turning on interrupts - we won't get any */
    for (;;)
    {
        _BIS_SR(LPM0_bits);
        _NOP();
    }
}

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

    SCFI0 = FN_3 | FLLD_4;
    FLL_CTL0 = XCAP18PF;            // set load capacitance for xtal
    SCFQCTL = 64 - 1;               // 256*32768Hz = 8.388608MHz
    FLL_CTL0 |= DCOPLUS;

    P1DIR = 0xE7;                   // All P1.x outputs
    P1OUT = 0;                      // All P1.x reset
    P2DIR = 0x00;                   // All P2.x outputs
    P2OUT = 0;                      // All P2.x reset
    P3DIR = 0xFF;                   // All P3.x outputs
    P3OUT = 0;                      // All P3.x reset
    P4DIR = 0xFF;                   // All P4.x outputs
    P4OUT = 0;                      // All P4.x reset
    P5DIR = 0xFF;                   // All P5.x outputs
    P5OUT = 0;                      // All P5.x reset
    P6DIR = 0xFF;                   // All P6.x outputs
    P6OUT = 0;                      // All P6.x reset

    /* Configure UART0 */
    UCTL0 = CHAR;                   /* 8-bit character */
    UTCTL0 = SSEL1;                 /* UCLK = SMCLK */
    UBR00 = 72;                     /* 115200 bps, based on the 256*32768Hz clock */
    UBR10 = 0;
    UMCTL0 = 0x7F;
    P2SEL |= (BIT5 | BIT4);
    U0ME |= UTXE0;                  /* Enable only USART0 TXD */

    record();

    for (;;)
        play();
    _NOP();
}

#pragma vector=DAC12_DMA_VECTOR
__interrupt void dma_interrupt(void)
{
    DMA0CTL &= ~DMAIFG;             /* Clear DMA0 interrupt flag */
    _BIC_SR_IRQ(LPM0_bits);
}

⌨️ 快捷键说明

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