MSP430 - Problem mit ADC und DTC, mehrere Channels wiederholt lesen

OP #3404259
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
OP #3407593
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
Persönliche Seite #3407663
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.
Gast #3408862
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.
OP #3410394
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
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren