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?
Warte bis... == Interrupt? Ins blaue: Setze mal vor dem "Gehe in Sleep Power Save" ein TCNT0 = 0 mfg mf
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.
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
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.
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
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.