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.