Forum: Compiler & IDEs at90can Analogwerte auslesen


von JBOpael (Gast)


Lesenswert?

Hallo zusammen,

ich programmiere gerade einen at90can128 mit dem Avr Studio. Ich hab ein 
paar Zeilen geschrieben um alle Analogwerte nacheinander auszulesen. Das 
funktioniert auch soweit. Sobald ich aber den Port D4 setze, spielen 
meine Analogwerte verrückt. Genau genommen, kann ich die Werte dem Port 
nicht mehr zu Ordnen.

Hier mal ein paar zeilen:
1
// Init funktion
2
void init_ad_wandler()
3
{
4
5
  //Referenz auf VCC mit externer Kapazität an AVREF legen; Kanalauswahl auf Kanal 0
6
  ADMUX=(1<<REFS0);
7
  ADMUX |= 0; //erster port
8
9
10
  PORTC &= 0xF0;
11
  //Converter an, adc_prescaler 128, damit adc_clock F_CPU/128
12
  //Sampledauer für die erste Conversion 25 adc_clk takte, für jede weitere 13 adc_clk takte
13
  //sofort erste conversion starten
14
  ADCSRA=(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
15
16
  DIDR0=0x4F; //Disablen der digitalen input buffer von ADC5,4,3,2,1,0
17
  ADCSRA |= ((1<<ADEN)|(1<<ADSC)); //Converter Enablen und erste Conversion starten
18
19
20
}
1
void Cycle_AD_Wandlung(void)
2
{
3
  unsigned char port;
4
  unsigned char port2;
5
  unsigned int adc_wert;
6
  uint16_t zw;
7
  ADCSRB=0;
8
9
  static int port_test=0;
10
  
11
//ADSC ist 1 solange Wandlung andauert
12
  if(!(ADCSRA & (1<<ADSC)))
13
  {
14
    port= ADMUX & 0xF; //Welcher Port wurde gewandelt? Die untersten 4 Bit geben die Analog Pins an
15
    port2 = PORTC & 0xF;
16
    adc_wert=ADCW; //Low und high byte lesen
17
    act_val[ACT_ANALOG_NTC2]=ADMUX;
18
    switch (port)
19
    {
20
      case 0: //Multiplex
21
        act_val[ACT_ANALOG_NTC]=Mittelung(adc_wert,8,3);
22
        port++;
23
      break;
24
25
      case 1: //Power 2
26
        act_val[ACT_ANALOG_LEISTUNG2]=Mittelung(adc_wert,8,3);
27
        port++;
28
      break;
29
30
      case 2: //Power 1
31
        act_val[ACT_ANALOG_LEISTUNG1]=Mittelung(adc_wert,9,3);
32
        port++;
33
        break;
34
35
      case 3: //Power 3
36
        act_val[ACT_ANALOG_LEISTUNG3]=Mittelung(adc_wert,10,3);
37
        port++;
38
      break;
39
40
      case 4: //Analog 2 
41
        act_val[ACT_ANALOG_2]=Mittelung(adc_wert,11,3);
42
        port++;
43
      break;
44
45
46
.....
47
.....
48
.....
49
    }
50
51
    ADMUX &= ~0xF; //untersten  4 bit löschen (die port bits)
52
    ADMUX |= port; //nächster zu erfassender port
53
54
    PORTC &= ~0xF;
55
    PORTC |= port2;
56
57
    ADCSRA |= (1<<ADSC); //nächste conversion beginnen
58
  }
59
}//end of function

wenn ich jetzt den Ausgang D4 Setzte, kommt die Wandlung durcheinader.

kennt jemand das phenomen, oder hat jemand eine Idee wie ich das umgehen 
kann?


Danke schonmal

von Helfer (Gast)


Lesenswert?

1) Beim letzten case Fall im switch würde ich erwarten, dass port statt 
auf port+1 auf 0 zurückgesetzt wird. Das Zurücksetzen vermisse ich.
1
void Cycle_AD_Wandlung(void)
2
{
3
  ...
4
  if( !(ADCSRA & (1<<ADSC)) ) { // Wenn ADC-Wandler fertig ist...
5
    uint8_t port = ADMUX & 0xF; // 0..15
6
    uint16_t adc_wert = ADCW;  
7
8
    switch(port) {
9
      // Auswerten 0..4 Fälle!
10
      // port++ => zählt bis max. 5!
11
    }
12
13
    // ADC-Messung auf nächstem Port einrichten
14
    ADMUX &= ~0xF;
15
    ADMUX |= port; //nächster zu erfassender port 0..5 
16
                   //=> mehr als case 0..4!
17
    ...
18
    // Nächste Wandlung starten
19
    ADCSRA |= (1<<ADSC);
20
  }
21
}
22
23
// Beispielanwendung
24
int main(void)
25
{
26
  init_ad_wandler();
27
  while(1) {
28
     Cycle_AD_Wandlung();
29
  }
30
}

2) In init_ad_wandler() wird die Referenz des ADC manipuliert. Ich würde 
dort noch eine Dummywandlung machen lassen, d.h. eine ADC Messung und 
das Ergebnis verwerfen.

von Helfer (Gast)


Lesenswert?

Nachtrag: Die Stelle wo du "aber den Port D4 setze" machst, sehe ich in 
deinem Code nicht. Für mich manipulierst du nur

    port2 = PORTC & 0xF;
    ...
    PORTC &= ~0xF;
    PORTC |= port2;

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.