; ********************************************************************** ; * File Demo_int.asm scheda: GPC 552 con SXA51 * ; * GRIFO(R) via Dell'Artigiano 8/6 40016 S. Giorgio di Piano (BO) * ; * Tel. +39 051 892052 Fax. +39 051 893661 * ; * http://www.grifo.it http://www.grifo.com * ; * by Alessio Francesconi del 16.09.04 * ; ********************************************************************** ; Questo programma, sostanzialmente, ha il compito di gestire l'interrupt ; della seriale. Premendo qualsiasi tasto della tastiera del "sistema di ; sviluppo" viene attivato l'interrupt della seriale in ricezione, e il carat_ ; tere premuto viene inserito in un buffer circolare composto da dieci caselle ; di memoria. A monitor viene stampato sia il codice ASCII del carattere in ; in questione, sia in numero di attivazioni degli interrupt seriali. ; Per i movimenti e posizionamenti del cursore sono state ; adoperate alcune sequenze di comando secondo lo standard ADDS Viewpoint ; (vedi manuale GET51). ; ; ; Gestione memorie ; STCODE EQU 2050H ;indirizzo del FMO52 come inizio RAM utente STDATA EQU 3000H ; TXCHAR EQU 0DH ;variabile contenente il valore del carattere da trasmettere DELAY EQU 12H ;variabile utilizzata nella procedura di ritardo di 100 usec (DELAY100) UNITY EQU 0EH ;variabile contenente il valore delle unità TENS EQU 0FH ;variabile contenente il valore delle decine HUNDREDS EQU 10H ;variabile contenente il valore delle centinaia POINT_W EQU 11H ;variabile puntatore di scrittura POINT_R EQU 13H ;variabile puntatore di lettura TRA_OK BIT 16H ;variabile a bit che riflette il comportamento di TI ;di TI COUNT EQU 17H ;contatore di caratteri ricevuti ; ; Inizio programma ; ORG STCODE ;inizio a mettere il codice dall'indirizzo in STCODE AJMP MAIN ; ORG STCODE+0023H ;aggiungo l'indirizzo del vettore dell'interrupt seriale AJMP INTERRUPT ; ORG STCODE+0100H ;sposto l'inizio del mio codice x lasciare posto ai vettori interrupt ; MAIN: MOV SP,#2FH ;inizializzo il puntatore della prima locazione libera dello stack CLR RS0 ;imposto l'indirizzo di memoria dei registri (00H-07H) CLR RS1 ACALL SERIAL ;inizializza la seriale SETB IP.4 ;abilito la priorità alta per gli interrupt seriali SETB IE.4 ;seleziono l'interrupt seriale SETB IE.7 ;abilito gli interrupt in generale CLR TRA_OK ;pongo a 0 il flag della trasmissione MOV DPTR,#HEADING ;stampo a monitor la stringa "HEADING" ACALL STRING MOV POINT_W,#00 ;inizializzo la variabile puntatore scrittura MOV POINT_R,#00 ;inizializzo la variabile puntatore lettura MOV COUNT,#00 ;inizializzo il contatore dei caratteri ricevuti ; CYCLE: MOV A,POINT_R ;controllo se il puntatore lettura e quello in CJNE A,POINT_W,DIFFERENT ;scrittura sono allo stesso punto, se si non è SJMP CYCLE ;arrivato nessun interrupt DIFFERENT: MOV DPL,POINT_R ;sposto il punt. lettura nel DPTR MOV DPH,HIGH BUFFER MOVX A,@DPTR ;punto il DPTR nel buffer circolare INC POINT_R ;incremento puntatore lettura MOV TXCHAR,#1AH ;cursore in alto ACALL TRASMSER ACALL ASCII ;traduco il codice binario della tastiera in ASCII ACALL TRASCII ;spedisco in seriale il codice ASCII MOV TXCHAR,#0AH ;cursore in basso ACALL TRASMSER MOV A,COUNT ;sposto in TXCHAR il contatore degli interrupt ACALL ASCII ACALL TRASCII MOV A,POINT_R ;controllo se il contatore lettura arriva alla CJNE A,#10,CYCLE ;decima locazione del buffer per poi azzerarlo MOV POINT_R,#00 ;ed uscire AJMP CYCLE ; ; Procedura di inizializzazione seriale ; SERIAL: PUSH PSW ;salvo PSW MOV SCON,#50H ;seleziono modo 1, rx attivo MOV TH1,#253 ;imposto a 253 il TH1 ANL PCON,#7FH ;azzero il bit 7 del PCON (SMOD):imposto baud rate POP PSW ;ripristino PSW RET ; ; Procedura che consente la trasmissione di dati sulla seriale ; TRASMSER: PUSH PSW ;salvo PSW TRASM1: JBC TRA_OK,TRASM2 ;salta a TRASM2 se TRA_OK = 1 e azzera TRA_OK SJMP TRASM1 ;salta a TRASM1 perche' TRA_OK = 0 ;seriale ancora in fase di trasmissione TRASM2: MOV SBUF,TXCHAR ;scrive nel buffer della seriale il car. da trasmettere CLR TRA_OK POP PSW ;ripristino PSW RET ; ; Procedura per scrivere parti di testo via seriale ; STRING: PUSH PSW ;salvo registri utilizzati dalla procedura PUSH ACC PUSH TXCHAR STRINGLOOP: MOVX A,@DPTR ;carica in A il contenuto della memoria puntata da JZ ENDSTRING ;se l'ultimo carattere letto e' nullo (00H),salta alla fine MOV TXCHAR,A ;carica il carattere nella variabile per la trasmissione ACALL TRASMSER ;trasmetti il carattere INC DPTR ;incrementa il puntatore al carattere SJMP STRINGLOOP ;il ciclo riparte per un altro carattere ENDSTRING: POP TXCHAR ;ripristina i registri sopra indicati POP ACC POP PSW RET ; ; Procedura che trasforma il codice acquisito dai port in codice decimale ; ASCII: PUSH PSW ;salvo i registri usati dalla procedura PUSH ACC PUSH B MOV B,#100 ;carica in B il valore 100 DIV AB ;divide A per B (100) ADD A,#30H ;aggiunge alle centinaia 30H per renderlo un Ascii MOV HUNDREDS,A ;salva le centinaia MOV A,B ;ricarica in A il valore MOV B,#10 ;carica in B il valore 10 DIV AB ;divide A per B (10) ADD A,#30H ;aggiunge alle decine 30H per renderlo un Ascii MOV TENS,A ;salva le decine MOV A,B ;ricarica in A il valore ADD A,#30H ;aggiunge alle unita' 30H per renderlo un Ascii MOV UNITY,A ;salva le unita POP B ;ripristina i registri usati dalla procedura POP ACC POP PSW RET ; ; Procedura per inviare il valore sullo schermo tramite seriale ; TRASCII: PUSH PSW ;salvo i registri usati dalla procedura PUSH ACC PUSH TXCHAR MOV A,HUNDREDS ;controllo se le centinaia sono diverse da '0' CLR F0 ;azzero il flag F0 MOV TXCHAR,A ;HUNDREDS in TXCHAR CJNE A,#48,ASCII1 ;se diverse salta a ASCII1 MOV TXCHAR,#20H ;altrimenti spedisce uno spazio SETB F0 ;indico che le centinaia erano uguali a '0' ASCII1: ACALL TRASMSER MOV A,TENS ;controllo se le decine sono diverse da '0' MOV TXCHAR,A ;metto le decine in TXCHAR CJNE A,#48,ASCII2 ;se diverse spedisci le decine JNB F0,ASCII2 ;altrimenti controlla se le centinaia erano a '0' MOV TXCHAR,#20H ;spedisce uno spazio ASCII2: ACALL TRASMSER MOV TXCHAR,UNITY ;trasmette le unita' ACALL TRASMSER MOV TXCHAR,#08H ;trasmette tre ritorni a sinistra ACALL TRASMSER ACALL TRASMSER ACALL TRASMSER POP TXCHAR ;ripristina i registri usati dalla procedura POP ACC POP PSW RET ; ; Procedura di risposta degli interrupt seriali ; INTERRUPT: PUSH PSW ;salvo i registri utilizzati nella procedura PUSH ACC PUSH DPH PUSH DPL JNB RI,NO_RI ;controllo se è arrivato un interrupt di ricezione CLR RI ;o di trasmissione: se in rx lo si azzera, tx salta INC COUNT ;incremento contatore dei caratteri arrivati MOV DPL,POINT_W ;sposto il puntatore scrittura nel DPTR MOV DPH,HIGH BUFFER MOV A,SBUF ;carico in ACC il carattere nel registro SBUF MOVX @DPTR,A ;punto la locazione del buffer per la scrittura INC POINT_W ;incremento il puntatore scrittura MOV A,POINT_W ;controllo se il puntatore scrittura è arrivato CJNE A,#10,NO_RI ;alla decima casella per poi azzerarlo MOV POINT_W,#00 NO_RI: JNB TI,ENDINT SETB TRA_OK ;setto il flag di trasmissione CLR TI ;azzero TI ENDINT: POP DPL POP DPH POP PSW POP ACC RETI ; HEADING: DB 0CH,' Programma per la gestione degli interrupts seriali: ----attesa caratteri----',1DH,1DH,' Codice ASCII del Carattere: ',1DH,' Numero caratteri ricevuti: ',00H ORG STDATA BUFFER: DS 10 END