Hallo,
Leider komme ich schon wieder nicht weiter bei einem Problem. Ich
versuche Daten ins EEprom zu schreiben und beim Start die gespeicherten
Daten wieder in die Variablen auszulesen. Wahrscheinlich habe ich Fehler
im Code, denn während der Rest meines Programms in Picbasic Pro
geschrieben ist, habe ich mich bei den EEprom-Routinen mit Assembler
versuchen müssen, weil die Picbasic-Befehle auch nicht funktionierten.
Es scheint ab und zu etwas ins EEprom geschrieben zu werden, jedoch nur
unregelmässig und nicht das was geschrieben werden sollte. Das
ausgelesene EEprom sieht dann etwa so aus:
86 10 00 00 00 58 00 00
FF FF 00 FF FF FF FF FF
86 10 00 00 00 58 00 00
FF FF 00 FF FF FF FF FF
86 10 00 00 00 58 00 00
FF FF 00 FF FF FF FF FF
... (die restlichen Zeilen sind genauso)
Ich habe zum Beispiel eine Routine wie folgt:
write_band:
EEADR = $08
Eedata = band
asm
bsf status, RP0 ; Bank1
bcf intcon, GIE ; Disable INTs
bsf eecon1, WREN ; Enable Write
movlw 055h ;
movwf eecon2 ; 55h must be written to EECON2
movlw 0AAh ; to start write sequence
movwf eecon2 ; Write AAh
bsf eecon1, WR ; Set WR bit begin write
bsf intcon, GIE ; Enable INTs
endasm
delayms 10
Return
Diese sollte ins EEprom schreiben und wird aufgerufen, sobald die
Variable "band" geändert wird.
Am Anfang des Programms steht dann die dazugehörige Leseroutine, die
einmal beim Start aufgerufen wird:
asm
bcf status, RP0 ; Bank0
movlw 0x08 ; Read address 8 in EEPROM space
Movwf eeadr ; Address to read
bsf status, RP0 ; Bank1
bsf eecon1, RD ; EE Read
bcf status, RP0 ; Bank0
movf eedata, W ; W = EEDATA
endasm
band = eedata 'band ist eine bit-variable.
Ich kenne mich mit Assembler nicht gross aus, habe mich einfach an die
Anweisungen in den Microchip-Papieren gehalten. Ich habe auch
DWord-Variablen die im EEprom gespeichert werden sollen, dort führe ich
diese Routinen einfach 4 Mal nacheinander aus für die 4 Bytes in einem
DWord. Dass mein Code vielleicht nicht optimal ist kann gut sein, wie
gesagt ich habe noch kaum Assembler programmiert.
Gibt es aber Fehler, die ich einfach nicht erkenne?
Gruss
Martin
Hallo Martin, nach dem Befehl "bsf eecon1,wr" schreibst du "btfsc eecon1,wr" und dann "goto $-1". Du verläßt die Schreibroutine erst, wenn die Speicherzelle auch wirklich beschrieben ist.
Hallo Erhard
Vielen Dank für die Hilfe!
Die Write-Routine sieht also jetzt so aus:
write_band:
EEADR = $08
Eedata = band
asm
bsf status, RP0 ; Bank1
bcf intcon, GIE ; Disable INTs
bsf eecon1, WREN ; Enable Write
movlw 055h ;
movwf eecon2 ; 55h must be written to EECON2
movlw 0AAh ; to start write sequence
movwf eecon2 ; Write AAh
bsf eecon1, WR ; Set WR bit begin write
btfsc eecon1, WR ; Wait for write to complete
goto $-1
bsf intcon, GIE ; Enable INTs
endasm
delayms 10
Return
Was bedeutet das "goto $-1" genau? D.h. auf welche Adresse verweist $-1?
Das Problem ist jetzt, nachdem ich diese beiden Zeilen bei jeder
Write-Routine eingefügt habe, dass der Pic auf gar keine Eingabe mehr
reagiert, keinen Taster und auch den Encoder nicht. Woran könnte das
liegen?
Gruss
Martin
Die special function register (SFR) EECON1 und EECON2 liegen auf der
Registerbank 3, um die anzusprechen muss vorher noch STATUS,RP1 gesetzt
werden (danach natürlich wieder zurücksetzen).
Beispiel:
asm
bsf status, RP0 ; Bank1
bcf intcon, GIE ; Disable INTs
bsf eecon1, WREN ; Enable Write
movlw 055h ;
bsf status, RP1 ; Bank3
movwf eecon2 ; 55h must be written to EECON2
movlw 0AAh ; to start write sequence
movwf eecon2 ; Write AAh
bcf status, RP1 ; Bank1
bsf eecon1, WR ; Set WR bit begin write
bsf intcon, GIE ; Enable INTs
endasm
Hallo
Vielen Dank auch dir Dieter für die Antwort. Funktionieren tat es nur
mit dieser Änderung leider nach wie vor nicht, aber du hast mich auf das
Problem aufmerksam gemacht.
Ich habe mir dann das mit den Bänken mal genauer überlegt und habe
gemerkt, dass z.B. eecon1 auch auf Bank3 ist, und den Code entsprechend
angepasst:
asm
bsf status, RP0 ; gehe auf Bank1
bcf intcon, GIE ; lösche dort Bit GIE
bsf status, RP1 ; gehe auf Bank3
bsf eecon1, WREN ; setze dort Bit WREN
movlw 055h ;
movwf eecon2 ; schreibe 55h in eecon2
movlw 0AAh ;
movwf eecon2 ; schreibe AAh in eecon2
bsf eecon1, WR ; bleibe auf Bank3 weil eecon1 auch dort
ist
bcf status, RP1 ; gehe wieder auf Bank1
bsf intcon, GIE ; setze dort WIE wieder
endasm
Ebenso beim Lesen, dort sind eeadr auf Bank2 und eedata auf Bank3, dann
muss es so heissen:
asm
bcf status, RP0 ;
bsf status, RP1 ; Bank2
movlw 0x00 ; Read address 0 in EEPROM space
Movwf eeadr ; Address to read
bsf status, RP0 ; Bank3
bsf eecon1, RD ; EE Read
bcf status, RP0 ; Bank2
movf eedata, W ; W = EEDATA
bcf status, RP1 ;
bsf status, RP0 ; kehre wieder zu Bank1 zurück
endasm
Nun scheint das ganze auch tatsächlich zu funktionieren! Ich war mir der
ganzen Bank-Sache einfach gar nicht bewusst, aber jetzt leuchtet es mir
ein. Ich möchte nach wie vor nicht mein ganzes Programm in Assembler
schreiben, aber vielleicht verliert es ja doch einmal den "Buch mit 7
Siegeln"-Status.
Danke an alle.
Gruss
Martin
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.