Huhu,
ich will eine 7-Segment-Anzeige mit dem Attiny2313 ansteuern und habe
mir dazu das Tutorial hier auf der Seite
http://www.mikrocontroller.net/articles/AVR-Tutorial:_7-Segment-Anzeige
angeschaut. Ich habe sogar eine Anzeige mit gemeinsamer Anode, weshalb
ich die Schaltung leicht adaptieren konnte.
Den Code zum ersten Beispiel habe ich soweit übernommen, nur zähle ich
bei mir herunter und ich lasse das ganze nicht in der normalen loop
laufen, sondern in einem Interrupt-Timer (Compare und zum Testen bis
Maximum).
Das Problem: Wenn ich den µC anmache, dann leuchtet kurz eine "8" und
danach nichts mehr.
Ich schließe Fehler im Timercode oder der Schaltung aus, da
richtigerweise undefinierbare Zeichen in zeitlich regelmäßigen Abständen
auf der Anzeige erscheinen, wenn ich einfach das Register "Count" statt
R0 auf PORTB ausgebe.
Deshalb vermute ich, dass etwas mit Zuweisung der Ziffer aus dieser
"Datenbank" nicht stimmt, also diese Codetabelle. Muss ich da etwas
beachten, wenn ich den Code im Beispiel für den Attiny2313 übernehmen
will? Ist da etwas anders als beim Atmega?
Hier noch der Code:
1
.INCLUDE "tn2313def.inc"
2
3
.def temp = R16
4
.def count = R17
5
.def zero = R1
6
7
.org 0x0000 rjmp RESET
8
.org 0x000D rjmp TIM0_COMPA ;Timer/Counter Compare Match A
Im Timerinterrupt willst du zu ZH das Register zero addieren, das aber
bevor in die Endlosschleife eingetreten wurde mit 9 versehen wird!
Sonst konnte ich gerade keinen Fehler feststellen.
Warum machst du im Timerinterrupt den Umweg beim addieren des counters
zu Z über temp???
julian
Hi
>Das Problem: Wenn ich den µC anmache, dann leuchtet kurz eine "8" und>danach nichts mehr.>ldi count, 9>mov zero, count
zero<> 9
>mov temp, count ;die wortweise Adressierung der Tabelle>add temp, count ;berücksichtigen
Das kannst du dir sparen, wenn du die Tabelle so anlegst:
1
Codes: ;Die Codetabelle für die Ziffern 0 bis 9
2
.db 0b11000000, 0b11111001
3
.db 0b10100100, 0b10110000
4
.db 0b10011001, 0b10010010
5
.db 0b10000010, 0b11111000
6
.db 0b10000000, 0b10010000
>dec count>breq resetCount>reti>resetCount:>ldi count, 9>reti
Damit wird aber die '0' nie angezeigt.
1
subi count,1
2
brcs resetCount
3
reti
4
resetCount:
5
ldi count, 9
6
reti
Im Moment macht sich das durch die leere Loop-Schleife nicht bemerkbar.
Aber du solltest in der Interruptroutine SREG sichern und wieder
zurückschreiben.
MfG Spess
Ich hätte da mal noch eine allgemeine Frage zu diesen "Tabellen".
add ZL, count
adc ZH, zero
kann ich nur machen, weil ich ja nur 9 Ziffern und die 0 habe oder? Ich
meine, im ZH würde es mit mehr Einträgen ja gar nicht weiterzählen, da
steht ja jetzt maximal eine 1 drin, verstehe ich das richtig? Wenn man
jetzt eine größere Tabelle hätte und man wöllte die Werte auslesen,
könnte man die dann so auslesen?:
add ZL, LOW(count)
add ZH, HIGH(count)
oder wie ginge das?
Hi
>danke für die Hinweise Jetzt funktionierst :)
Schön zu hören. Aber noch etwas, das ich etwas verdrängt hatte: Es ist
sinnvoll, wenn Interruptroutinen nur einen Austrittspunkt
Niklas Beuster schrieb:> Ich hätte da mal noch eine allgemeine Frage zu diesen "Tabellen".>> add ZL, count> adc ZH, zero>> kann ich nur machen, weil ich ja nur 9 Ziffern und die 0 habe oder?
Nö
> Ich> meine, im ZH würde es mit mehr Einträgen ja gar nicht weiterzählen, da> steht ja jetzt maximal eine 1 drin, verstehe ich das richtig?
Warum soll da 1 drinnen stehen? Was da drinnen steh, hängt von der
Vorbelegung ab, also wo genau im Speicher die Tabelle angeordnet wurde.
> Wenn man> jetzt eine größere Tabelle hätte und man wöllte die Werte auslesen,> könnte man die dann so auslesen?:>> add ZL, LOW(count)> add ZH, HIGH(count)>> oder wie ginge das?
Zuallererst eimal wäre dann count kein 8-Bit Register :-)
sondern irgendwas mit 16 Bit. Und dann addierst du Low-Byte mit Low-Byte
und High-Byte mit High-Byte. Aber immer schön einen adc für das
High-Byte verwenden. Du musst ja den eventuellen Carry vom Low-Byte ins
High-Byte mitnehmen.
> Zuallererst eimal wäre dann count kein 8-Bit Register :-)> sondern irgendwas mit 16 Bit.
Achso, klar. Habe da wohl was durcheinander gebracht. Die ZL und ZH
Register sind wohl 16 Bit groß? Muss ich mir mal genauer anschauen...
Danke jedenfalls.
Niklas Beuster schrieb:> Die ZL und ZH> Register sind wohl 16 Bit groß?
Zusammen ja...
Jedes einzelne ist nur 8 Bit groß, aber beide zusammen bilden einen
Pointer (Adresszeiger), der auf einen Speicherbereich zeigt, dessen
Adresse 16 Bit groß sein kann (also bis 64k). Bei größeren AVRs gibt es
dann noch eine Verlängerung des Pointers im I/O-Bereich und einen
erweiterten LPM-Befehl.
Niklas Beuster schrieb:> Muss ich mir mal genauer anschauen...
Das solltest Du tun. Achte dabei darauf, wann der Flash byteweise
adressiert wird (LPM) und wann wordweise (IJMP, ICALL). Und beachte
auch, dass man diesen Z-Pointer (und auch die Pointer X und Y) auch für
SRAM-Zugriffe nutzen kann, dann aber etwas anders handhaben muss.
Falls Du mal ein Beispiel betreffs Multiplexing einer
Lichtschachtanzeige sehen willst, dann schau mal hier:
http://www.hanneslux.de/avr/divers/pm24/index.htmlhttp://www.hanneslux.de/avr/divers/pm24/vm24ko01.asm
...