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

📄 exercise-6.c

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

    A simple voice recorder. It records samples from the ADC12 into all the spare flash memory.
    It then repeatedly replays this, using the DAC12. Constructed from elements of examples:
*/
#include <stdint.h>
#include <msp430xG43x.h>

#define AUDIO_MEM_START     0x2000
#define AUDIO_MEM_END       0xFE00

int16_t *ptr;

void record(void)
{
    long int i;

    /* 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 = BIT0;
    ADC12IFG = 0x00;

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

    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;
    }

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

    /* Set the recording off, and wait in LPM0 for it to complete */
    _EINT();
    P1OUT |= BIT0;                      /* Turn on the LED */
    ADC12CTL0 |= ENC;
    ptr = (int16_t *) AUDIO_MEM_START;
    for (;;)
    {
        _BIS_SR(LPM0_bits);
        _NOP();
        if (ptr >= (int16_t *) AUDIO_MEM_END)
            break;
    }
    ADC12CTL0 &= ~ENC;
    P1OUT &= ~BIT0;                     /* Turn off the LED */
    _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 = CCIE;
    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;

    _EINT();
    ptr = (int16_t *) AUDIO_MEM_START;
    for (;;)
    {
        _BIS_SR(LPM0_bits);
        _NOP();
        //if (ptr >= (int16_t *) AUDIO_MEM_END)
        //    break;
    }
    _DINT();
}

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=ADC_VECTOR
__interrupt void adc_interrupt(void)
{
    int16_t val;

    val = ADC12MEM0;

    if (ptr < (int16_t *) AUDIO_MEM_END)
    {
        FCTL3 = FWKEY;                  /* Lock = 0 */
        FCTL1 = FWKEY | WRT;
        *ptr++ = val;                   /* Write to the flash */
        FCTL1 = FWKEY;                  /* Erase, write = 0 */
        FCTL3 = FWKEY | LOCK;

        val >>= 4;
        TXBUF0 = val;
    }
    else
    {
        _BIC_SR_IRQ(LPM0_bits);
    }
}

#pragma vector=TIMERA0_VECTOR
__interrupt void timera_interrupt(void)
{
    int16_t val;

    if (ptr >= (int16_t *) AUDIO_MEM_END)
        ptr = (int16_t *) AUDIO_MEM_START;
    if (ptr < (int16_t *) AUDIO_MEM_END)
    {
        val = *ptr++;
        DAC12_0DAT = val;

        val >>= 4;
        TXBUF0 = val;
    }
    else
    {
        _BIC_SR_IRQ(LPM0_bits);
    }
}

⌨️ 快捷键说明

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