*-------------------------------------------------------* * Program: Ura s funkcijo nastavitve * * * * Procesor: Motorola 68HC11 * * Okolje: Razvojno okolje by Robert Rostohar 1999 * * Avtor: aljaz.ogrin@email.si * *-------------------------------------------------------* *** Operacijski sistem *** *** Razdelitev naslovnega prostora *** _TOC1 EQU $1016 Timer: Prvi izhodni primerjalni register _TMSK1 EQU $1022 Timer: Prvi prekinitveni register z masko _TFLG1 EQU $1023 Timer: Prvi prekinitveni register z zastavicami _TCNT EQU $100E Timer: 16-bitni prosto tekoči števec _DPRA EQU $1800 PORTI... _CRA EQU $1801 _DPRB EQU $1802 _CRB EQU $1803 _XRAM EQU $2000 Zunanji RAM $2000 ... $3FFF (8192 byte-ov) _EPROM EQU $E000 Uporabniški EPROM $E000 ... $FFFF (8192 byte-ov) _ITOC1 EQU $FFE8 Prekinitev ob prvem izhodnem primerjalnem registeru _IRESET EQU $FFFE Reset *** Prekinitveni vektorji *** ORG _IRESET Ob resetu FDB _START pojdi na začetek ORG _ITOC1 Ob dogodku _TCNT = _TOC1 FDB _SCHINT pojdi na časovno rezinjenje *** Tabela spremenljivk ********************************************* ORG _XRAM SCHTST RMB 1 Spremenljivka, ki pove ali je opravilo končano SCHPTR RMB 2 interna - Kazalec na opravilo v tabeli SCHTAB LED1 RMB 1 7-segment LedX bufferji LED2 RMB 1 LED3 RMB 1 LED4 RMB 1 KBDKEY RMB 1 interna - tipka pritisnjena? (00/FF) KBDOFFS RMB 1 interna KBDBEG RMB 2 KBD buffer begin pointer (2 bytes) KBDBUFF RMB 9 KBD buffer (8 bytes + 1 empty) KBDEND RMB 2 KBD buffer end (first empty) pointer (2 bytes) TIMF RMB 1 RTC frames TIMS RMB 1 RTC seconds TIMM RMB 1 RTC minutes TIMH RMB 1 RTC hours DISPLHM RMB 1 *** Tabela opravil, eno opravilo pride na vrsto vsako 1/64 sekunde *** ORG _EPROM SCHTAB FDB RTC 1 Ura realnega časa FDB SCHRTS 2 Prazno opravilo FDB KEY_DRV 3 Branje s tipkovnice FDB LEDDRV1 4 LED_driver1 FDB RTC 5 Ura realnega časa FDB SCHRTS 6 Prazno opravilo FDB SCHRTS 7 Prazno opravilo FDB LEDDRV2 8 LED_driver2 FDB RTC 9 Ura realnega časa FDB SCHRTS 10 Prazno opravilo FDB SCHRTS 11 Prazno opravilo FDB LEDDRV3 12 LED_driver3 FDB RTC 13 Ura realnega časa FDB SCHRTS 14 Prazno opravilo FDB SCHRTS 15 Prazno opravilo FDB LEDDRV4 16 LED_driver4 *** Tabela znakov za pretvorbo ASCII -> 7-segment LED *** LED_MAP FCB #%00001001 error FCB #%00111111 num 0 = ASCII 48 FCB #%00000110 num 1 FCB #%01011011 num 2 FCB #%01001111 num 3 FCB #%01100110 num 4 FCB #%01101101 num 5 FCB #%01111101 num 6 FCB #%00000111 num 7 FCB #%01111111 num 8 FCB #%01101111 num 9 = ASCII 57 *** Tabela znakov za pretvorbo tipkovnica -> ASCII *** KBD_MAP FCB $1B esc FCC "987" FCC "+654" FCC "-321" FCB $01 shift FCB $0D enter FCC ".0" *** Reset *********************************************************** _START lds #$3FFF Sklad je prazen in se nahaja na koncu XRAM-a jsr INIT Inicializacija jsr SCHON Zagon časovnega rezinjenja JSR MAIN HALT bra HALT Varnostna mrtva znaka *** Inicializacija *** INIT * porti... clr _CRA control=0 -> load Data Direction Register clr _CRB ldaa #$0F bit 0..3 - out, bit 4..7 - input staa _DPRA na portu A ldaa #$FF bit 0..7 - output staa _DPRB na portu B ldaa #$04 control=$04 -> load Peripherial Register staa _CRA staa _CRB clr _DPRA displeji ugasnjeni clr _DPRB vsi segmenti ugasnjeni * LED display-i clr LED1 clr LED2 clr LED3 clr LED4 * tipkovnica... CLR KBDKEY tipka ni pritisnjena LDX #KBDBUFF STX KBDBEG naslov keyb. buffer * -> pointer begin & end (buf. empty) STX KBDEND * ura RTC clr TIMF clr TIMS clr TIMM clr TIMH RTS * *** Inicializacija časovnega rezinjenja *** SCHON clr SCHTST Opravilo je končano ldx #SCHTAB Naložimo naslov prvega opravila v X register stx SCHPTR in ga shranimo v kazalec na trenutno opravilo ldd _TCNT Naložimo 16-bitni prosto tekoči števec (timer) addd #1200 in ga povečamo za 1200 ciklov, kar pomeni 1/1024 * sekunde std _TOC1 ter shranimo v izhodni primerjalni register ldaa #$80 Naložimo 10000000 in s tem: staa _TFLG1 pobrišemo OC1F bit v TFLG1 registru, kar pomeni, da * čakamo na dogodek _TCNT = _TOC1 staa _TMSK1 postavimo OC1I bit v TMSK1 registru, kar pomeni, da * bo dogodek _TCNT = _TOC1, oziroma OC1F = 1, sprožil * prekinitev cli Omogočimo maskirane prekinitve (zastavica I = 0) rts * *** Prekinitev na vsako 1/1024 sekunde *** _SCHINT ldaa SCHTST (4) Pogledamo status prejšnjega opravila beq SCHOK (3) Ali je bilo opravilo končano SCHERR bra SCHERR Napaka predolgo opravilo SCHOK inc SCHTST (6) Status opravila je ena, ker trenutno teče ldd _TOC1 (5) Naložimo register _TOC1 addd #1200 (4) in ga povečamo za 1200 ciklov, kar pomeni da bo std _TOC1 (5) naslednja prekinitev čez 1200 ciklov ldaa #$80 (2) Omogočimo novo prekinitev staa _TFLG1 (4) dogodku _TCNT = _TOC1 cli (2) Omogočimo novo prekinitev, ki se načeloma ne * sme zgoditi, preden se ta ne zaključi. ldx SCHPTR (5) Naložimo kazalec na kazalec na opravilo ldx 0,X (5) Naložimo kazalec na opravilo jsr 0,X (6) Izvršitev opravila ldaa SCHPTR+1 (4) Kazalec na kazalec na opravilo adda #$02 (2) naj kaže na naslednje opravilo anda #$1E (2) Če smo prisli do konca, gremo zopet od začetka staa SCHPTR+1 (4) Shranimo novi kazalec na kazalec na opravilo clr SCHTST (6) Opravilo je končano, njegov status je nič rti (12) * (81) ciklov, za opravilo jih ostane še 1119 *** Prazno opravilo *** SCHRTS rts (5) Prazno opravilo * (5) Skupaj *** Opravilo Branje s tipkovnice *** KEY_DRV LDAA _DPRA PSHA shrani port A; stack: portA LDAB _DPRB PSHB shrani port B; stack: portB,portA LDAA #$FF STAA _DPRA DISPLAYS OFF LDAB #%11101111 K_NXT ASRB pomik aktivne vrstice BCC K_NIC če carry=0, nicla je zunaj - * konec skeniranja vrstic, ni bilo tipke STAB _DPRB Aktivna vrstica 4,3,2,1 LDAA _DPRA Beri port A COMA negativna logika - negacija A ANDA #$F0 odreže spodnje 4 bite BEQ K_NXT če je vse 0, tika ni pritisnjena - * PONOVI naslednja vrstica * tipka je pritisnjena TST KBDKEY tipka je pritisnjena - * ali je še od prej pritisnjena? BNE K_END skoci, če > 0 (je od prej) COMB CLR KBDOFFS K_SH_B INC KBDOFFS LSRB shift B desno BHS K_SH_B carry = 0? JA -> repeat DEC KBDOFFS vrednost: 0..3 (b1:b0) ASL KBDOFFS ASL KBDOFFS offs = offs * 4 (b3:b2) K_SH_A INC KBDOFFS LSLA shift A levo BHS K_SH_A carry = 0? JA -> repeat DEC KBDOFFS vrednost: 0..15 = offset * gremo po znak v tabelo LDX #KBD_MAP LDAB KBDOFFS offset -> B ABX X = #KBD_MAP + B(offset) LDAA 0,X znak "KBD_MAP+offset" -> A * nalozimo v buffer LDX KBDEND nalozimo pointer na prazno mesto STAA 0,X shranimo znak v prazno mesto INX povecamo pointer CPX #KBDEND primerjamo X z naslovom konca bufferja = * ciklična povezava na začetek buff. BNE K_POLN nista enaka - nismo na koncu bufferja * -> skok na preverjanje polnosti LDX #KBDBUFF gremo na začetek bufferja K_POLN CPX KBDBEG preverjanje polnosti buff. BEQ K_OK če (BEG = X+1) -> buffer poln - konec STX KBDEND ni poln - shranimo novo končno vrednost K_OK LDAB #$FF STAB KBDKEY tipka pritisnjena, KBDKEY > 0 BRA K_END K_NIC CLR KBDKEY ni bilo tipke, KBDKEY = 0 K_END PULB naloži stari port B; stack: portA STAB _DPRB restavriraj port B PULA naloži stari port A; stack: clear STAA _DPRA restavriraj port A RTS *** Opravilo Prikaz na LED1 *** LEDDRV1 LDAA #%00000111 nalozimo nov naslov LED LDAB LED1 nalozimo novo cifro clr _DPRB ugasnemo prejsnjo cifro STAA _DPRA aktiviramo nov naslov STAB _DPRB aktiviramo novo cifro rts * *** Opravilo Prikaz na LED2*** LEDDRV2 LDAA #%00001011 LDAB LED2 clr _DPRB STAA _DPRA STAB _DPRB rts * *** Opravilo Prikaz na LED3*** LEDDRV3 LDAA #%00001101 LDAB LED3 clr _DPRB STAA _DPRA STAB _DPRB rts * *** Opravilo Prikaz na LED4*** LEDDRV4 LDAA #%00001110 LDAB LED4 clr _DPRB STAA _DPRA STAB _DPRB rts * *** Opravilo Ura realnega časa *** RTC inc TIMF bne T_END inc TIMS ldaa TIMS cmpa #60 bcs T_END clr TIMS inc TIMM ldaa TIMM cmpa #60 bcs T_END clr TIMM inc TIMH ldaa TIMH cmpa #24 bcs T_END clr TIMH T_END rts * *** ASCII number TO 7-SEG *** (accA IN, accA OUT) A_2_7 CMPA #47 "0"-1 BLS A7_err ce manjsi / enak -> err CMPA #58 "9"+1 BHS A7_err ce vecji / enak -> err SUBA #47 "0"-1, A=offset (0 do 10) = [err,0,1,2,...,9] LDX #LED_MAP PSHB shrani B; stack: B TAB A(offset) -> B ABX X = #LED_MAP + B(A(offset)) PULB restavriraj B; stack: clear LDAA 0,X "LED_MAP+offset" -> A RTS A7_err LDX #LED_MAP LDAA 0,X "LED_MAP+0" -> A RTS *** Conversion Time To LED (LED1,2 = accA, LED3,4 = accB) *********** T2L * LED1,2 pshb shranimo drugo število; stack: B tab transfer A -> B clra ldx #10 idiv A:B / X -> X + (D) pshx shranimo ostanek(desetice); stack:B,X addb #48 enice: dodamo ascii offset za "0" tba transfer B -> A jsr A_2_7 ora #%10000000 dodamo piko staa LED2 pulb pula stack: B (druga številka) adda #48 desetice: dodamo ascii offset za "0" jsr A_2_7 staa LED1 * LED 3,4 pulb shranimo drugo število; stack: / clra ldx #10 idiv A:B / X -> X + (D) pshx shranimo ostanek(desetice); stack: X addb #48 enice: dodamo ascii offset za "0" tba transfer B -> A jsr A_2_7 staa LED4 pulb pula stack: / adda #48 desetice: dodamo ascii offset za "0" jsr A_2_7 staa LED3 rts * *** Get Key (return: AccA ascii char or $00 if not pressed) ********* GET_KEY pshx ldx KBDBEG cpx KBDEND beq Gno_key ldaa 0,X inx cpx #KBDEND bne Gok ldx #KBDBUFF Gok stx KBDBEG bra Gend Gno_key clra Gend pulx rts * *** Main Program **************************************************** MAIN * LDAA #51 "3" * JSR A_2_7 * STAA LED4 nastavi clr TIMF clr TIMS clr LED3 clr LED4 ldaa #%01110110 "H" staa LED1 ldaa #%01001000 "=" staa LED2 hh1 jsr GET_KEY clr TIMF držimo ustavljeno uro tsta beq hh1 A = 0, tipka ni pritisnjena cmpa #48 blo hh1 primerjamo z "0", če manjše znak ni številka tab transfer A -> B; shranimo cifro jsr A_2_7 (ohrani B) staa LED3 subb #48 B - 48 -> B ldaa #10 mul A(10) * B(cifra) -> D (za desetice) stab TIMH D == B = 00..90 hh2 jsr GET_KEY clr TIMF držimo ustavljeno uro tsta beq hh2 A = 0, tipka ni pritisnjena cmpa #48 blo hh2 primerjamo z "0", če manjše znak ni številka tab transfer A -> B; shranimo cifro jsr A_2_7 (ohrani B) staa LED4 subb #48 B - 48 -> B addb TIMH B + TIMH -> B stab TIMH B -> TIMH jsr delay ************ clr TIMS clr LED3 clr LED4 ldaa #%00110111 "M" staa LED1 ldaa #%01001000 "=" staa LED2 mm1 jsr GET_KEY clr TIMF držimo ustavljeno uro tsta beq mm1 A = 0, tipka ni pritisnjena cmpa #48 blo mm1 primerjamo z "0", če manjše znak ni številka tab transfer A -> B; shranimo cifro jsr A_2_7 (ohrani B) staa LED3 subb #48 B - 48 -> B ldaa #10 mul A(10) * B(cifra) -> D (za desetice) stab TIMM D == B = 00..90 mm2 jsr GET_KEY clr TIMF držimo ustavljeno uro tsta beq mm2 A = 0, tipka ni pritisnjena cmpa #48 blo mm2 primerjamo z "0", če manjše znak ni številka tab transfer A -> B; shranimo cifro jsr A_2_7 (ohrani B) staa LED4 subb #48 B - 48 -> B addb TIMM B + TIMM -> B stab TIMM B -> TIMM jsr delay ************ clr DISPLHM new_tim tst DISPLHM bne min_sek ldaa TIMH ure in minute ldab TIMM jsr T2L bra LOOP min_sek ldaa TIMM minute in sekunde ldab TIMS jsr T2L LOOP jsr GET_KEY cmpa #43 + beq HRS cmpa #45 - beq MINS cmpa #13 Enter beq nast1 bra WAIT HRS ldaa #$FF staa DISPLHM bra WAIT MINS clr DISPLHM WAIT tst TIMF BEQ new_tim ldaa TIMF cmpa #127 beq pika1 bra LOOP pika1 ldaa LED4 ora #%10000000 staa LED4 bra LOOP RTS nast1 jmp nastavi ************************** delay ldx #$CFFF dly1 dex bne dly1 rts ********************************************************************* END