Forum: Mikrocontroller und Digitale Elektronik Vielleicht is es nur n recht dämlicher fehler.


von TS (Gast)


Lesenswert?

... 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

von Michael U. (amiga)


Lesenswert?

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

von Björn W. (bwieck)


Lesenswert?

Da fehlt ein SEI am Ende der Interruptroutine.

Grüße
Björn

von Peter (Gast)


Lesenswert?

@Bjorn

Nein, das SEI fehlt nicht, das wird durch RETI erledigt...

von Björn W. (bwieck)


Lesenswert?

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
Noch kein Account? Hier anmelden.