Hallo Forum, beim Schreiben ins EEPROM vom atXmega kommt es bei mir zu einem Reset des Prozessors. Dies ist ja auch in Errata AVR1008 beschrieben. Aber ich schaffe es nicht, den IdleMode zu integrieren. Bei der AVR1008 Datei ist die Funktion __sleep(); vorhanden, welche mein Compiler (WinAVR) nicht kennt, somit kann ich diesen Teil nicht implementieren. Kann mir jemand von euch den Code um den Idle-Mode nach dem Schreiben ins EEPROM von 2,4µs zu bekommen geben. Ich verwende den atXmega64 A3. Laut dem Errata kann es nach dem Schreiben in das EEPROM innerhalb von 2,5µs zu einem Falschausführen vom Code kommen, deshalb soll man den µC in den Idle-Mode schicken und entweder durch den Timer oder durch den EEPROM-ready Interrupt wieder aus dem Idle Mode zurück holen. Diese Implementierung macht mir Probleme. Verwende ich die Libary von Joachim Rath (xeeprom.h) macht mein Prozessor ebenfalls (manchmal) einen Reset nach dem schreiben. Hier ist ebenfalls nicht die Routine mit dem Idle-Mode integriert. Danke für eure Hilfe im Voraus. EEPROM
Mahlzeit, versuche mal: #include <avr/sleep.h> //Power Management and Sleep Modes ... set_sleep_mode(SLEEP_MODE_IDLE); // idle modus sleep_enable(); // aktivieren sleep_cpu(); // auf nächsten Interrupt warten MfG
Hallo, ich hab den Tipp von Joachim Rath umgesetzt und auch Seine xeeprom.h eingesetzt. (Datei siehe oben eingebunden.) Mein Source Code sieht auszugsweise so aus:
1 | ....
|
2 | .....
|
3 | #include “xeeprom.h“ // *.h Datei zum EEPROM ansprechen von Joachim Rath (GNU)
|
4 | ...
|
5 | main
|
6 | ...
|
7 | |
8 | clock_init(); // Clock auf 30 MHz stellen |
9 | EEpromInit(); // EEPROM Inistialisieren |
10 | usart_init(); // UART Initialisieren |
11 | sei(); // Interrupt enable |
12 | |
13 | sprintf (buffer,"Beginn auslesen"); |
14 | usart_sendstring(buffer); |
15 | {
|
16 | usart_sendstring("\r"); // Return auf die Serielle schicken |
17 | usart_sendstring("\n"); // New line ausgeben |
18 | |
19 | a = EEpromReadFloat(50); |
20 | |
21 | wait_ms(1); // Zeitschleife von x ms |
22 | |
23 | sprintf (buffer,"Start Zahl 1 aus EEPROM: %f ", a); |
24 | usart_sendstring(buffer); |
25 | |
26 | wait_ms(1000); // Zeitschleife von x ms |
27 | |
28 | |
29 | usart_sendstring("\r"); |
30 | usart_sendstring("\n"); |
31 | |
32 | a = 5; |
33 | |
34 | sprintf (buffer,"Beginn mit dem Schreiben"); |
35 | usart_sendstring(buffer); |
36 | |
37 | usart_sendstring("\r"); // Return auf der Seriellen ausgeben |
38 | usart_sendstring("\n"); // NewLine ausgeben |
39 | |
40 | EEpromWriteByte(50,a); // Ab hier oder in den nächsten Zeilen muss der Fehler liegen. |
41 | set_sleep_mode(SLEEP_MODE_IDLE); // idle modus |
42 | sleep_enable(); // aktivieren |
43 | sleep_cpu(); // auf nächsten Interrupt warten |
44 | |
45 | |
46 | wait_ms(1000); // Zeitschleife von x ms |
47 | |
48 | sprintf (buffer,"Written 1"); |
49 | usart_sendstring(buffer); |
50 | |
51 | a= 99; // bewusst andere Zahl eingegeben. |
52 | usart_sendstring("\r"); |
53 | usart_sendstring("\n"); |
54 | |
55 | sprintf (buffer,"Written End"); |
56 | usart_sendstring(buffer); |
57 | |
58 | usart_sendstring("\r"); |
59 | usart_sendstring("\n"); |
60 | |
61 | a = EEpromReadByte(50); |
62 | |
63 | sprintf (buffer,"Zahl 1 aus EEPROM: %f ", a); |
64 | usart_sendstring(buffer); |
65 | |
66 | wait_ms(1000); |
67 | |
68 | usart_sendstring("\r"); |
69 | usart_sendstring("\n"); |
70 | |
71 | sprintf (buffer,"Auslesen Ende"); |
72 | usart_sendstring(buffer); |
Als Ergebnis bekomme ich auf der Seriellen Schnittstelle: Reginn auslesen Start Zahl 1 aus EEPROM: 5 Beginn mit dem Schreiben Beginn mit dem Schreiben Beginn mit dem Schreiben Beginn mit dem Schreiben Beginn mit dem Schreiben Beginn mit dem Schreiben Beginn mit dem Schreiben Beginn mit dem Schreiben Beginn mit dem Schreiben Dies lässt für mich den Schluss zu, dass er irgendwie zurück springt und später hängen bleibt. Was ab ich in der Implementierung falsch gemacht? Gruß EEPROM
Setz das
1 | set_sleep_mode(SLEEP_MODE_IDLE); // idle modus |
2 | sleep_enable(); // aktivieren |
mal an den Anfang von main. Du hast nur 2.5us Zeit, in den idle-mode zu kommen, da sind alle unnötigen Befehle dazwischen zu viel. Ansonsten http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=88416 Oliver
Nabend, EEPROM schrieb: > Mein Source Code sieht auszugsweise so aus: sei so gut und poste ein nachvollziehbares Projekt. Mit einem Auszug ist es schwer einen Workaround zu finden, der dann allen nutzt. MfG
Sorry, dass ich nicht gleich das ganze Programm gemailt hab. Ich hab die Änderung von Oliver schon eingepflegt. Aber er macht immer noch diese mir unklaren Sprünge/Resets. Das: Start Zahl 1 aus EEPROM: 5 Beginn mit dem Schreiben BBeginn auslesen Start Zahl 1 aus EEPROM: 5 Beginn mit dem Schreiben BBeginn auslesen Start Zahl 1 aus EEPROM: 5 Beginn mit dem Schreiben BBeginn auslesen Start Zahl 1 aus EEPROM: 5 Beginn mit dem Schreiben BBeginn auslesen Start Zahl 1 aus EEPROM: 5 Beginn mit dem Schreiben Ist die Ausgabe auf der Seriellen Schnittstelle. Danach bleibt das Programm hängen. Gruß EEPROM
Moin, entweder bin ich blind oder >Start Zahl 1 aus EEPROM: 5 >Beginn mit dem Schreiben >BBeginn auslesen >Start Zahl 1 aus EEPROM: 5 >Beginn mit dem Schreiben >BBeginn auslesen >... passt nicht zum geposteten Code. >while(1) // hier verharren, wenn Schreib und Lesen auf EEPROM erledigt > {;} nach einem Durchlauf ist schluss. Es sei denn der Watchdog ist aktiv (Fuses) Bau dir eine whund.h mit folgendem Inhalt: #undef wdt_enable static inline void wdt_enable(uint8_t value) // Watchdog ein { uint8_t wdt = WDT_ENABLE_bm | WDT_CEN_bm | value; CCP = CCP_IOREG_gc; WDT.CTRL = wdt; while(WDT.STATUS & WDT_SYNCBUSY_bm); } #undef wdt_disable static inline void wdt_disable(void) // Watchdog abschalten { uint8_t wdt = (WDT.CTRL & ~WDT_ENABLE_bm) | WDT_CEN_bm; CCP = CCP_IOREG_gc; WDT.CTRL = wdt; } ... und schalte den WD am Anfang der main() aus. Compileroptimierung muss eingeschaltet sein. MfG
Danke für deine Hilfe, jetzt klappt es ;-). Ich musste noch mit der Compileroptimierung spielen. Gruß EEPROM
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.