Hallo, habe ein Problem mit einer Multiplex Ansteuerung. Möchte folgendes machen: Eine Siebensegment Anzeige, die durch einen Latch (74HC573), die Zahlen 0 bis 9 hochzählen soll. Die Zahlen sind ind einer Tabelle in Hex-Form gespeichert. Jetzt will ich diese Auslesen und zur Anzeigen bringen. Vor dem Schreiben soll das Latch auf High gesetzt werden danach wieder auf Low. Bekomme aber nur die Null zur Anzeige. Was mache ich nur falsch? Habe mir schon die Zähne an der Tastatur ausgebissen. Anbei noch das Programm: .device AT90s8515 .include "C:\Programme\Atmel\AVR Studio\Appnotes\8515def.inc" ;Definition der Steuerleitungen .equ sek_ein = PA7 ; Sekunden Einer .equ sek_zen = PA6 ; Sekunden Zehner .equ min_ein = PA5 ; Minuten Einer .equ min_zen = PA4 ; Minuten Zehner .equ stu_ein = PA3 ; Stunden Einer .equ stu_zen = PA2 ; Stunden Zehner ; Variablendefinition .def zeichen = r0 ; Zeichen aus Tabelle .def counter = r17 ; Zaehler für die Anzeige .def temp = r18 .def buffer = r19 .def delay = r20 .def delay1 = r21 .CSEG .ORG 0x00 ; Programm beginnt bei 0 rjmp main ; Starte Hauptprogramm init: cli ldi temp,0b1111111 out DDRA,temp ret write_data: ldi temp,0b11111111 out DDRB,temp cbi porta,sek_ein out PORTB,buffer sbi porta,sek_ein ret main: ldi temp,RAMEND out SPL,temp rcall init ldi ZL,LOW(tabelle*2) ldi ZH,HIGH(tabelle*2) ldi counter,10 loop_msg1: lpm mov buffer,zeichen rcall write_data inc ZL brcc no_carry1 inc ZH no_carry1: dec counter brne loop_msg1 loop: rjmp loop ; Ziffern 0 1 2 3 4 5 6 7 8 9 Tabelle: .db 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90 Danke im voraus Michael T
Du darfst nix "rcall"en bevor der Stackpointer gesetzt ist! Und außerdem: inc ändert nix am Carry. Nimm einfach adiw zum erhöhen des Z-Pointers.
Hi! cbi setzt Ausgang auf 0 = Low Ausgabe sbi setzt Ausgang auf 1 = High Wolltest du es nicht andersrum?? Eine Verzögerung der Ausgabe vermisse ich ebenfalls, du wirst bestenfalls eine 9 sehen. Beachte auch die Flag's im Datasheet. Bei inc steht da Z,N,V. ADIW ist also völlig richtig. viel Erfolg Uwe
Danke, aber eine 9 ist da nicht das ganze bleibt bei 0 stehen. Gibt es da vieleicht noch eine andere Lösung? Viele Grüße Michael T
Oder ums noch deutlicher zu machen:
> Du darfst nix "rcall"en bevor der Stackpointer gesetzt ist!
heißt auch, daß der Stackpointer nicht richtig initialisiert wird. Der
besteht beim 8515 nämlich aus SPH und SPL. Aber das ist wohl nicht der
Grund für das Versagen des Programms. Das wird eher mit dem mehrfach
erwähnten inc/adiw zusammenhängen.
Schmittchen.
Öhm, was ich über den SP geschrieben habe vergeßt mal bitte wieder. Ich habe mir eingeildet das "rcall init" käme vor der Initialisierung des Stackpointers. Aber dass der Stack nicht richtig initialisiert ist stimmt natürlich, siehe Tutorial #3.
Habe ich alles probiert.
Mit dem "rcall"en, habe mich schon gewundert.
Das Programm geht in der Simulation wunderbar.
Doch bleibt es im Avr irgendwo hängen.
Habe ich vieleicht was übersehen.
Viele Grüße
Michael T
Jetzt geht es!
.include "C:\Programme\Atmel\AVR Studio\Appnotes\8515def.inc"
.def zeichen = r0
.def buffer = r16
.def counter = r17
.def delay =r18
.def delay1 =r19
.def temp = r20
.equ sek_ein = pa7
.CSEG
.ORG 0x0000
rjmp main
init: ldi temp,0b11111111 ;
out ddra,temp ;PORTA ist Ausgang
out ddrb,temp ;PORTB ist Ausgang
ret
output: sbi porta,sek_ein ;spreche Anzeige an
out portb,buffer ;sende Daten
cbi porta,sek_ein ;disable Anzeige
rcall dly ;springe zur Pause
ret
dly: dec delay
brne dly
dec delay1
brne dly
ret
main: ldi temp,LOW(ramend) ; Oberes Byte
out SPL,temp ; an Stapelzeiger
ldi temp,HIGH(ramend) ; Unteres Byte
out SPH,temp ; an Stapelzeiger
rcall init
Loop0: ldi counter,10 ;Zaehler für Zeichen
ldi ZL,LOW(Tabelle*2) ;Low-Zeiger auf Tabellenanfang
ldi ZH,HIGH(Tabelle*2) ;High-Zeiger auf Tabellenanfang
loop1: lpm ;hole Zeichen aus Tabelle
mov buffer,zeichen ;Zeichen uebergeben
rcall output ;schreibe Zeichen in Anzeige
adiw ZL,1 ;16-Bit Pointer um 1 erhoehn
nocarry: dec counter ;alle Zeichen gesendet?
brne loop1 ;Nein! Sende naechstes Zeichen
loop: rjmp main ;Programm wird neu gestartet
; Ziffern 0 1 2 3 4 5 6 7 8 9
Tabelle: .db 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90
Habe jetzt adiw genommen, aber mit "inc ZL" und "inc ZH" geht es auch.
Nur was ist jetzt der unterschied vom Stackpointer bei:
ldi temp, LOW(ramend) ; Oberes Byte
out SPL,temp ; an Stapelzeiger
ldi temp,HIGH(ramend) ; Unteres Byte
out SPH,temp ; an Stapelzeiger
zu: ldi temp,RAMEND
out SPL,temp
Weiss einer dazu die Antwort?
Gruß
Michael T
Wie meinen? Na einmal belegst du nur SPL mit einem Wert, das andere Mal SPL und SPH! SPH steht nach dem Einschalten auf 0x00, und das ist schon was anderes als 0x02, damit steht im ersten (richtigen) Fall der Stackpointer auf 0x025F, in deinem zweiten (nicht funktionierenden) Fall auf 0x005F. Irgendwann läuft dir da dann was rein. RAMEND = 0x025F HIGH(RAMEND) = 0x02 LOW(RAMEND) = 0x5F Schmittchen.
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.