Forum: Mikrocontroller und Digitale Elektronik ATmega8 ADC unterschiedliche Sample-Zeit??


von Michael D. (etzen_michi)


Lesenswert?

Nabend.

Habe mich gerade mit dem Sleep-Modis des ATmega8 vertraut gemacht, da 
ist mir aufgefallen, das der ADC irgendwie von 0,5ms bis 2ms benötigt.

Wavon kann diese Schwankung kommen?

Das Programm:
Pseudocode:

Gehe in Sleep "Power Save".
Warte auf Timer Overflow.
Gehe in Sleep "ADC Noise Reduction"
Warte bis ADC fertig und wache auf.
Rechne ein wenig.
Fange wieder von vorne an.


Das Rechnen dauert immer gleich lange, da er unabhängig vom Ergebnis 
immer das gleiche Rechnet.
Nur der ADC benötigt immer unterschiedlich lange.


Stromaufnahme:

          ___
         | ^ |
      ___| | |
_____| ^   | |______
  ^    |   |
  |    |   | Rechnen (Ohne Sleep)
  |    | ADC Sampling (ADC Noise Reduction)
  | Sleep (PWR SAVE)


Oder habe ich da irgendwo einen Fehler im Gedanken?

von Achim M. (minifloat)


Lesenswert?

Warte bis... == Interrupt?
Ins blaue:
Setze mal vor dem "Gehe in Sleep Power Save" ein TCNT0 = 0
mfg mf

von Michael D. (etzen_michi)


Lesenswert?

Der Timer0 wird nicht verwendet.

Ich verwende nur den Timer2 mit einem 32,768kHz Quarz um ca. jede 
Sekunde einen Interrupt zu erhalten (Overflow).

Der andere Sleep Modi (Der mit der ungleichmäßigen Laufzeit) wird durch 
den Interrupt des ADC beim fertigstellen einer Messung beendet.

Nicht ganz sauber aber hier mal das Programm:
1
int main(void) {
2
3
     // Chip Select auf High (Active Low)
4
     // MISO und IRQ als Eingang, Rest als Ausgang
5
     PORTB= 1<<RFMCSN;
6
     DDRB=~(1<<RFMMISO | 1<<RFMIRQ);    // SS muss als Ausgang konfiguriert sein damit SPI ordentlich arbeitet.
7
8
     //ADC Konfigurieren
9
     ADMUX= 1<<REFS1 | 1<<REFS0 | 1<<ADLAR | 0<<MUX0 | 0<<MUX1 | 0<<MUX2 | 0<<MUX3;
10
     ADCSRA= 1<<ADEN | 0<<ADSC | 0<<ADFR | 1<<ADIF | 1<<ADIE | 1<<ADPS2 | 1<<ADPS1 | 1<<ADPS0;
11
12
     // Timer 2 Konfigurieren
13
     TCCR2= 0<<FOC2 | 0<<WGM21 | 0<<WGM20 | 0<<COM21 | 0<<COM20 | 0<<CS22 | 0<<CS21 | 0<<CS20;
14
     TIMSK= 0<<OCIE2 | 1<<TOIE2;
15
     ASSR= 1<<AS2;
16
17
     // SPI Initialisieren
18
     SPI_Init();
19
20
     // Interrupts aktivieren
21
     sei();
22
23
     // RFM70 Initialisieren
24
     RFM70_Init();
25
     RFM70_switchBank();
26
     RFM70_TX(1);
27
28
//*****************************************************************************************************
29
// Ab hier sollte das Gerät komplett konfiguriert sein
30
31
     PORTB|= 1<<RFMCE;
32
33
     ADCSRA|= 1<<ADSC;
34
     TCCR2|= 1<<CS22 | 0<<CS21 | 1<<CS20;
35
     set_sleep_mode(SLEEP_MODE_ADC);
36
     sei();
37
     sleep_mode();
38
39
40
     while(1) {
41
          if(Flag) {
42
               RFM70_PWR(1);
43
               Flag=0;
44
               RFM70_OpenPL();
45
               RFM70_PLData(ADCL);
46
               RFM70_PLData(ADCH);
47
               RFM70_SendPL();
48
               RFM70_WaitforTX();
49
               RFM70_PWR(0);
50
               set_sleep_mode(SLEEP_MODE_PWR_SAVE);
51
               sei();
52
               sleep_mode();
53
          }
54
     }
55
}
56
57
58
//*******************************************************************************************************
59
// Beginn Unterprogramme
60
61
ISR(ADC_vect) {
62
     Flag=1;
63
}
64
65
ISR(TIMER2_OVF_vect) {
66
     set_sleep_mode(SLEEP_MODE_ADC);
67
     sei();
68
     sleep_mode();
69
}


Was ich gerade überlege, könnte es mit der höhe des ADC Wertes zusammen 
liegen?
Wobei dieser sich max. in den unteren 3Bit geändert hat.

von Achim M. (minifloat)


Lesenswert?

Mach da mal drei Pins frei, an denen du anzeigen kannst, welcher Task 
wirklich gerade aktiv ist. Was mir sonst noch auffällt:
if(flag)
{
  // und hier wird erstmal fleißig mit dem RFM
  // kommuniziert, initialisiert, diskutiert
  // und auf dessen TX-Acknowledge gewartet?
}
Wo wird in dem geposteten Code gerechnet?

mfg mf

von Michael D. (etzen_michi)


Lesenswert?

Ja gut ... mit "Rechnen" meine ich den Teil, wo er Flag=1 ist und er mit 
dem RFM komuniziert, bis er wieder in den Sleep geht.

von Peter D. (peda)


Lesenswert?

Michael D. schrieb:
> Ich verwende nur den Timer2 mit einem 32,768kHz Quarz um ca. jede
> Sekunde einen Interrupt zu erhalten (Overflow).

Daran liegt es. Im  asynchronen Mode ist ne Menge zu beachten, damit 
Sleep richtig funktioniert.

Beitrag "Sleep-Funktion / Power Save"

Für den ADC zu schlafen, lohnt sich daher nicht.
Ruhigere ADC-Werte (Sleep ohne async T2) konnte ich auch nicht 
feststellen.
Bei ordentlichem Platinenlayout steht die Wandlung auch ohne Sleep auf 
10 Bit.


Peter

von Bananen Joe (Gast)


Lesenswert?

Wird der ADC nicht nach dem Neustart neuinitialisiert? Die erste 
Wandlung braucht doch daher eh laenger? Interessant waere jetzt wie der 
ADC sich nach dem Aufwecken aus dem Sleep-Modus verhaelt( -> 
Datenblatt).
Aehnliches gilt fuer die Mainclock, die muss auch erst anschwingen wenn 
sie aus dem Ruhemodus erwacht.

von Michael D. (etzen_michi)


Lesenswert?

Peter Dannegger schrieb:
> >Ich verwende nur den Timer2 mit einem 32,768kHz Quarz um ca. jede
> >Sekunde einen Interrupt zu erhalten (Overflow).
> Daran liegt es. Im  asynchronen Mode ist ne Menge zu beachten, damit
> Sleep richtig funktioniert.

Habe nach den Beispielen hier: 
http://www.mikrocontroller.net/articles/Sleep_Mode mich eingearbeitet.
Habe auch über Stunden eine Sekundengenaue abarbeitung.


Peter Dannegger schrieb:
> Bei ordentlichem Platinenlayout steht die Wandlung auch ohne Sleep auf
> 10 Bit.

Bei diesem Projekt geht es mehr um das kennenlernen der "Sleep" 
Funktion, als um den ADC.
Das Board ist in diesem Fall ein Steckbrett.


Bananen Joe schrieb:
> Wird der ADC nicht nach dem Neustart neuinitialisiert? Die erste
> Wandlung braucht doch daher eh laenger?

Ob er immer neu Initialisiert wird weiß ich nicht genau, glaube aber 
nicht, sondern nur beim ersten Mal.
Anschließend läuft er ja gleichmäßig nach immer der gleichen Zeit vom 
gleichen Zustand aus, das ist es was mich wundert.


Bananen Joe schrieb:
> Interessant waere jetzt wie der
> ADC sich nach dem Aufwecken aus dem Sleep-Modus verhaelt

Beim Einschlafen wird der ADC ja automatisch gestartet und das nächste 
Aufwachen ist wenn der ADC fertig ist. Werkeln tut er ja während der 
Controller im Halbschlaf ist.


Bananen Joe schrieb:
> Aehnliches gilt fuer die Mainclock, die muss auch erst anschwingen wenn
> sie aus dem Ruhemodus erwacht.

Bzgl. der Mainclock habe ich es hier: 
http://www.mikrocontroller.net/articles/Sleep_Mode so verstanden das 
sich der Controller von alleine um die Zeit zum Aufwachen kümmert.
Daher das diese Zeit beim internen RC am geringsten sein soll, habe ich 
da mit dem Watchdog nochnicht rum probiert.
Werde das heute Abend mal testen wie das Ergebniss ausschaut wenn ich 
den Watchdog einstelle.

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.