;****** Multiplex7Seg 1.2 (c) Oliver Mezger 15.12.2010 .include "m16def.inc" ;*** Zuordnung zu den Ports *** .equ SegmentIn = PINA .equ SegmentOut = PORTA .equ SegmentDdr = DDRA .equ TastaturIn = PINB .equ TastaturOut = PORTB .equ TastaturDdr = DDRB .equ StelleIn = PINC .equ StelleOut = PORTC .equ StelleDdr = DDRC .def null = R23 ;Register mit 0 .def tmp = R16 ;tmp-Register zum Arbeiten .def tmp2 = R17 .def spalte = R18 ;Spalte fuer Darstellung .def zeichen = R19 ;Index des Zeichens .def durchlauf = R20;Zaehler fuer Zeichenwechsel .def itmp = R21 ;tmp-Register fuer Interrupt .def led = R22 ;RGB-LED animieren jmp reset ;Einsprung nach Reset .org OVF0addr ;Einsprung nach Timer0 Ueberlauf jmp isr_timer ;nach ISR .org $2a ;folgender Code ab Adresse $2a isr_timer: in itmp,SREG ;SREG retten push itmp ldi itmp, 150 ;Interrupttimer einstellen out TCNT0,itmp cpi spalte,0b00010000 ;wenn nicht Spalte 5 brlo nspalte ;dann naechste Spalte ldi spalte,1 ;Spalte1 initialisieren ldi XH, high(anzeige) ;Datenzeiger initialisieren ldi XL, low(anzeige) nspalte: ;naechste Spalte ld itmp,x+ ;lade Wert aus anzeige und erhoehe x ;wandle Wert in 7-Segmentmuster um ldi ZH, high(bcd_7*2) ;Datenzeiger im Programmspeicher initialisieren ldi ZL, low(bcd_7*2) add ZL,itmp ;Addiere Wert um zum Eintrag zu kommen adc ZH,null lpm itmp, z ;lade Daten aus Flash-Programmspeicher out SegmentOut,itmp ;gib 7-Segmentmuster aus in itmp, StelleOut ;schalte die Stelle ein andi itmp,0b11110000 or itmp,spalte out StelleOut,itmp lsl spalte ;naechste Stelle pop itmp ;SREG wieder herstellen out SREG,itmp reti ;return from Interrupt reset: ;Hauptprogramm ldi tmp,high(RAMEND);Oberste RAM-Adresse holen out SPH, tmp ;Stack-Pointer initialisieren ldi tmp,low(RAMEND) out SPL, tmp ldi tmp,$ff out SegmentDdr,tmp ;SegmentPort als Ausgang out StelleDdr,tmp ;StellenPort als Ausgang ldi tmp,0b11101111 ;Tastatur init out TastaturOut,tmp ldi tmp,0b00010000 out TastaturDdr,tmp ldi tmp,3 ;Systemtakt / 64 out TCCR0,tmp ;Timer setzen in tmp,TIMSK ;Timerinterrupt einschalten ori tmp, 1 << TOIE0 out TIMSK,tmp ldi null,0 ldi XH, high(anzeige) ;Datenzeiger initialisieren ldi XL, low(anzeige) st X+,null ;Feld mit 0 initialisieren st X+,null st X+,null st X+,null sei ;globale Interruptfreigabe loop: ;Schleife fuer Tastaturabfrage sbis TastaturIn,0 ;wurde Taste gedrueckt? rjmp taste inc led ;Animation der FarbLED andi led,7 ;nur von 0 bis 7 mov tmp,led swap tmp ;vertausche Nibble lsl tmp ;und noch einmal schieben in tmp2,StelleOut ;schreibe auf StelleOut andi tmp2,0b00011111 or tmp2,tmp out StelleOut,tmp2 rcall wait rjmp loop taste: sbis TastaturIn,0 ;Taste immer noch gedrueckt rjmp taste rcall zaehle ;wenn losgelassen erhoehe zaehler um 1 rjmp loop zaehle: ;der Zaehler wird um 1 erhoeht ldi YH, high(anzeige) ;Datenzeiger initialisieren ldi YL, low(anzeige) nextstelle: ld tmp,y ;lade Stelle cpi tmp,9 ;ist sie 9? breq ueberlauf ;Ueberlauf auf naechste Stelle inc tmp ;sonst erhoehe um 1 st y,tmp ret ueberlauf: ;erhoehe naechste Stelle st y,null adiw y,1 rjmp nextstelle wait: ldi tmp,50 ;aeusseren Zaehler laden 50 ms wl1: ldi tmp2,250 ;inneren Zaehler 1ms bei 1Mhz wl2: nop dec tmp2 ;tmp2-- brne wl2 ;Sprung wenn nicht null dec tmp ;tmp-- brne wl1 ;Sprung wenn nicht null ret bcd_7: ;Feld fuer BCD nach 7-Segment Wandlung .db 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f .dseg; Datenbereich anzeige: ;Feld fuer die 4 Stellen .byte 4; Feld mit 4 Byte