Endlich war Zeit, meine Testschaltung auch mal aufzubauen.
Diese eignet sich gut für Lötübungen. Die Bauteile sind als 0805 angelegt. Ich habe bis auf die LEDs und den µC alle übrigen Teile (Widerstände, Kondensatoren) von alten Festplattenelektroniken mit einer Heißluftstation entnommen, was eben da war. Deshalb wurde nicht durchgängig mit 0805 bestückt und als Vorwiderstand 1k (102) bzw. sogar 10k (103) benutzt. 😉 Die LED sind trotzdem noch erkennbar an. Auf die LED angepasste Widerstände wären hier natürlich deutlich besser.
Die ursprüngliche Intention war der erste Versuch, mittels eagle und professionellem Hersteller Platinen zu entwerfen. Bisher wurde immer auf Lochraster gebastelt. Es ist also ein Erstlingswerk, ich bin mir bereits vieler Fehler bewußt. (z.B. für die Handlötung zu kleine Lötpads am IC, ging trotzdem erstaunlich gut; 15 LEDs wären möglich statt 11; keine Beschriftung der Lagen; ungeduldige 😉 Entflechtung; ungünstige Platzierung der Bauteilbeschriftungen usw.) Ungeachtet dessen funktionieren die Platinen zuverlässig und sind fehlerfrei. Gelötet wurde mit einem Weller WECP-20 mit meißelförmiger 2mm-Spitze mit verbleitem 0,5mm-Lötzinn. Als µC geeignet sind ATtiny2313(A), ATTiny4313, AT90S1200(A), AT90S2313(A) und auch AT89C2051/4051 (bei geänderter RESET-Beschaltung) Der ISP-Programmieradapter ist nur für die AVR nutzbar, die 8051-er müssen vorher programmiert werden. Die LEDs stammen aus dem SMD-LED-Sortiment von Pollin bzw. die 0603-Bauform von Reichelt. (z.B. Bestellnummer: LY L29K)
Das Programm wurde recht schnell „zusammengeworfen“, da es nur zum schnellen Test dienen soll:
.include "1200def.inc" ; Das Programm ist für den AT90S1200 geschrieben,
; für den ATTiny2313 oder andere sind Änderungen erforderlich!!
.equ XTAL = 3187200
.def i = r21 ; diverse Zwischenvariablen
.def Change = r22
.def Change_D = r23
.def Change_B = r24
.def temp = r25
.def DelCount_1 = r26 ; bestimmt die Dauer der äußeren Warteschleife
.def DelCount_2 = r27 ; mittlere Warteschleife
.def DelCount_3 = r28 ; innere Warteschleife
.org 0x0000
rjmp main ; Programmstart
rjmp EXT_INT0 ; IRQ0 Handler
rjmp TIM0_OVF ; Timer0 Overflow Handler
rjmp ANA_COMP ; Analog Comparator Handler
EXT_INT0:
TIM0_OVF:
ANA_COMP:
reti ; fehlgeleitete Interrupts abfangen (sollte eigentlich nicht vorkommen)
main:
ldi temp, 0xFF ; Port B und D auf Ausgang
out DDRB, temp
out DDRD, temp
main2: ldi Change, 0x00 ; Variablen initialisieren
ldi Change_B, 0x00
ldi Change_D, 0x03
// hier geht es los mit der Animation
// Effekt 1: versetztes Wechselblinken über alle LEDs
ldi i, 0x06 ; 6-mal sollst Du es tun
main1: ldi temp, 0xAA
out PORTB, temp
ldi temp, 0x55
out PORTD, temp
ldi DelCount_1, 0x05 ; 5 Warterunden
rcall wait
ldi temp, 0x55
out PORTB, temp
ldi temp, 0xAA
out PORTD, temp
ldi DelCount_1, 0x05 ; 5 Warterunden
rcall wait
dec i
cpse Change, i ; Schleife zu Ende?
rjmp main1
// Effekt 2: LED-Kette geht schrittweise an
ldi temp, 0xFF
out PORTB, temp
ldi temp, 0x30
schieben1: lsl temp ; zuerst PORTD anschalten
out PORTD, temp
ldi DelCount_1, 0x05 ; 5 Waitrunden
rcall wait
dec Change_D
cpse Change, Change_D
rjmp schieben1
ldi temp, 0xFF
schieben: lsl temp ; jetzt ist PORTB dran
out PORTB, temp
ldi DelCount_1, 0x05 ; 5 Waitrunden
rcall wait
cpse temp, Change_B
rjmp schieben
// Effekt 3: LEDs sind an, dunkler Punkt wandert durch die Kette
ldi Change_B, 0x78
ldi i, 0x80
mov temp, i
wandern: out PORTB, temp ; erst PORTB
lsr temp
dec i
ldi DelCount_1, 0x05 ; 5 Runden durch die Waitschleife
rcall wait
cpse Change_B, i
rjmp wandern
ldi Change_D, 0x04
ldi i, 0x40
ldi temp, 0x00
out PORTB, temp
mov temp, i
wandern2: out PORTD, temp ; dann PORTD
lsr temp
dec Change_D
ldi DelCount_1, 0x05 ; 5 Runden durch die Waitschleife
rcall wait
cpse Change, Change_D
rjmp wandern2
// Ein dunkler Punkt wird durchgeschoben
ldi i, 0x08
ldi temp, 0x80
Shift: out PORTB, temp
ror temp
dec i
ldi DelCount_1, 0x05 ; 5 Runden durch die Warteschleife
rcall wait
cpse Change, i
rjmp Shift
ldi i, 0x04
ldi temp, 0x00
out PORTB, temp
out PORTD, temp
ldi temp, 0x40
Shift1: out PORTD, temp
ror temp
dec i
ldi DelCount_1, 0x05 ; 5 Runden durch die Warteschleife
rcall wait
cpse Change, i
rjmp Shift1
rjmp main2 ; Animationsprogramm beginnt von vorn
; subroutine wait, keine Ahnung, wie lang die ist, zu faul zum Rechnen, daher reines Bauchgefühl,
; DelCount_1 muss vom Aufrufer gefüllt werden
wait:
delay2: ldi DelCount_2, 0xFF
delay1: ldi DelCount_3, 0xFF
delay: dec DelCount_3
cpse Change, DelCount_3
rjmp delay
dec DelCount_2
cpse Change, DelCount_2
rjmp delay1
dec DelCount_1
cpse Change, DelCount_1
rjmp delay2
ret