Forum: Mikrocontroller und Digitale Elektronik dsPIC ADC scanning through


von gast (Gast)


Lesenswert?

Hallo,
ich bin dabei, den ADC meines dsPIC33F in Betrieb zu nehmen. Ich möchte 
5 channels (AIN0-AIN4) sequentiell im 12-bit mode durchscannen und 
mittels DMA die Resultate abspeichern. Dazu habe ich den example code 
16-4 aus dem 33F manual 
(http://ww1.microchip.com/downloads/en/DeviceDoc/70183A.pdf) genommen 
und einige Anpassungen gemacht, da dieser Code dort nur für 4 channels 
(AIN0-AIN3) ist. Meine Anpasssungen sind folgende:

- AD1CON1bits.FORM = 0;
- AD1CON1bits.AD12B = 1;
- AD1CSSL = 0x001F;
- AD1CON2bits.SMPI = 4;
- DMA0CNT = 39;

Nun ja, irgendwie funktioniert mein Code leider nicht. Wenn ich aber nur 
4 channels scanne, dann gehts einwandfrei.

vielen dank für die Hilfe!

1
/*==========================================================================================
2
ADC Initialization for Channel Scan
3
===========================================================================================*/
4
void adcInit(void){
5
initDma0();
6
7
AD1CON1bits.FORM = 0; // Data Output Format: Signed Fraction (Q15
8
format)
9
AD1CON1bits.SSRC = 2; // Sample Clock Source: GP Timer starts conversion
10
AD1CON1bits.ASAM = 1; // ADC Sample Control: Sampling begins immediately
11
after conversion
12
AD1CON1bits.AD12B = 1; // 12-bit ADC operation
13
AD1CON1bits.SIMSAM = 0; // Samples multiple channels individually in
14
sequence
15
AD1CON2bits.BUFM = 0;
16
AD1CON2bits.CSCNA = 1; // Scan Input Selections for CH0+ during Sample A
17
bit
18
AD1CON2bits.CHPS = 0; // Converts CH0
19
AD1CON3bits.ADRC = 0; // ADC Clock is derived from Systems Clock
20
AD1CON3bits.ADCS = 63; // ADC Conversion Clock
21
//AD1CHS0: A/D Input Select Register
22
AD1CHS0bits.CH0SA = 0; // MUXA +ve input selection (AIN0) for CH0
23
AD1CHS0bits.CH0NA = 0; // MUXA -ve input selection (Vref-) for CH0
24
25
//AD1CHS123: A/D Input Select Register
26
AD1CHS123bits.CH123SA = 0; // MUXA +ve input selection (AIN0) for CH1
27
AD1CHS123bits.CH123NA = 0; // MUXA -ve input selection (Vref-) for CH1
28
//AD1CSSL: A/D Input Scan Selection Register
29
AD1CSSL = 0x001F; // Scan AIN0, AIN1, AIN2, AIN3, AIN4 inputs
30
AD1CON1bits.ADDMABM = 0; // DMA buffers are built in scatter/gather mode
31
AD1CON2bits.SMPI = 4; // 5 ADC buffers
32
AD1CON4bits.DMABL = 3; // Each buffer contains 8 words
33
IFS0bits.AD1IF = 0; // Clear the A/D interrupt flag bit
34
IEC0bits.AD1IE = 0; // Do Not Enable A/D interrupt
35
AD1CON1bits.ADON = 1; // Turn on the A/D converter
36
initTmr3();
37
}
38
/*======================================================================================
39
Timer 3 is setup to time-out every 125 microseconds (8Khz Rate). As a
40
result, the module
41
will stop sampling and trigger a conversion on every Timer3 time-out,
42
i.e., Ts=125us.
43
=======================================================================================*/
44
void initTmr3(void)
45
{
46
TMR3 = 0x0000;
47
PR3 = 4999; // Trigger ADC1 every 125usec
48
IFS0bits.T3IF = 0; // Clear Timer 3 interrupt
49
IEC0bits.T3IE = 0; // Disable Timer 3 interrupt
50
T3CONbits.TON = 1; //Start Timer 3
51
}
52
53
// Linker will allocate these buffers from the bottom of DMA RAM.
54
struct
55
{
56
unsigned int Adc1Ch0[8];
57
unsigned int Adc1Ch1[8];
58
unsigned int Adc1Ch2[8];
59
unsigned int Adc1Ch3[8];
60
unsigned int Adc1Ch4[8];
61
} BufferA __attribute__((space(dma)));
62
63
struct
64
{
65
unsigned int Adc1Ch0[8];
66
unsigned int Adc1Ch1[8];
67
unsigned int Adc1Ch2[8];
68
unsigned int Adc1Ch3[8];
69
unsigned int Adc1Ch4[8];
70
} BufferB __attribute__((space(dma)));
71
// DMA0 configuration
72
// Direction: Read from peripheral address 0-x300 (ADC1BUF0) and write
73
to DMA RAM
74
// AMODE: Peripheral Indirect Addressing Mode
75
// MODE: Continuous, Ping-Pong Mode
76
// IRQ: ADC Interrupt
77
78
void initDma0(void)
79
{
80
DMA0CONbits.AMODE = 2; // Configure DMA for Peripheral indirect mode
81
DMA0CONbits.MODE = 2; // Configure DMA for Continuous Ping-Pong mode
82
DMA0PAD = 0x0300; // Point DMA to ADC1BUF0
83
DMA0CNT = 39; // 40 DMA request (4 buffers, each with 8 words)
84
DMA0REQ = 13; // Select ADC1 as DMA Request source
85
DMA0STA = __builtin_dmaoffset(&BufferA);
86
DMA0STB = __builtin_dmaoffset(&BufferB);
87
IFS0bits.DMA0IF = 0; //Clear the DMA interrupt flag bit
88
IEC0bits.DMA0IE = 1; //Set the DMA interrupt enable bit
89
DMA0CONbits.CHEN=1; // Enable DMA
90
}
91
92
/*========================================================================================
93
_DMA0Interrupt(): ISR name is chosen from the device linker script.
94
========================================================================================*/
95
unsigned int DmaBuffer = 0;
96
void __attribute__((_interrupt_)) _DMA0Interrupt(void)
97
{
98
if(DmaBuffer == 0){
99
xMsb = (unsigned char)(BufferA.Adc1Ch0[1] >> 8);
100
xLsb = (unsigned char)(BufferA.Adc1Ch0[1] & 0xFF);
101
yMsb = (unsigned char)(BufferA.Adc1Ch1[1] >> 8);
102
yLsb = (unsigned char)(BufferA.Adc1Ch1[1] & 0xFF);
103
vrefMsb = (unsigned char)(BufferA.Adc1Ch2[1] >> 8);
104
vrefMsb = (unsigned char)(BufferA.Adc1Ch2[1] & 0xFF);
105
temperatureMsb = (unsigned char)(BufferA.Adc1Ch3[1] >> 8);
106
temperatureLsb = (unsigned char)(BufferA.Adc1Ch3[1] & 0xFF);
107
zMsb = (unsigned char)(BufferA.Adc1Ch4[1] >> 8);
108
zLsb = (unsigned char)(BufferA.Adc1Ch4[1] & 0xFF);
109
110
}
111
else
112
{
113
xMsb = (unsigned char)(BufferB.Adc1Ch0[1] >> 8);
114
xLsb = (unsigned char)(BufferB.Adc1Ch0[1] & 0xFF);
115
yMsb = (unsigned char)(BufferB.Adc1Ch1[1] >> 8);
116
yLsb = (unsigned char)(BufferB.Adc1Ch1[1] & 0xFF);
117
vrefMsb = (unsigned char)(BufferB.Adc1Ch2[1] >> 8);
118
vrefMsb = (unsigned char)(BufferB.Adc1Ch2[1] & 0xFF);
119
temperatureMsb = (unsigned char)(BufferB.Adc1Ch3[1] >> 8);
120
temperatureLsb = (unsigned char)(BufferB.Adc1Ch3[1] & 0xFF);
121
zMsb = (unsigned char)(BufferB.Adc1Ch4[1] >> 8);
122
zLsb = (unsigned char)(BufferB.Adc1Ch4[1] & 0xFF);
123
}
124
125
DmaBuffer ^= 1;
126
IFS0bits.DMA0IF = 0; //Clear the DMA0 Interrupt Flag
127
}

von gast (Gast)


Lesenswert?

AMODE = 0;

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.