MSP-EXP430FR5739: ADC10B Sequenz per DMA in Array ablegen

Das Beispielprogramm ruft mit 50 Hz den ADC auf welcher eine Serie an Messungen macht (Channel A1, dann A0). Der ADC triggert nach jeder Messung die DMA welche das Messergebnis abholt und in das Array ADC_Result schreibt. Das alles läuft völlig ohne CPU Interaktion.

[c]
#include „msp430fr5739.h“

unsigned int ADC_Result[2];

void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT

// Setup clock system
CSCTL0_H = 0xA5; // Password
CSCTL1 |= DCOFSEL0 + DCOFSEL1; // DCO 8 MHz
CSCTL2 = SELA_3 + SELS_3 + SELM_3; // set ACLK = SMCLK = DCO/8

// Port Setup
P1SEL0 |= BIT0; // P1.0 is input for ADC
P1SEL1 |= BIT0; // Channel A0
P1SEL1 |= BIT1; // P1.1 is input for ADC
P1SEL0 |= BIT1; // Channel A1

// Setup der DMA
DMACTL0 |= DMA0TSEL__ADC10IFG; // ADC10 interrupt soll die DMA triggern
__data16_write_addr((unsigned short)&DMA0SA,(unsigned long) &ADC10MEM0);
// DMA soll das ADC Ergebnis lesen…
__data16_write_addr((unsigned short)&DMA0DA,(unsigned long) &ADC_Result[0]);
// …und ins array ADC_Result[] schreiben
DMA0SZ = 2; // One word per transfer
DMA0CTL |= DMADT_4; // Repeated single transfer
DMA0CTL &= ~DMADSTBYTE; // DMA destination is a word
DMA0CTL &= ~DMASRCBYTE; // DMA source is a word
DMA0CTL |= DMASRCINCR_0; // Source address is unchanged (immer gleiches Register)
DMA0CTL |= DMADSTINCR_3; // Destination address is incremented (nächstes array element)
DMA0CTL &= ~DMALEVEL; // Trigger on low level (otherwise DMA is too fast)
DMA0CTL |= DMAIE; // Enable Interrupts
DMA0CTL |= DMAEN; // Enable DMA

// Setup Timer
TA0CCR0 = 20000 – 1; // PWM Period 50 Hz
TA0CCTL1 = OUTMOD_7; // CCR1 reset/set
TA0CCR1 = 2000; // CCR1 PWM duty cycle 10 %
TA0CTL = TASSEL_2 + MC_1 + TACLR; // SMCLK, up mode, clear TAR

// Setup ADC
ADC10CTL0 &= ~ADC10ENC;
ADC10CTL1 |= ADC10CONSEQ_3; // Repeat-Sequence-of-Channels Mode
ADC10CTL1 |= ADC10SHS_1; // Set PWM as trigger source
ADC10CTL1 &= ~ADC10SHP; // Bypass Sample timer
ADC10CTL2 |= ADC10RES; // 10-bit conversion results
ADC10MCTL0 |= ADC10INCH_1; // Start Sequence with Channel A1
ADC10CTL0 |= ADC10ON; // ADC on
ADC10CTL0 |= ADC10ENC; // Enable ADC conversation

_BIS_SR(GIE); // General interrupt enable

while(1) __bic_SR_register(CPUOFF); // CPU off
}

#pragma vector=DMA_VECTOR
__interrupt void DMA0_ISR (void)
{
switch(__even_in_range(DMAIV,16))
{
case 0: break; // No interrupt
case 2:
// ADC and DMA are ready, values are now stored in Array ADC_Result
__no_operation(); // Set breakpoint here
break; // DMA0IFG
case 4: break; // DMA1IFG
case 6: break; // DMA2IFG
case 8: break; // Reserved
case 10: break; // Reserved
case 12: break; // Reserved
case 14: break; // Reserved
case 16: break; // Reserved
default: break;
}
}
[/c]

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert