... aber es is auch schon spät :-)
jemand ne ahnung warum hier nix ins eeprom geschrieben wird?
(Es kommen daten über den uart rein, das hab ich geprüft)
; Daten empfangen mit Interrupt
; und zur?cksenden
.include "m162def.inc"
.def temp = r16
.def temp_save = r17
.def sreg_saveW = r18
.def sreg_saveI = r19
.def save = r20
.equ CLOCK = 4600000
.equ BAUD = 4800
.equ UBRRVAL = CLOCK/(BAUD*16)-1
; hier geht das Programmsegment los
.CSEG
.org 0x00
rjmp main
.org URXC0addr
rjmp int_rxc
; Hauptprogramm
main:
ldi temp, LOW(RAMEND) ; Stackpointer initialisieren
out SPL, temp
ldi temp, HIGH(RAMEND)
out SPH, temp
ldi temp, LOW(UBRRVAL) ; Baudrate einstellen
out UBRR0L, temp
ldi temp, HIGH(UBRRVAL)
out UBRR0H, temp
ldi temp, (1<<URSEL0)|(3<<UCSZ00) ; Frame-Format: 8 Bit
out UCSR0C, temp
sbi UCSR0B, RXCIE ; Interrupt bei Empfang
sbi UCSR0B, RXEN ; RX (Empfang) aktivieren
ldi ZL,low(daten) ; der Z-Zeiger wird hierexclusiv
ldi ZH,high(daten) ; für die
Datenadressierungverwendet
ldi save,30
sei ; Interrupts global aktivieren
loop:
rjmp loop ; Endlosschleife
(ABERInterrupts!)
; Interruptroutine wird ausgeführt,
; sobald ein Byte über den UART empfangen wurde
int_rxc:
mov temp_save, temp
in sreg_saveI, sreg
in temp, UDR ; empfangenes Byte lesen
push temp
dec save
breq writeStack ;solange das Register noch nicht einmal
übergelaufen ist wird auch nix gespeichert
out sreg,sreg_saveI
mov temp,temp_save ; temp wiederherstellen
reti
; der eigentliche EEPROM Schreibzugriff
; Adresse in ZL/ZH
; Daten in temp
writeStack:
cli ; Interrupts sperren,
dienächsten
; zwei Befehle dürfen NICHT
; unterbrochen werden
ldi save,30
writeStackLoop:
pop temp
rcall EEPROM_write ; Byte im EEPROM speichern
adiw ZL,1 ; Zeiger erhöhen
cpi ZL,low(EEPROMEND+1) ; Vergleiche den Z Zeiger
ldi temp,high(EEPROMEND+1) ; mit der maximalen
EEPROMAdresse +1
cpc ZH,temp
brne int_rxc_1 ; wenn ungleich, springen
ldi ZL,low(Daten) ; wenn gleich,
Zeigerzurücksetzen
ldi ZH,high(Daten)
int_rxc_1:
dec save
brne writeStackLoop ;Daten schreiben solange Z != 0
reti
EEPROM_write:
sbic EECR, EEWE ; prüfe ob der
letzteSchreibvorgang beendet ist
rjmp EEPROM_write ; wenn nein, nochmal prüfen
out EEARH, ZH ; Adresse schreiben
out EEARL, ZL ;
out EEDR,temp ; Daten schreiben
in sreg_saveW,sreg ; SREG sichern
sbi EECR,EEMWE ; Schreiben vorbereiten
sbi EECR,EEWE ; Und los !
out sreg, sreg_saveW ; SREG wieder herstellen
ret
; hier wird der EEPROM-Inhalt definiert
.ESEG
Daten:
.db 0
Hallo,
wenn Du den Kram etwas aufräumen würdest, könnte man es sogar
nachverfolgen...
int_rxc:
mov temp_save, temp
in sreg_saveI, sreg
in temp, UDR ; empfangenes Byte lesen
push temp
dec save
breq writeStack ;solange das Register noch nicht einmal
übergelaufen ist wird auch nix gespeichert
out sreg,sreg_saveI
mov temp,temp_save ; temp wiederherstellen
reti
und was passiert mit dem temp auf dem Stack wenn nicht gespeichert
wird???
Ansonsten: Du weißt, wie lange das Schreiben des EEPROM dauert und wie
lange es dauert, ein Zeichen mit 4800 Baud zu empfangen?
Solange Du nur mit der Tastatur tippst, mag es klappen, ansonsten
schreibt man in der RX-Interruptroutine nicht ins EEPROM.
Gruß aus Berlin
Michael
Da fehlt ein SEI am Ende der Interruptroutine. Grüße Björn
@Bjorn Nein, das SEI fehlt nicht, das wird durch RETI erledigt...
Peter wrote:
> Nein, das SEI fehlt nicht, das wird durch RETI erledigt...
Ups! das wusste ich ja noch garnicht...
Kann ich mir das ja in Zukunft sparen.
Danke.
Grüße
Björn
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.