Forum: Mikrocontroller und Digitale Elektronik MSP430 - Problem mit ADC und DTC, mehrere Channels wiederholt lesen


von Markus X. (markusx)


Lesenswert?

Hallo,

ich schreibe mit Energia an einem kleinen Programm zur Spannungs-/ 
Strommessung.
Ziel ist es mittels eines Timer-Interrupts alle 100ms (funktioniert) die 
Werte aufzunehmen und alle 1s den Mittelwert zu bilden und diesen dann 
auszugeben, bzw. aufzuaddieren.

Der Interrupt funktioniert und ich kann mir auf den Display testweise 
die Zeit anzeigen lassen.

Zum ADC: Ich habe auf den Eingängen A0, A1, A4 und A5 die Analogwerte 
anliegen. Diese wollte ich mit dem ADC continuierlich sampeln und 
mittels DTC auf ein Array schreiben.
Aus diesem Array hätte ich dann bei einem Interrupt den gerade 
darinstehenden Wert genommen.

Soweit der Plan... Leider funktionert das ganze noch nicht. Scheinbar 
wird nichts in das Array geschrieben (?).

Danke für die Hilfe!

MfG
Markus
1
#include <LiquidCrystal.h>
2
#include <msp430.h>
3
4
5
6
LiquidCrystal lcd(19, 18, 14, 13, 12, 11);
7
const int buttonPin = PUSH2;
8
9
int spannung = 0, mwspannung=0;
10
int strom = 0, mwstrom =0;
11
int zaehler=0;
12
int verbrauch=0;
13
int gesamt=0;
14
unsigned int results[6];
15
16
17
18
void setup() {
19
  lcd.begin(16, 2);
20
   
21
 WDTCTL = WDTPW + WDTHOLD;                       // Disable watchdog reset
22
  
23
  ADC10CTL0 &= ~ENC;                             
24
  ADC10CTL1 |= CONSEQ_3+ INCH_5; 
25
  ADC10CTL0 |= ADC10SHT_1 + ADC10ON + MSC; 
26
  ADC10AE0 |= 0x33; // select channel A0,A1,A4,A5
27
  ADC10SA = (int)results;
28
  ADC10DTC0 |= ADC10CT;
29
  ADC10DTC1 = 0x06;
30
  ADC10CTL0 |= ADC10SC + ENC; // start conversions
31
32
33
34
    
35
    TA0CTL &=~MC_1;            
36
    
37
    TA0CCR0 = 0x9C34;   //rechnerisch: 9C40, aber Korrektur, da zu langsam
38
    TA0CCTL0 = CCIE; 
39
    TA0CTL = TASSEL_2 + ID_3 + MC_1 ;         
40
    _EINT();
41
42
43
                 
44
  
45
 
46
}
47
48
void loop() {
49
  //lcd.clear();
50
 
51
52
  lcd.setCursor(3, 0);
53
  lcd.print(results[0]);   //Test ob Array beschrieben wird
54
 
55
 lcd.setCursor(12, 0);
56
   lcd.print(results[1]); 
57
    
58
}
59
60
//Interrupt Routine entfernt

von Go MSP (Gast)


Lesenswert?

Probier doch einmal den TI Code:
Beitrag "Re: MSP430 ADC10 mehrere Kanäle"

von Markus X. (markusx)


Lesenswert?

Hallo,

danke, aber der TI Code, bzw. die hier im Forum liegenden Codes sind mir
bekannt. (denke zumindest alles gefunden zu haben)

TI-Init:

  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  ADC10CTL1 = INCH_2 + CONSEQ_1;            // A2/A1/A0, single sequence
  ADC10CTL0 = ADC10SHT_2 + MSC + ADC10ON + ADC10IE;
  ADC10DTC1 = 0x03;                         // 3 conversions
  ADC10AE0 |= 0x07;                         // P2.2,1,0 ADC10 option
select
  P1DIR |= 0x01;                            // Set P1.0 output



Mein Init:

  WDTCTL = WDTPW + WDTHOLD;                       // Disable watchdog
reset
  ADC10CTL0 &= ~ENC;                              // ADC aus
  ADC10CTL1 |= CONSEQ_3+ INCH_5;                  // Kont. Samplen,
A5-A0
  ADC10CTL0 |= ADC10SHT_1 + ADC10ON + MSC;        //
  ADC10AE0 |= 0x33; // select channel A0,A1,A4,A5
  ADC10SA = (int)results;
  ADC10DTC0 |= ADC10CT;
  ADC10DTC1 = 0x06;
  ADC10CTL0 |= ADC10SC + ENC; // start conversions


Meine Frage geht gerade in die Richtung, ob die Zeile:

ADC10SA = (int)results;

So funktioniert. Ansonsten gibt es ja nicht viele Ansätze a) ADC geht /
geht nicht -> init falsch
b) Arrayzuweisung geht nicht ->keine Werte da

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Vergleich mal ganz genau, was hier passiert:


TI:

> ADC10CTL0 = ADC10SHT_2 + MSC + ADC10ON + ADC10IE;


Du:

> ADC10CTL0 &= ~ENC;                              // ADC aus
> ADC10CTL0 |= ADC10SHT_1 + ADC10ON + MSC;        //

Das TI-Beispiel initialisiert das komplette ADC10CTL0-Register, Du aber 
belässt es im Reset-Zustand und änderst nur einige Bits darin.

Das muss nicht die Ursache Deines Problems sein, kann aber.

von Go MSP (Gast)


Lesenswert?

Bei der Initialisierung muss nach dem disablen aufs Busy gewartet 
werden.
1
ADC10CTL0 &= ~ENC;
2
while(ADC10CTL1 & BUSY);

Rufus Τ. Firefly schrieb:
> Das TI-Beispiel initialisiert das komplette ADC10CTL0-Register, Du aber
> belässt es im Reset-Zustand und änderst nur einige Bits darin.

Das sollte natürlich auch geprüft werden.

von Markus X. (markusx)


Lesenswert?

Hallo,

danke für die Hilfe, das mit dem verodern ... da wollte ich einfach auf 
Nummer sicher gehen nichts wichtiges zu überschreiben. Ich habs jetzt 
mit Blick aufs Handbuch geändert, leider will er immer noch nicht :(

Hier ein hoffentlich verständliches Testprogramm
1
LiquidCrystal lcd(19, 18, 14, 13, 12, 11);
2
3
4
int zaehler=1;
5
int spannung;
6
unsigned int results[6];
7
int rtc=0;
8
9
10
11
void setup() {
12
  // set up the LCD's number of columns and rows: 
13
  lcd.begin(16, 2);
14
  
15
 
16
 WDTCTL = WDTPW + WDTHOLD;                       // Disable watchdog reset
17
18
  ADC10CTL0 = 0x00;
19
  while(ADC10CTL1 & BUSY);
20
  ADC10CTL1 = CONSEQ_1+ INCH_5;             //continuous sample mode, 
21
  ADC10CTL0 = ADC10SHT_2 + ADC10ON + MSC;   //sample and hold time, adc on, cont. sample
22
  ADC10AE0  = 0x33;                         // select channel A0,A1,A4,A5
23
  ADC10SA   = results[0];
24
  ADC10DTC0 = ADC10CT;
25
  ADC10DTC1 = 0x06;
26
  ADC10CTL0 |= ADC10SC + ENC;                // start conversions
27
28
29
  TA0CTL &=~MC_1;            
30
  TA0CCR0 = 0x9BB2;   //rechnerisch: 9C40, aber Korrektur, da zu langsam
31
  TA0CCTL0 = CCIE; // Capture/compare interrupt flag
32
  TA0CTL = TASSEL_2 + ID_3 + MC_1 ;         // Timer A config: SMCLK, /8, count up, overflow interrupt enabled
33
  _EINT();
34
35
}
36
37
void loop() {
38
  //lcd.clear();
39
 lcd.setCursor(0, 0); lcd.print("V:");
40
 lcd.setCursor(0, 1); lcd.print("t:");
41
 
42
  lcd.setCursor(3, 0);
43
  lcd.print(spannung);
44
  lcd.setCursor(3, 1);
45
  lcd.print(rtc);
46
 
47
}
48
49
#pragma vector = TIMER0_A0_VECTOR                   // Timer A overflow (TAIFG) interrupt
50
__interrupt void TIMER0_A0_ISR (void)                //
51
{   zaehler++;
52
   
53
  if (zaehler==50){
54
  rtc++;  
55
   spannung = results[1];
56
   zaehler=0;
57
       };
58
}

von Tapp (Gast)


Lesenswert?

Die Adresse ist nicht
1
ADC10SA   = results[0];
sondern
1
ADC10SA   =  &(results[0]);

von Markus X. (markusx)


Lesenswert?

Oha,

beim ganzen probieren vergessen... Danke


aber &(results[0]) führt zur Fehlermeldung

und (int)&(results[0]) führt auch nicht zur gewünschten Funktion

von Markus X. (markusx)


Lesenswert?

Hallo,


Hier die Lösung:

1
 ADC10DTC0 = ADC10CT + ADC10B1;


ADC10B1 muss scheinbar auch gesetzt werden.

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.