; vytvoril: DANYK ; http://danyk.cz ; Napsáno pro frekvenci 1MHz !!!!!!!!!!!!!!! .NOLIST .INCLUDE "m16def.inc" .LIST .DEF REG=R16 ;univerzalni docasny registr .DEF CIF1=R18 ;minuty .DEF CIF2=R19 ;10ky minut .DEF CIF3=R20 ;hodiny .DEF CIF4=R21 ;10ky hodin .DEF PR_ST_TL=R22 ;předchozí stav tlačítek .DEF PRODL_TL=R23 ;odpočítává prodlevu tlač. do další reakce .DEF DELREG=R24 ;bit0=polarita displeje, deleni 128Hz na 1/2Hz .DEF DELREG2=R25 ;deleni 1/2Hz na 1/60Hz .EQU SMER1=DDRA .EQU PORT1=PORTA .EQU SMER2=DDRB .EQU PORT2=PORTB .EQU SMER3=DDRC .EQU PORT3=PORTC .EQU SMER4=DDRD .EQU PORT4=PORTD .EQU PINY=PINC .CSEG .ORG 0 RJMP START ; vektory preruseni .ORG OC2addr ;preruseni citacem0 RJMP CITAC START: ;nastaví port 1 (bity 0...6) jako výstup LDI REG,0b01111111 OUT SMER1,REG LDI REG,0b11111111 OUT PORT1,REG ;nastaví port 2 jako výstup LDI REG,0xFF OUT SMER2,REG LDI REG,0xFF OUT PORT2,REG ;nastaví port 3 (bity 0123 vystup, 45 vstup) LDI REG,0b00001111 OUT SMER3,REG LDI REG,0b00111111 OUT PORT3,REG ;nastaví port 4 jako výstup LDI REG,0xFF OUT SMER4,REG LDI REG,0xFF OUT PORT4,REG LDI REG,LOW(RAMEND) OUT SPL,REG LDI REG,HIGH(RAMEND) OUT SPH,REG ; vynuluje/presnastavi registry LDI DELREG,255 LDI DELREG2,30 LDI CIF1,0 LDI CIF2,0 LDI CIF3,0 LDI CIF4,0 LDI PR_ST_TL,0 LDI PRODL_TL,0 ;vypne analog. komparator - neni nikdy vyuzit (setri energii) LDI REG,0b10000000 OUT ACSR,REG ; NASTAVENI CASOVACE A JEHO PRERUSENI CLI ;zakaze globalni preruseni LDI REG,0b00000000 ; zakaze preruseni OCIE2 OUT TIMSK,REG ; LDI REG,0b00001000 ; OUT ASSR,REG ; LDI REG,0b00001010 ; nulovani pri dosazeni porovnavane hodnoty... OUT TCCR2,REG ; ...(tzv. CTC), preddeli 8 LDI REG,31 ; nastavi porovnavanou hodnotu (dělí se n+1) OUT OCR2,REG ; CEKEJNAUPDATE: IN REG,ASSR ;čeká na update OCR2,TCCR2,TCNT2 ANDI REG,0b00000111 CPI REG,0b00000000 BRNE CEKEJNAUPDATE LDI REG,0b11000000 ; vymaze preruseni OCF2 a TOV2 OUT TIFR,REG ; LDI REG,0b10000000 ; povoli preruseni OCIE2 OUT TIMSK,REG ; LDI REG,0b01110000 ;povoli uspani (sleep) a nastavi mód OUT MCUCR,REG SEI ;povoli globalni preruseni ;hlavní smyčka SMYCKA: SLEEP ;uspi RJMP SMYCKA CITAC: ;preruseni RCALL PREPOLUJ SBRS DELREG,0 ;tlacitka vyhodnoti jen v kazdem druhem preruseni RCALL TLACITKA DEC DELREG ;deleni f/256, zmena polarity displeje (bit0) BRNE HOP DEC DELREG2 ;deleni f/30 BRNE HOP LDI DELREG2,30 ; RCALL MINUTA ;1x za minutu inkrementuje cas HOP: RETI ;tenhle zázrak dělá počítání od 00:00 do 23:59 a znovu MINUTA: INC CIF1 ;zvýší cifru 3 CPI CIF1,10 ;ověří, jestli tam neni 10 BRNE KONEC ;pokud ne, celé to končí LDI CIF1,0 ;pokud ano, vynuluje jí to INC CIF2 ;a zvýší cifru 4 CPI CIF2,6 ;ověří, jestli tam neni 6 BRNE KONEC ;pokud ne, celé to končí LDI CIF2,0 ;pokud ano, vynuluje jí to HODINA: INC CIF3 ; zvýší cifru 5 CPI CIF3,10 ;ověří, jestli tam neni 10 BRNE KONTR24 ;pokud ne, skočí na kontrolu 24 LDI CIF3,0 ;pokud ano, vynuluje jí to INC CIF4 ;a zvýší cifru 6 KONTR24: CPI CIF3,4 ;kontrola, zda cifra 5 není 4 BRNE KONEC CPI CIF4,2 ;a zda současně cifra 6 není 2 BRNE KONEC LDI CIF3,0 ;pokud ano, je 24 hodin, dojde k... LDI CIF4,0 ;...nulování obou cifer KONEC: RET TLACITKA: ;Zjištění stavu tlačítek. f je 100Hz CPI PRODL_TL,0 ;počítadlo prodlevy do další reakce BREQ UZJE0 DEC PRODL_TL UZJE0: IN REG,PINY ;Zjistí stav tlačítek ANDI REG,0b00110000 CP PR_ST_TL,REG ;pokud předchozí stav = současný, TL už nereaguje znovu BREQ NEREAGOVAT CPI PRODL_TL,0 ;pokud neuplynula minimální prodleva, nereaguje znovu BRNE NEREAGOVAT SBRS REG,5 RJMP NA_TLAC1 SBRS REG,4 RJMP NA_TLAC2 RJMP NEREAGOVAT NA_TLAC1: RCALL TLAC1 RJMP NEREAGOVAT NA_TLAC2: RCALL TLAC2 NEREAGOVAT: MOV PR_ST_TL,REG ;Uloží aktualni stav tlacitek pro příští test ;určuje prodlevu do další reakce (x 15,6ms) ;stisknutí/držení tlačítka nastaví prodlevu do další reakce SBRS REG,5 LDI PRODL_TL,4 ;prodleva TL1 SBRS REG,4 LDI PRODL_TL,4 ;prodleva TL2 RET ;Tlačítko nařizování hodin TLAC1: RCALL HODINA RET ;Tlačítko nařizování minut ; -při něm se nulují vteřiny ; -preteceni minut behem narizovani neinkrementuje hodiny TLAC2: INC CIF1 ;zvýší cifru 3 CPI CIF1,10 ;ověří, jestli tam neni 10 BRNE KONECM ;pokud ne, celé to končí LDI CIF1,0 ;pokud ano, vynuluje jí to INC CIF2 ;a zvýší cifru 4 CPI CIF2,6 ;ověří, jestli tam neni 6 BRNE KONECM ;pokud ne, celé to končí LDI CIF2,0 KONECM: LDI DELREG,255 ;nuluje delici registry LDI DELREG2,30 ;... RET PREPOLUJ: ;LCD displej se prepoluje MOV REG,CIF4 RCALL ZOBRAZ_DH SBRC DELREG,0 COM REG ;podminene invertuje polaritu ORI REG,0b00110000 ;aktivuje pullup odpory tlacitek OUT PORT3,REG MOV REG,CIF3 RCALL ZOBRAZ ORI REG,0b10000000 ;řídí společnou elektrodu (BP) SBRC DELREG,0 COM REG ;podminene invertuje polaritu OUT PORT4,REG MOV REG,CIF2 RCALL ZOBRAZ SBRC DELREG,0 COM REG ;podminene invertuje polaritu OUT PORT1,REG MOV REG,CIF1 RCALL ZOBRAZ SBRC DELREG,6 ANDI REG,0b01111111 ;řídí tečky (h) 1Hz blikani SBRS DELREG,6 ORI REG,0b10000000 ;řídí tečky (h) 1Hz blikani SBRC DELREG,0 COM REG ;podminene invertuje polaritu OUT PORT2,REG RET ZOBRAZ: ;prevede BCD kod na zobrazeni 7 segmentu CPI REG,0 BREQ ZOBRAZ0 CPI REG,1 BREQ ZOBRAZ1 CPI REG,2 BREQ ZOBRAZ2 CPI REG,3 BREQ ZOBRAZ3 CPI REG,4 BREQ ZOBRAZ4 CPI REG,5 BREQ ZOBRAZ5 CPI REG,6 BREQ ZOBRAZ6 CPI REG,7 BREQ ZOBRAZ7 CPI REG,8 BREQ ZOBRAZ8 CPI REG,9 BREQ ZOBRAZ9 LDI REG,0b10111111 ;pokud je hodnota mimo 0-9, zobrazi "-" RET ZOBRAZ0: LDI REG,0b11000000 RET ZOBRAZ1: LDI REG,0b11111001 RET ZOBRAZ2: LDI REG,0b10100100 RET ZOBRAZ3: LDI REG,0b10110000 RET ZOBRAZ4: LDI REG,0b10011001 RET ZOBRAZ5: LDI REG,0b10010010 RET ZOBRAZ6: LDI REG,0b10000010 RET ZOBRAZ7: LDI REG,0b11111000 RET ZOBRAZ8: LDI REG,0b10000000 RET ZOBRAZ9: LDI REG,0b10010000 RET ZOBRAZ_DH: ;prevede BCD kod na zobrazeni pro desitky hodin ;(jine zapojeni a chovani nez ostatni cifry) CPI REG,1 BREQ ZOBRAZ_DH1 CPI REG,2 BREQ ZOBRAZ_DH2 LDI REG,0b11111111 ;pokud je hodnota mimo 1-2, zobrazi nic (nula je potlacena) RET ZOBRAZ_DH1: LDI REG,0b11111001 RET ZOBRAZ_DH2: LDI REG,0b11111100 RET