*-------------------------------------------------------* * Program: Test serijske komunikacije * * * * 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 _BAUD EQU $102B SCI: Baud Rate Register _SCCR1 EQU $102C SCI: Control Register 1 _SCCR2 EQU $102D SCI: Control Register 2 _SCSR EQU $102E SCI: Status Register _SCDR EQU $102F SCI: Data Register _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 ORG _XRAM *** Tabela spremenljivk *** SCHTST RMB 1 Spremenljivka, ki pove ali je opravilo končano SCHPTR RMB 2 Kazalec na opravilo v tabeli SCHTAB RECB RMB 2 begin (word) RECBUFF RMB 200 buffer RECE RMB 2 word TRAB RMB 2 begin (word) TRABUFF RMB 200 buffer TRAE RMB 2 word ***** ORG _EPROM *** Tabela opravil, eno opravilo pride na vrsto vsako 1/64 sekunde *** SCHTAB FDB SCHRTS Prazno opravilo FDB SCHRTS Prazno opravilo FDB SCHRTS Prazno opravilo FDB SCHRTS Prazno opravilo FDB SCHRTS Prazno opravilo FDB SCHRTS Prazno opravilo FDB SCHRTS Prazno opravilo FDB SCHRTS Prazno opravilo FDB SCHRTS Prazno opravilo FDB SCHRTS Prazno opravilo FDB SCHRTS Prazno opravilo FDB SCHRTS Prazno opravilo FDB SCHRTS Prazno opravilo FDB SCHRTS Prazno opravilo FDB SCHRTS Prazno opravilo FDB SCIINT Serijska komunikacija *** 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 LDX #TRABUFF STX TRAB STX TRAE LDX #RECBUFF STX RECB STX RECE 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 ********************************************************************* ************************* SCI DRIVER ******************************** * This is driver which read and write bytes from Serial Communication Data * Register, initialize SCC1, SCC2 and BAUD registers and check status * of Serial Communications Status Register. ********************************************************************* ************************* SCI INIT ********************************** * First initialize Serial Communications Register 1 and 2 and set * baud rate register. ********************************************************************* SCI_I psha * Push a and pshx * x to stack. ldaa #%00000000 * We don't need noise and other error check staa _SCCR1 * store default value to Serial Comm. Reg. 1. ldaa #%00001100 * Load flags for enable RX and TX staa _SCCR2 * store to Serial Communications Register 1. ldaa #%00000001 * Load baud rate flags to a and store it staa _BAUD * in baud rate register (38.40K Baud). pulx * Pull x and pula * a from stack. rts * Return from subroutine. ************************* END OF SCI INIT *************************** ************************* SCI INTERRUPT ROUTINE ********************* * First check Serial Control Status Register. If receive register is * full we read from it and if receive buffer is not full store value. * If transmit buffer is empty we read from transmit buffer and if it * is not empty we get byte and store it to data registrer. ********************************************************************* SCIINT psha * Push a, pshb * b and pshx * x to stack. ldaa _SCSR * Load status register to a. anda #%00100000 * If Receive Data Register is not full, beq TRTRY * we go to check transmit. ldab _SCDR * Else read received byte from data register. ************************* WRITE RECEIVED CHARACTERS TO BUFFER ******* * This part of interrupted routine store received character to RECB * buffer and increase RECE pointer. Then fill TRAB with received * character for reply to console. ********************************************************************* ldx RECE * load pointer for writing to buffer, stab 0,x * store received byte on location. inx * Increase pointer, cpx #RECE * compare end of buffer with pointer, bne RECW1 * if no at end go to store new pointer value. ldx #RECB+2 * Else wrap pointer to begin. RECW1 cpx RECB * Compare write and read pointers, beq TRTRY * if values are the same is error go TX. stx RECE * Else store increased write pointer. ************************* TRANSMIT CHARACTERS FROM BUFFER *********** * This part of interrupted routine get character from TRA - transmit * buffer if it is not empty and transmit fifo not full. ********************************************************************* TRTRY ldaa _SCSR * Load status register, anda #%10000000 * if transmitt buffer full, beq ENDSCI * end routine. ldx TRAB * Load pointer to reading from buffer, cpx #TRAE * compare it with physhical end and if it is bne TRAT1 * not at end go to compare with write pointer ldx #TRAB+2 * If pointer is at end wrap it to begin. TRAT1 cpx TRAE * Compare if read and write point values, beq ENDSCI * if buffer is full finish with error ->end. ldab 0,x * Else load value from buffer and stab _SCDR * store it to data register. inx * Increment read pointer and stx TRAB * store it. ENDSCI pulx * Pull x, pulb * b and pula * a from stack. rts * Return from interrupt. ************************* END OF SCI DRIVER ************************* ********************************************************************* ************************* READ RECEIVED CHARACTERS FROM BUFFER ****** * This subroutine must be called from non interrupted function. Read one * character from the REC buffer RECB-RECE to A. In case of an empty * buffer, the procedure returns Z=1. A successful read is indicated by Z=0. ********************************************************************* RECRCH pshx * Push x to stack. ldx RECB * Load read pointer, cpx #RECE * compare it with physical end. bne RECR1 * If it is at the end wrap it ldx #RECB+2 * to physical begin. RECR1 cpx RECE * Compare read pointer with write pointer beq RECRER * and if the buffer is empty return with z=0. ldaa 0,x * Else load pointed value to a, inx * increment read pointer, stx RECB * store it and RECRER pulx * pull x. rts * Return from subroutine. ************************* END OF READ CHARACTER ********************* ************************* WRITE CHARACTER TO TRANSMIT BUFFER ******** * This subroutine must be called from non interrupted function. Put one * character from a to transmit buffer TRAB-TRAE In case of full buffer, the * procedure returns Z=1. A successful write is indicated by Z=0. ********************************************************************* TRAWCH pshx * Push x to stack. ldx TRAE * Load write pointer and staa 0,x * store a to pointed location. inx * Increment write pointer, cpx #TRAE * compare it with physical end. bne TRAW1 * If it is at the end wrap it ldx #TRAB+2 * to physical begin. TRAW1 cpx TRAB * Compare write pointer with read pointer beq TRAWER * and if buffer is full return with z=0. stx TRAE * Store write pointer and TRAWER pulx * pull x. rts * Return from subroutine. ************************* END OF WRITE CHARACTER ******************** ************************** TX_STR ************************************ * This function puts character string to transmit buffer that will * be send to terminal. For argument we must load address of the first * character of string to x. String must be zero-terminated. ********************************************************************* TX_STR psha * Push a and pshx * x to stack. PRILO ldaa 0,x * Load an argument - pointer, beq ENDPR *if value of pointed character is zero return jsr TRAWCH * Put character to transmitt buffer and inx * increase pointer and bra PRILO * go to send next character. ENDPR pulx * Pull a and pula * x from stack. rts * Return from subroutine. ************************** END OF TX_STR ***************************** MAIN ldx #SGREET * Load programm greeting buffer pointer jsr TX_STR * and call procedure to display it. rx jsr RECRCH * Echo all received characters. beq rx jsr TRAWCH bra rx rts SGREET FCC " SCI TEST intro string " FCB $0D,$0A FCC " help!!!!" FCB $0D,$0A FCB $00 END