Halli hallo an Alle, also ich experimentiere jetzt das erste Mal mit dem EEPROM von meinem ATMega16. Um später mal einen Interpreter zu schreiben, dessen Code vom PC aus in den EEPROM geladen werden soll, wollte ich einfach mal anfangen ein paar Bytetokens in den EEPROM zu schreiben und mit einer Schleife auslesen.Ungefähr so: void main(void) { SetPorts(); USART_INIT(BAUD); Start=0; eeprom_write_byte( &eeprom_var1, 0x00 );EEPROM addr 0002 eeprom_write_byte( &eeprom_var2, 0x01 );EEPROM addr 0003 eeprom_write_byte( &eeprom_var3, 0x02 );EEPROM addr 0004 for(;;) { int i=2; BYTE token; sbi(PORTB, LED); USART_Receive(); if (Start=='1') { //for(i=2;i<5;i++) { token = eeprom_read_byte(i); switch (token) { case 0x00: // FUNKTION1 aufrufen funktion1(); //break; case 0x01: // FUNKTION2 aufrufen funktion2(); //break; case 0x02: // FUNKTION3 aufrufen funktion3(); // break; default: // KONTROLLLED cbi(PORTB, LED); break; } //} } else { sbi(PORTB, LED); } } } Dabei sind folgende Fragen aufgetreten: 1.Kann man beim Flashen des µC gleich die Bytetokens in den EEPROM schreiben? Habe mir das Beispiel dazu angesehen, was aber erst über Variablen geht. Geht das irgendwie auch direkt? 2.Wieso treten alle Fälle ein, obwohl ich die Schleife mit der Adresse auskommentiert habe? 3.Wie kann man solch eine Schleife am besten realsieren? Vielen Dank für alle die sich bemühen, Ciao Thomas
> 1.Kann man beim Flashen des µC gleich die Bytetokens in den EEPROM > schreiben? Habe mir das Beispiel dazu angesehen, was aber erst über > Variablen geht. Geht das irgendwie auch direkt? Das hängt von Deiner Programmiersoftware ab, aber es können wohl alle. Du mußt halt ein Ladefile für Deinen Programmer erzeugen (iHex, raw binary, S-Record -- was immer Dein Programmer verträgt). > 2.Wieso treten alle Fälle ein, obwohl ich die Schleife mit der > Adresse auskommentiert habe? Weil Du auch die breaks auskommentiert hast? > 3.Wie kann man solch eine Schleife am besten realsieren? uint16_t i, len; uint8_t *ee_addr; len = eeprom_read_word(0); for (i = 0, ee_addr = 2; i < len; i++, ee_addr++) switch (eeprom_read_byte(ee_addr)) { case ... ; }
Hi Jörg, schön, dass Du Dich wieder mal meldest * freu vielen Dank. Klar die Breaks müssen rein. Die Schleife habe ich auch mal getestet und funktioniert auch supi. Doch kannst Du mir bitte mal die Besonderheit der Adresse 0 des EEPROMs erklären? Ich nehmen an Du benutzt sie, um die Länge der Daten zu bestimmen.Hab das mal auch mal versucht: eeprom_write_byte( &laenge, 0x0002 ); aber so kommen mehr als drei Schleifendurchgänge heraus.Wieso? Das mit dem File ist mir im Prinzip klar, aber wie realsiert man das denn? Ich benutze WINAVR auch zum programmieren. Später will ich mal die Daten über die RS232 einlesen und in den EEPROM speichern.Das müßte ja dann mit einem selbstgeschriebenen Windowsprogramm gehen. Danke nochmal, Thomas
Hallo Thomas! Um den eeprom-Variablen gleich von vorneherein einen Wert zu verpassen gibt's z.B. folgenden Weg: signed char var1 _attribute_ ((section (".eeprom"))) = 10; signed char var2 _attribute_ ((section (".eeprom"))) = 3; signed char var3[] _attribute_ ((section (".eeprom"))) = {1, 2, 3}; Dann musst du noch in Deinem MakeFile folgende Zeile suchen: #AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep und das # entfernen damit die Werte beim Programmieren des µC in den eeprom geschrieben werden. Hoffe ich konnte helfen. Stefan
Halli hallo, @Stefan: Vielen Dank Stefan! Ich glaube das hilft mir weiter. Und wird dabei die erste Variable auch an die Adresse 0 und die zweite Variable an die Adresse 1 usw. geschrieben? @für alle: Ich versuche dafür einen Ringpuffer anzulegen, der mir die ankommenden Zeichen von der UART abspeichert.Dazu habe ich folgenden Text im Forum gefunden: *Am einfachsten arbeitet es sich mit einem Ringbuffer, sagen wir mal 8 *byte gross. *Zur Verwaltung benutzt man 3 Register, einen Schreibpointer, einen *Lesepointer und ein Zählregister (Anzahl der empfangenen Bytes). *-Zeichen wird empfangen -> Rx-Int wird ausgelöst *-das byte wird an der durch den Schreibpointer addressierten *Speicherzelle abgelegt *-der Schreibpointer wird erhöht und geprüft, ob dabei die max.Adresse *überschritten wurde, wenn ja, auf die Anfangsadresse zurücksetzen *-byte-Zähler erhöhen fertig. * *Gelesen wird, wenn Zeit dafür ist. Zuerst prüfen, ob der Counter > 0 *wenn ja: *-ein byte aus der durch den Lesepointer adressierten Speicher holen *-Lesepointer erhöhen, wenn > max_Adresse zurücksetzen *-byte-Zähler erniedrigen ich habe das versucht mal zu realsieren.Der Ringbuffer soll bei mir gefüllt werden, wenn ein Interrupt von der Uart kommt. Wenn das erste Zeichen einen bestimmten Wert hat(noch nicht realisiert), soll der EEPROM mit der gleichen Folge von der UART geschrieben werden. Aber der Compiler gibt immer Warungen aus, die ich nicht so recht verstehe. *warning: passing arg 1 of `eeprom_write_byte' makes pointer from *integer without a cast Kann mit bitte jemand weiterhelfen???? BYTE rxbuffer[8]; BYTE buff_count; uint8_t *write_buffer; uint8_t *read_buffer; uint8_t *max_buff; void SetVariables(void) { write_buffer=rxbuffer; read_buffer=rxbuffer; buff_count=0; max_buff=&rxbuffer[8]; } SIGNAL(SIG_UART_RECV) { *write_buffer = UDR; if (write_buffer<max_buff) write_buffer++; else write_buffer=rxbuffer; buff_count++; } void WriteEeprom (void) { while (buff_count) { eeprom_write_byte(buff_count,write_buffer); write_buffer--; buff_count--; } }
Hi Thomas!
>eeprom_write_byte(buff_count,write_buffer);
so wird das nix, der erste parameter dieser funktion muss eine Adresse
in den eeprom speicher sein, also z.B.
signed char var1 _attribute_ ((section (".eeprom"))) = 10;
.....
eeprom_write_byte(&var1, 73);
mit arrays sieht das ganze dann so aus:
signed char vararray[] _attribute_ ((section (".eeprom"))) = {10,
12, 13};
.....
eeprom_write_byte(&vararray[0], 73);
MfG
Stefan
@Stefan: habs gerade mal versucht zu testen, aber da stimmt was noch nicht: for(i=0;i<3;i++) { switch (eeprom_read_byte(&vararray[i])) { ich will der Wert an stelle i auslesen und dann mit switch schauen, ob ein Fall eingetroffen ist. Leider springt er immer auf default :-(( und nichts passiert? Hast Du ne Ahnung wieso?
Tach, wurde das Eeprom auch wirklich beschrieben, also steht was drin? Am besten mal mit Ponyprog oder so den eeprom auslesen und kucken. Damit der avrdude den eeprom beim flashen mit beschreibt musst du die oben genannte Zeile im makefile noch editieren (das # weg). Vom Code her müssts denk ich theoretisch passen wie ich das sehe... Stefan
Hi, also ich habe die Raute im Makefile entfernt, aber ich habe es bis jetzt nur im Simulator getestet und der springt in die Zeile: switch (eeprom_read_byte(&vararray[i])) und dann sollte beispielsweise ne 1 an dieser Stelle im Array stehen, damit dann dieser Fall eintreten kann case '1' function_xy(); aber stattdessen springt es immer zu default (tue nichts) Verstehste?? Also irgendwie haut die Syntax von eeprom_read_byte nicht hin. So ganz habe ich es eh noch nicht verstanden, wie das Adressargument aussehen muss. Muss es ein Pointer sein oder ein Wert eines Pointers oder nur ein int Wert. Habe leider keine Beispiele dazu gefunden :-( Kannste mir da vielleicht weiterhelfen, dass könnte mich insgesamt auch weiterbringen. ahoi thomas
So weit ich weis kann man im Simulator keine EEPROM-Zugriffe Simulieren (das setzen der Registern schon, schreiben und rücklesen der Daten allerdings nicht)...
Hi Stefan, jetzt funzt es! ich habe ausversehen das Makefile von einem anderen file geändert. so das der eeprom wirklich nicht beschrieben wurde. aber jetzt haut alles hin. Nun muss ich nur noch mal sehen, wie ich es schaffe, die ankommenden Daten von der RS232 in einen Ringpuffer zu schreiben, welcher dann in den EEProm übertragen wird. Meine Idee dazu habe ich ja weiter oben schon einmal gepostet. Vielen Dank Stefan... Ciao Thomas
Hi Stefan Du schriebst: *mit arrays sieht das ganze dann so aus: * *signed char vararray[] _attribute_ ((section (".eeprom"))) = {10, *12, 13}; Ist das auch der einfachste Weg, wenn man das ganze EEPROM mit Messwerten vollschreiben will(eine ewig lange Definition eines Arrays)? oder geht auch was in der Art von signed char vararray[] _attribute_ ((section (".eeprom"))) = {0..511}; oder kann man sonst irgendwie einen Adresszeiger in einer Schleife über das ganze EEPROM laufen lassen?
Hi Thomas! Die Werte in den {} Klammern brauchst du nur wenn du den Inhalt des eeproms "vorbeschrieben" haben willst... Du kannst natürlich einfach schreiben signed char vararray[512] _attribute_ ((section (".eeprom"))); nachdem du ja den eeprom eh als Ringbuffer verwenden willst brauchst du ja keine vorgegeben Werte nach dem flashen im eeprom stehen haben... Das ist eher sinnvoll wenn man eine Grundkonfiguration im eeprm ablegen möchte. MfG Stefan
Hi Stefan, danke nochmals für Deine Antwort. Zu Testzwecken habe ich den EEProm, mit meiner Grundkonfiguration gleich beim Flashen, beschrieben. Später soll allerdings die Grundkonfiguration mal über die RS232 in den EEProm gelangen. Um diese Daten ordentlich von der Uart zu empfangen, dachte ich mir, ein Ringbuffer wäre ganz gut. Wenn die Daten dann einmal im Ringbuffer sind, schreibe ich sie in den EEProm. Ich weiß nicht, ob es auch möglich ist, die Daten die von der Uart kommen, gleich in den EEProm zu schreiben. Meinst Du das geht, ohne das man dabei Daten verliert? danke Thomas
Beim Mega8 steht als "Typ Programming Time" für das EEPROM 8,5ms. Bis ca. 800 baud sollte das gehen. Ansonsten musst du beim Senden noch eine extra Pause einbauen.
@Uli: Habe eben versucht eine MMC an einem ATMega16 anzuschließen, aber leider bleibt das Programm in der Init-Routine stecken. Wie ist das mit den PIN Definitionen, wieso gibts 5 ? Hab ja nur 4 Leitungen... Für meinen Mega 16 habe ich das ganze wie folgt gesetzt: #define SPI_DI PB6 //Port Pin an dem Data Output... #define SPI_DO PB5 //Port Pin an dem Data Input... #define SPI_Clock PB7 //Port Pin an dem die Clock... #define MMC_Chip_Select PB4 //Port Pin an dem Chip Select... #define SPI_SS PB4 Stimmt das so ? MfG Stefan P.S. Kennt jemand ein IC in dem 3.3V/5V Level-Shifter drin sind ? Das mit den Widerständen ist mir nicht so ganz sympatisch...
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.