Forum: Mikrocontroller und Digitale Elektronik EEPROM lesen ATMEGA644 Assembler


von Martin Teves (Gast)


Lesenswert?

Ich habe versucht ein Bascom Programm in assembler zu übersetzen, um es 
im Anschluss zu optimieren.

Funktion: Am Int0 hängt ein Rechteckgenerator. Bei jeder positiven 
Flanke wird ein Bitmuster am PortB ausgegeben und der nächste Wert aus 
dem EEPROM gelesen. Nach 240 Werten soll wieder von vorne begonnen 
werden.


Aber das Programm tut irgendwie nicht das was es soll. Wo liegt mein 
Fehler?

.include "m644def.inc"

.org 0x000
         rjmp main            ; Reset Handler
.org INT0addr
         rjmp int0_handler    ; IRQ0 Handler


main:


.cseg

;Stackpointer initialisieren
    ldi     r16, low(RAMEND)
    out     SPL, r16
    ldi     r16, high(RAMEND)
    out     SPH, r16

;Port B als Ausgang
    ldi     r16, 0xFF
    out     DDRB, r16

;Interrupt Int0 auf steigende Flanke
 lds  r16,EICRA
 sbr  r16, 1<<ISC01 | 1<<ISC00
 sts  EICRA, r16

;Interrupt Int0 einschalten
 ldi  r16, 0x01
 out  EIMSK, r16


 sei         ; Interrupts global einschalten


 ldi     ZL,0x00                     ; Z-Zeiger laden. Der Einfachheit 
direkt adressiert
    ldi     ZH,0x00
    rcall   EEPROM_read                 ; Aufruf des Unterprogramms 
Daten aus EEPROM lesen




loop:
    rjmp loop

int0_handler:


    out     PORTB, r16
    inc     ZL
 cpi  ZL,0xF1
 brne    weiter
 ldi  ZL,0x00
weiter:
    rcall   EEPROM_read                 ; Aufruf des Unterprogramms 
Daten aus EEPROM lesen


   reti


EEPROM_read:
    sbic    EECR,EEPE                   ; prüfe ob der vorherige 
EEPROMzugriff beendet ist


    rjmp    EEPROM_read                 ; nein, nochmal prüfen

    out     EEARH, ZH                   ; Adresse laden EEAR=EEPROM 
adress register
    out     EEARL, ZL
    sbi     EECR, EERE                  ; Lesevorgang aktivieren
    in      r16, EEDR                   ; Daten  aus dem EEprom Daten 
Register ins CPU Register kopieren
    ret


; Daten im EEPROM definieren
.eseg


dta1:
.db 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 1
.db 0 , 1 , 0 , 1 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3
.db 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3
.db 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3
.db 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3
.db 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3
.db 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3
.db 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3
.db 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3
.db 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 3 , 3 , 3 , 3
.db 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3
.db 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3
.db 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3
.db 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3
.db 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3
.db 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3
.db 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3
.db 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3
.db 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3 , 2 , 3
.db 2 , 3 , 2 , 3 , 2 , 3 , 2 , 1 , 1 , 1 , 1 , 1

von Ben (Gast)


Lesenswert?

was funktioniert den nicht bzw. in welcher form zeigt sich der fehler? 
kommt müll raus oder reagiert der AVR gar nicht erst?

übrigens ist der erste wert der ausgegeben wird schrott, da dieser nicht 
aus dem eeprom gelesen wird sondern nach dem ablauf deiner 
initialisierung in R16 stehengeblieben ist. ich würd das dahingehend 
ändern, daß die werte zuerst aus dem eeprom gelesen und danach 
ausgegeben werden.

von Ben (Gast)


Lesenswert?

sehe gerade du lädst R16 noch in der initialisierung mit dem ersten 
wert. okay, aber ich würds trotzdem ändern. spätestens wenn er AVR 
irgendwann noch mehr machen soll als EEPROM->PortB gibts probleme damit.

von Thomas (Gast)


Lesenswert?

Nur mal kurz ein paar Gedankengänge:

1) Erst die Interrupts enablen und dann danach den Pointer 
initialisieren? Das sollte in ungedrehter Reihenfolge geschehen!

2) Warum die Tabelle im EEProm speichern? Wird sie während das Programm 
läuft geändert? Wenn nicht, würde ich die Tabelle im Programmspeicher 
unterbringen, du sparst dir dann das Unterprogramm für's EEProm lesen 
und brauchst nur noch ein Befehl (LPM).

3) Du solltest in der Hauptschleife nichts machen und das Lesen und 
Ausgeben zusammen in den Interrupt legen, in der Initialisierung nur den 
Z-Pointer auf den ersten Eintrag und dann auf einen Interrupt warten.


Gruß,
Thomas

von Martin Teves (Gast)


Lesenswert?

1) Stimmt, am besten auch erst nach dem ersten Lesevorgang

2) Ja grundsätzlich sollte das in Zukunft über RS232 nachladbar sein. Ob 
ich das so lasse, muss ich mir nochmal überlegen. Vielleicht reicht mir 
auch der Flash-Speicher für die anderen Daten und mach es nicht mehr 
nachladbar.

von bastler_1651 (Gast)


Lesenswert?

hast du die eepromdaten auch in den atmega geladen? afaik macht der das 
nicht immer automatisch

von Martin Teves (Gast)


Lesenswert?

Ja, EEPROM-Daten habe ich manuell reingeladen und EEPROM File habe ich 
auch überprüft, ist korrekt.

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.