;**************************************************************************************** ;* Am Beispiel des AT-Tiny 2313 wird ein 16-Segment Display in Betrieb genommen. * ;* Bauanleitung bei http://www.avr-projekte.de * ;* Autor: Jürgen Woetzel * ;* Version vom 16.08.09 * ;**************************************************************************************** .include "tn2313def.inc" .device attiny2313 ;------------------------------------------------------------------------------------- .def S =r5 ;SRegister .def temp =r16 ;Trash .def temp1 =r17 ; .def temp2 =r18 ; .def itemp =r19 ;Bit-Zähler für Digits (Multiplex 16Seg) .def tick =r25 ;Zähler für div. Timings ;------------------------------------------------------------------------------------- ;Schieberegister 74HC595 für 16Seg.-Display .equ S_Port = PORTB ;Port des 74HC595 .equ S_DRR = DDRB ;Datenrichtung .equ RClock = 2 ;74HC595 Schieberegister -> Latch (steigende Flanke) .equ Clock = 1 ;74HC595 Takt (steigende Flanke) .equ SerD = 0 ;74HC595 Daten ;------------------------------------------------------------------------------------- .cseg .org 0 rjmp Reset ;------------------------------------------------------------------------------------- ;ISR .org OVF0addr in S,sreg ;Verschiedene Register sichern push temp push temp1 push temp2 push ZH push ZL inc tick ;Variable für Warteschleifen inc itemp ;Digitzähler +1, zählt immer nur von 0..3 ... cbr itemp,0b11111100 ;... und wird als Index auf das aktive Digit benutzt. ;************************************************************************************************ ;* Multiplexen der 16Segment Anzeige * ;* alle 2 ms wird eine der 4 Anzeigen (gem. Anode, Treiber low Aktiv) eingeschaltet (welche * ;* steht in itemp). * ;* Der entsprechende ASC-Code steht im SRam Dig1..4. Die ISR holt den zugehörenden ASC-Code * ;* und ermittelt damit den passenden 16Seg.-Code den er in die Schieberegister taktet. * ;* Im Mainprg. wird nur noch der ASC-Code nach dig1..4 geschrieben, den Rest macht die ISR. * ;************************************************************************************************ ;Erstes Byte in den 595 shiften. Bit0..3 =Digit(0=Digit ein), Bit7 =0 für DP ein. mov temp1,itemp ser temp ;temp = -1 clc ;Null an die richtige Pos. schieben nxtr: rol temp ;Anhand von itemp das richtige.. dec temp1 ;Digit schalten brpl nxtr ;>> in temp steht jetzt für das richtige Digit eine Null ;Wenn nötig, DP (Dezimalpunkt) einschalten mov temp1,temp com temp1 lds temp2,dpmem ;ein 0Bit im unteren Nibble schaltet den DP ; com temp2 ;ein 1Bit schaltet DP wenn nicht auskommentiert and temp1,temp2 brne noDP cbr temp,$80 ;DP ein noDP: rcall HC595 ;Erstes Byte in den HC595 takten ldi YH,high(Dig1) ;Zeiger auf Display SRAM ldi YL,low(Dig1) ;Y zeigt nun auf 1.Digit add YL,itemp ;aktuelles Digit addieren ld temp,Y ;in temp steht nun der ASCii Code des aktuellen Digit lsl temp ;;mal 2, pro Char sind 2 Bytes in der ASCTab. ldi ZH,high(ASCTab<<1) ;Zeiger auf ASCTab ldi ZL,low(ASCTab<<1) add ZL,temp ;+ offset lpm temp,Z+ ;1. Bitmuster -> Temp rcall hc595 ;Temp raustakten lpm temp,Z ;2.Bitmuster rcall hc595 ;und raus cbi S_Port,RClock ;Palim Palem,Steigende Flanke an RClock.. sbi S_Port,RClock ;..schreibt das Schieberegister in die Latches TIM0_OVF_exit: ;ISR Ende pop ZL ;Register Zurücklesen pop ZH pop temp2 pop temp1 pop temp out sreg,S reti ;---------------------------------------------------------------------- ;Taktet das Byte temp in das Schieberegister, vllt. noch als Makro machen,spart 3* rcall+ret HC595: sec ;Carry für Schleifenende rol temp ;erstes Datenbit ->C, C(Schleifenende) -> Temp (Bit0=1) rjmp shift ;Erstes Datenbit an Port legen nxbit: lsl temp ;Datenbit raus, Null rein breq ex1 ;das letzte Carry war meins und geht nichtmehr raus shift: brcc bit0 ;ist Datenbit =0? sbi S_Port,SerD ;nein, es ist 1 rjmp bit1 ;an Clock Läuten bit0: cbi S_Port,SerD ;Datenbit =0 bit1: cbi S_Port,Clock ;Steigende Flanke an Clock.. sbi S_Port,Clock ;.. schiebt das Bit in den HC595 rjmp nxbit ;Das ganze nochmal ex1: ret ;-------------------------------------------------------------------- ;-------------------------------------------------------------------- ;Init Reset: ldi temp,RAMEND ;Stack Init out SPL,temp ;Wie immer ans Ende des SRAM ;Timer Init ldi temp,1<<" .db 16,17,18,19,20,21,22,23,24," ",0 ;------------------------------------------------------------------------------------------ ;16 Segment ASCTabelle, das erste Byte enthält sie Segmente K..U, Byte2 A..F ;Low aktiv! 0=Segment ein 1=Segment aus ;Da man die Codes 0..15 eh nicht Darstellen kann habe ich 0..9 und A..F in die ;ersten 16 Tabellenpos. geschrieben. Das spart etwas Umrechnungszeit bei Dez - Hex Routinen ;------------------------------------------------------------------------------------------ .org $300 ;An gerade Adresse setzen, das spart der ISR Zeit da ZH nicht geprüft werden muss ASCTab: .db 0b11111111,0b00000000 ;0 .db 0b11011111,0b11001111 ;1 .db 0b11101110,0b00010001 ;2 .db 0b11101111,0b00000011 ;3 .db 0b11101110,0b11001110 ;4 .db 0b11101110,0b00100010 ;5 .db 0b11101110,0b00100000 ;6 .db 0b11011011,0b00111111 ;7 .db 0b11101110,0b00000000 ;8 .db 0b11101110,0b00000010 ;9 .db 0b11101110,0b00001100 ;A .db 0b10101011,0b00000011 ;B .db 0b11111111,0b00110000 ;C .db 0b10111011,0b00000011 ;D .db 0b11101110,0b00110000 ;E .db 0b11111110,0b00111100 ;F ;meine Sonderzeichen .db 0b10111011,0b01011000 ;0 Grad .db 0b11111010,0b01011010 ;5 Grad .db 0b10101111,0b10011111 ;Grad .db 0b11111111,0b11110011 ;Cursor .db 0b11110011,0b11101101 ;IN (für Innentemperatur) .db 0b11111010,0b111111001 ;OUT (für Aussen) .db 0b01110111,0b00000000 ;0 mit Schrägstrich .db 0b01111101,0b11111100 ;$18 Rechts .db 0b11010111,0b11001111 ;$19 Links ;ASCii .org ASCTab+32 .db 0b11111111,0b11111111 ;Space .db 0b11111111,0b11001111 ;! .db 0b10111111,0b11111110 ;" .db 0b10101010,0b11000011 ;# .db 0b10101010,0b00100010 ;$ .db 0b10001000,0b01100110 ;% .db 0b10011001,0b10100011 ;& .db 0b11011111,0b11111111 ;' .db 0b10111011,0b10110111 ;( .db 0b10111011,0b01111011 ;) .db 0b00000000,0b11111111 ;* .db 0b10101010,0b11111111 ;+ .db 0b11111101,0b11111111 ;, .db 0b11101110,0b11111111 ;- .db 0b11111010,0b11111001 ;. .db 0b11011101,0b11111111 ;/ .db 0b11111111,0b00000000 ;0 .db 0b11011111,0b11001111 ;1 .db 0b11101110,0b00010001 ;2 .db 0b11101111,0b00000011 ;3 .db 0b11101110,0b11001110 ;4 .db 0b11101110,0b00100010 ;5 .db 0b11101110,0b00100000 ;6 .db 0b11011011,0b00111111 ;7 .db 0b11101110,0b00000000 ;8 .db 0b11101110,0b00000010 ;9 .org ASCTab+65 ;ATM kein Bock auf Sonderzeichen .db 0b11101110,0b00001100 ;A .db 0b10101011,0b00000011 ;B .db 0b11111111,0b00110000 ;C .db 0b10111011,0b00000011 ;D .db 0b11101110,0b00110000 ;E .db 0b11111110,0b00111100 ;F .db 0b11101111,0b00100000 ;G .db 0b11101110,0b11001100 ;H .db 0b10111011,0b11111111 ;I .db 0b11111111,0b10000001 ;J .db 0b11001110,0b11101100 ;K .db 0b11111111,0b11110000 ;L .db 0b01011111,0b11001100 ;M .db 0b01110111,0b11001100 ;N .db 0b11111111,0b00000000 ;O .db 0b11101110,0b00011100 ;P .db 0b11110111,0b00000000 ;Q .db 0b11100110,0b00011100 ;R .db 0b11101110,0b00100010 ;S .db 0b10111011,0b00111111 ;T .db 0b11111111,0b11000000 ;U .db 0b11011101,0b11111100 ;V .db 0b11110101,0b11001100 ;W .db 0b01010101,0b11111111 ;X .db 0b01011011,0b11111111 ;Y .db 0b11011101,0b00110011 ;Z .org ASCTab+97 ;Die Kleinbuchstaben will ich mir ATM net geben, also vorerst alles in Grossschrift .db 0b11101110,0b00001100 ;A .db 0b10101011,0b00000011 ;B .db 0b11111111,0b00110000 ;C .db 0b10111011,0b00000011 ;D .db 0b11101110,0b00110000 ;E .db 0b11111110,0b00111100 ;F .db 0b11101111,0b00100000 ;G .db 0b11101110,0b11001100 ;H .db 0b10111011,0b11111111 ;I .db 0b11111111,0b10000001 ;J .db 0b11001110,0b11101100 ;K .db 0b11111111,0b11110000 ;L .db 0b01011111,0b11001100 ;M .db 0b01110111,0b11001100 ;N .db 0b11111111,0b00000000 ;O .db 0b11101110,0b00011100 ;P .db 0b11110111,0b00000000 ;Q .db 0b11100110,0b00011100 ;R .db 0b11101110,0b00100010 ;S .db 0b10111011,0b00111111 ;T .db 0b11111111,0b11000000 ;U .db 0b11011101,0b11111100 ;V .db 0b11110101,0b11001100 ;W .db 0b01010101,0b11111111 ;X .db 0b01011011,0b11111111 ;Y .db 0b11011101,0b00110011 ;Z ;--------------------------------------------------------------------------------------- .dseg .org SRAM_START Dig1: .byte 1 Dig2: .byte 1 Dig3: .byte 1 Dig4: .byte 1 DPmem: .byte 1