Hallo ich habe ein wenig mit dem EEPROM aus dem Mega8 gespielt. Lesen lief dann endlich irgendwann (siehe Thread im anderem Forum), aber schreiben wollte einfach nicht gehen. Es müssen 2 Bits NACHEINANDER gesetzt werden. Der Code sah zunächst so aus: EECR |= (1<<EEMWE); EECR |= (1<<EEWE); dann hab ich mal versucht es so zu lösen: asm("sbi 0x1C, 2"); asm("sbi 0x1C, 1"); und damit läuft es nun. Fasst der Compiler die beiden Befehle oben zusammen und setzt die beiden Bits gleichzeitig? Vielen Dank Gruß Philipp
> Fasst der Compiler die beiden Befehle oben zusammen und setzt die > beiden Bits gleichzeitig? Nein. Die I/O-Register sind in der avr-libc als volatile deklariert, d.h. jeder einzelne Zugriff, der im Quellcode steht, muß auch tatsächlich durchgeführt werden. Dein C-Code und die Assembler-Variante machen übrigens verschiedene Dinge. Deine Bitwertigkeiten stimmen nicht. Übrigens: Warum benutzt du nicht gleich die EEPROM-Funktionen der avr-libc?
Wollte es gern zu Fuss machen mit dem EEPROM. Gibt es einen echten Vorteil durch die libc? Was ist denn der Unterschied zwischen C Variante und ASM? (Beides übrigens aus dem Datenblatt) Mit der C Variante funktioniert es leider nicht, mit dem ASM schon. Deshalb dachte ich das es evtl. zusammengefasst wird. EEMWE ist Bit 2 laut Datenblatt und im iom8.h auch als 2 definiert. Und ich dachte set bit in register macht braucht dann als parameter auch bit 2? Oder was meinst du als unterschied zwichen der C und er ASM version? Vielen Dank Gruß Philipp
Ja. Man weiß ganz genau was der Controller tut, weiß wo welches Byte liegt, kann es dadurch leicht über den ISP bearbeiten usw und man bleibt näher an der Hardware, was ich nicht schlecht finde, weil ich ab und zu gezwungen werde etwas mit ASM zu tun. Und es ja nun wirklich nicht aufwendiger. Gruß Philipp
> Ja. Man weiß ganz genau was der Controller tut, weiß wo welches > Byte liegt, kann es dadurch leicht über den ISP bearbeiten usw > und man bleibt näher an der Hardware, was ich nicht schlecht > finde, weil ich ab und zu gezwungen werde etwas mit ASM zu tun. Dann solltest du alles in Assembler programmieren. Du benutzt so viele Dinge aus der Bibliothek, aber ausgerechnet die Dinge, bei denen es auf eine `timed sequence' ankommt, willst du unbedingt zu Fuß schreiben, obwohl die Bibliothek dir dafür eine fertige (und getestete) Implementierung liefert. Das widerspricht sich irgendwie.
> EEMWE ist Bit 2 laut Datenblatt und im iom8.h auch als 2 > definiert. Und ich dachte set bit in register macht braucht dann > als parameter auch bit 2? Hast recht. Ich habe Mist erzählt.
Hi! Ich hatte vor 6 Monaten das selbe Problem. Im Datenblatt steht, daß die beiden Operationen in einem bestimten maximalen Abstand ( 4 Takte) nacheinander stattfinden müssen. Ich hab es zuerst mit dem Code aus der Atmel Appnote versucht, das ging aber nicht. Der Grund ist der, daß es der GCC nicht schafft Code zu kompilieren der in den 4 Takten ausgeführt wird. Darum funktionen die Zugriffe nicht. Ich habs damals so gelöst: void write_config(void) { uint8_t address = 0; uint8_t* source = (uint8_t*) &DataToBeWritten; uint8_t i; uint8_t eecr_t1; uint8_t eecr_t2; cli(); for ( i = 0; i < sizeof(DataToBeWritten); i++) { // Wait for completion of previous write while(EECR & (1<<EEPE)) ; // Set up address and Data Registers EEARH = 0; EEARL = address; EEDR = *source; // prepare values. needed since write has to be initiated within 4 clocks // doing other ways causes the compiler to compile too slow code eecr_t1 = EECR | 0b00000100; eecr_t2 = eecr_t1 | 0b00000010; EECR = eecr_t1; // Start eeprom write by setting EEPE EECR = eecr_t2; // write next byte to next address address++; source++; } sei(); }
> Der Grund ist der, daß es der GCC nicht schafft Code zu > kompilieren der in den 4 Takten ausgeführt wird. Optimierung ausgeschaltet? Anyway, derartige timed sequences sind ein wesentliches Anwendungsfeld von inline asm, vorzugsweise in der Bibliothek verpackt. Damit ist man nämlich komplett unabhängig von der Optimierung. Genau das ist letztlich das, was die EEPROM-Bibliotheksroutinen tun.
Hi! Nein. Im Gegenteil ich hab es mit mereren Optimierungsvarianten versucht. Das ganze innerhalb von 4 Takten ging sich mit keiner Variante aus. Nachdem ich herausgefunden hatte warum das Schreiben nicht geht hab ich mich dann aber auch nicht mehr lange mit dem Problem herumgeschlagen sondern hab eben den workaround gemacht. lg, Thorsten
Hab nun die Option -S entdeckt beim gcc ;) also bei mir liefert EECR |= (1<<EEMWE); EECR |= (1<<EEWE); exakt das gleiche in ASM wie asm("sbi 0x1C, 2"); asm("sbi 0x1C, 1"); nochmal zur Lib: Kann die auch große Daten IRQ gesteuert schreiben oder ist da diese Warteschleife benutzt worden? Vielen Dank Gruß Philipp
Thorsten: Welche Appnote eigentlich? AVR100 kommt nur mit Assemblercode. Philipp: > Kann die auch große Daten IRQ gesteuert schreiben oder ist da diese > Warteschleife benutzt worden? Nein, die Bibliothek macht das im polled mode. Wenn du das via Interrupt schreiben willst, musst du das wirklich selbst bauen (oder mal im Internet gucken, vielleicht hat ja AVRlib schon was dafür?).
@Philipp Da hast du mir etwas voraus :-) Ich hatte die Option nicht entdeckt. Ich geb aber auch zu, daß ich mit den diversen Compileroptionen - egal bei welcher Umgebung und für welches BS - seit eh und je etwas auf Kriegsfuß stehe. "-S Stop after the stage of compilation proper; do not assemble." In welcher Weise löst das das Problem? @Jörg Appnote triffts wohl nicht zu 100% Ich hatte es dem Datenblatt des AVR den ich damals verwendet hab entnommen. Welcher das war kann ich aber im Augenblick nicht sagen da ich momentan nicht an den PC komme. Wenn ich nicht irre habe ich den Code aufgehoben. Sollte es von Interesse sein schau ich zu Hause auch gern nach was der der GCC ursprünglich gemacht hat. lg, Thorsten
Ich denke, er meint '-Os' für die Optimierung auf Speichergröße (size)...
> Appnote triffts wohl nicht zu 100% Ich hatte es dem Datenblatt des > AVR den ich damals verwendet hab entnommen. Welcher das war kann ich > aber im Augenblick nicht sagen da ich momentan nicht an den PC > komme. Ich habe mir eben den Code aus dem Datenblatt für den ATmega1281 genommen und ihn durch den GCC geschickt. Mit -Os generieren mir daraus sowohl GCC 3.4.6 als auch 4.1.0 gleichlautend: EEPROM_write: .L3: sbic 63-0x20,1 rjmp .L3 out (65)+1-0x20,r25 out 65-0x20,r24 out 64-0x20,r22 sbi 63-0x20,2 sbi 63-0x20,1 ret > Ich denke, er meint '-Os' für die Optimierung auf Speichergröße > (size)... Nö, mit -S kann man sich den generierten Assemblercode ansehen. Das ist das, was ich hier auch zitiert habe. Ist für meine Begriffe oftmals übersichtlicher als die Disassembler-Ausgabe.
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.