' ********************************************************************** ' * File: Corso_BASCOM8051_019.BAS * ' * Versione: 1.1 * ' * Data: 25.05.09 * ' * Ambiente sviluppo: Bascom 8051 COMP.,IDE 2.0.14.0 + FLIP 2.4.6 * ' * Schede: GMM 5115 + GMM TST3 * ' * Sviluppato da: GRIFO(r) Italian Technology * ' * via Dell'Artigiano 8/6 * ' * 40016 S. Giorgio di Piano (BO) * ' * Tel. +39 051 892052 Fax. +39 051 893661 * ' * http://www.grifo.com http://www.grifo.it * ' * Autore: Gianluca Angelini * ' ********************************************************************** ' Programma di esempio 019 del corso BASCOM 8051. ' Gestisce tutti i tasti di una tastiera a matrice 4x4. ' Il programma acquisisce continuamente lo stato dei 16 tasti collegati alla ' tastiera a matrice presente sulla GMM TST3, e li trasmette sulla linea ' seriale. L'acquisizione avviene con Debouncing e con Autorepeat: i tasti sono ' acquisiti con un Debouncing di 20 millisecond, il primoo tasto in Autorepeat ' viene fornito dopo 500 millisecondi ed i rimanenti ogni 100 millisecondi. ' La rappresentazione dei tasti premuti avviene su una console seriale dotata ' di monitor, con un protocollo fisico costante a 19200 Baud, 8 Bit x chr, ' 1 Stop bit, Nessuna parit?. ' Questa console puÚ coincidere con un sistema in grado di gestire una ' comunicazione seriale in RS 232. Al fine di semplificarne l'uso si puÚ ' usare un PC dotato di una linea COMx, che esegue un programma di emulazione ' terminale come HYPERTERMINAL o l'omonima modalit? offerta dal BASCOM 8051 ' (vedere Configurazioni IDE). ' Il programma funziona solo se la GMM 5115 Ë montata sullo zoccolo Z1 della ' GMM TST3!! ' Nel programma i termini riga e colonna sono riferiti allo schema elettrico ' della tastiera a matrice, non al suo formato fisico!! ' ' Aggiunte: . ' ' 25/05/09: Corso_BASCOM8051_019.BAS - Ver 1.1 - By G.A. ' Prima versione. ' ' '*************************** Configurazioni IDE ******************************** ' NOTE: per usare correttamente questo programma demo, eseguire i seguenti ' punti: ' 1) Controllare la presenza del file 89C5115.DAT nella directory in cui Ë ' installato il BASCOM 8051 e copiarlo se non Ë presente. ' 2) Nella finestra "Options | Compiler | Misc" settare: ' Register File = 89C5115.DAT ' Byte End(Hex) = A0 ' Size warning = selezionata a 16384 (=4000H) ' 3) Nella finestra "Options | Communication" settare: ' COM port = la linea del PC collegata alla GMM 5115, tramite la GMM TST3 ' Baudrate = 19200 ' Parity = None ' Databits = 8 ' Stopbit = 1 ' Handshake = None ' Emulation = TTY ' Font = Terminal, Normale, 12 punti, colore bianco ' Backcolor = Navy ' Run emulator modal = non selezionato ' 4) Al termine della compilazione, della programmazione del codice nella ' GMM 5115, della riselezione della modalit? RUN e prima di resettare o ' riaccendere il Mini Modulo, aprire la finestra di emulazione terminale ' del BASCOM 8051 con l'opzione: Tools | Terminal emulator (Ctrl+T). '********************** Direttive del compilatore ****************************** $regfile "89C5115.DAT" ' File di definizione microcontrollore usato $romstart = &H0 ' Indirizzo inizio codice in FLASH $iramstart = &H0 ' Indirizzo inizio dati in RAM interna $ramstart = &H0 ' Indirizzo inizio dati in RAM esterna $ramsize = &H100 ' Dimensioni della RAM esterna $crystal = 14745600 ' Frequenza del quarzo del microcontrollore $large ' Dimensione codice > 2K $map ' Genera informazioni di debug $baud = 19200 ' Velocit? comunicazione seriale: 19200 Baud ' Altri parametri sono fissi a: 8 bit x chr ' 1 Stop bit ' No parity '******************************* Definizioni *********************************** ' Le risorse usate dal programma sono collegate come illustrato nelle seguenti ' tabelle: ' !!! N.B. Sulla GMM TST3 i jumper devono essere posizionati come segue: ' J1 in 2-3 ; J3 in 1-2 ; J10 in 1-2 ; J11 in 1-2 !!! ' ' Risorsa pin Z1 pin Segnale Segnale uP ' hw GMM TST3 GMM 5115 GMM 5115 usato ' TST1.Row0 33 27 P1.0 DSW1.1 T2 DL1 P1.0 ' TST1.Row1 32 26 P1.1 ADC1 T2EX P1.1 ' TST1.Row2 31 25 P1.2 ADC2 ECI P1.2 ' TST1.Row3 30 24 P1.3 ADC3 CEX0 P1.3 ' TST1.Col0 29 23 P1.4 ADC4 CEX1 P1.4 ' TST1.Col1 28 22 P1.5 ADC5 P1.5 ' TST1.Col2 27 21 P1.6 ADC6 P1.6 ' TST1.Col3 26 20 P1.7 ADC7 P1.7 ' ' Segnale pin COMx pin CN5 pin Z1 pin Segnale Segnale uP ' PC DB9 GMM TST3 GMM TST3 GMM 5115 GMM 5115 usato ' TX 3 3 9 3 RxD RS232 P3.0 ' RX 2 2 10 4 TxD RS232 P3.1 ' GND 5 5 20 14 GND - ' Dalla seconda tabella si ricava che il cavo di collegamento tra la COM del PC ' ed il CN5 della GMM TST3 Ë un normale cavo dritto o prolunga. Volendolo ' richiedere alla grifo(r) si deve specificare il codice CCR 9+9E. Pinrow0 Alias P1.0 ' Segnale collegato a riga 0 tastiera TST1 GMM TST3 Pinrow1 Alias P1.1 ' Segnale collegato a riga 1 tastiera TST1 GMM TST3 Pinrow2 Alias P1.2 ' Segnale collegato a riga 2 tastiera TST1 GMM TST3 Pinrow3 Alias P1.3 ' Segnale collegato a riga 3 tastiera TST1 GMM TST3 Pincol0 Alias P1.4 ' Segnale collegato a riga 0 tastiera TST1 GMM TST3 Pincol1 Alias P1.5 ' Segnale collegato a riga 1 tastiera TST1 GMM TST3 Pincol2 Alias P1.6 ' Segnale collegato a riga 2 tastiera TST1 GMM TST3 Pincol3 Alias P1.7 ' Segnale collegato a riga 3 tastiera TST1 GMM TST3 Pinrx Alias P3.0 ' Segnale collegato a RxD GMM 5115 Pintx Alias P3.1 ' Segnale collegato a TxD GMM 5115 '************************ Dichiarazioni costanti ******************************* Const Nokey = &HFF ' Valore per indicare nessun tasto premuto Const Debdt = 5 ' Tempo esecuzione Debouncing in millisecondi Const Debtime = 20 ' Tempo durata Debouncing per tasto reale in millisecondi Const Debcycle = Debtime / Debdt ' Numero cicli Debouncing ottenuto da tempi impostati Const Rep1sttime = 500 ' Tempo primo autorepeat tasto in millisecondi Const Rep1stcycle = Rep1sttime / Debdt ' Numero cicli primo autorepeat Const Repnexttime = 100 ' Tempo prossimoo autorepeat tasto in millisecondi Const Repnextcycle = Repnexttime / Debdt ' Numero cicli prossimo autorepeat Const Nextrep = Rep1sttime - Repnexttime ' Tempo partenza prossimo autorepeat tasto in millisecondi Const Nextcycle = Nextrep / Debdt ' Numero cicli partenza prossimo autorepeat tasto '************************ Dichiarazioni variabili ****************************** Dim Keypos As Byte ' Posizione tasto premuto su tastiera a matrice Dim Key As Byte ' Codice tasto premuto su tastiera a matrice Dim Krow As Byte ' Stato righe della tastiera a matrice Dim Kcol As Byte ' Stato colonne della tastiera a matrice Dim Kcode(16) As Byte ' Vettore con codici tasti della tastiera a matrice Dim Debpos As Byte ' Posizione tasto premuto in debouncing Dim Debcnt As Byte ' Contatore per debouncing Dim Reppos As Byte ' Posizione tasto premuto in autorepeat Dim Repcnt As Byte ' Contatore per autorepeat '************************ Dichiarazioni procedure ****************************** Declare Sub Ini_key() ' Inizializza linee su tastiera a matrice Declare Sub Set_col() ' Setta stato colonne tastiera a matrice Declare Sub Get_row() ' Preleva stato righe tastiera a matrice Declare Sub Scan_key() ' Verifica stato tastiera a matrice Declare Sub Deb_key() ' Preleva stato tastiera a matrice con Debouncing Declare Sub Rep_key() ' Preleva stato tastiera a matrice con Autorepeat e Debouncing '************************** Programma principale ******************************* Main: Pinrx = 1 ' Inizializza segnali per comunicazione seriale Pintx = 1 ' come ingressi digitali Call Ini_key() ' Inizializza linee su tastiera a matrice Print Print " Acquisizione 16 tasti da una tastiera a matrice 4x4" Print "Il programma mostra i tasti premuti sulla tastiera TST1,della GMM TST3, con la" Print "tecnica del Debouncing e dell'Autorepeat." Print Do Waitms Debdt ' Ritardo che equivale a tempo di Debouncing Call Rep_key() ' Preleva stato tastiera a matrice con Autorepeat e Debouncing If Key <> Nokey Then ' Verifica se c'Ë un tasto premuto Printbin Key ' Rappresenta tasto premuto su console End If Loop ' Fine ciclo infinito End '************************ Fine programma principale **************************** '****************** Inizio procedure usate dal programma *********************** ' Inizializza risorse, variabili e periferiche usate per la gestione della ' tastiera a matrice. ' Ingresso: Nulla ' Uscita: Kcode() = vettore con codici tasti inizializzato ' Debpos, Debcnt = variabili per Debouncing inizializzate ' Reppos, Repcnt = variabili per Autorepeat inizializzate Sub Ini_key() Adcf = &H00 ' Setta segnali per tastiera a matrice come I/O digitali Pinrow0 = 1 ' Inizializza segnali collegati a righe della Krow = Pinrow0 ' tastiera a matrice come ingressi digitali Pinrow1 = 1 Krow = Pinrow1 Pinrow2 = 1 Krow = Pinrow2 Pinrow3 = 1 Krow = Pinrow3 Pincol0 = 1 ' Inizializza segnali collegati a colonne della Pincol1 = 1 ' tastiera a matrice come uscite digitali alte Pincol2 = 1 Pincol3 = 1 Kcode(1) = "D" ' Setta codici tasti della tastiera a matrice Kcode(2) = "#" ' in apposito vettore Kcode(3) = "0" Kcode(4) = "*" Kcode(5) = "C" Kcode(6) = "9" Kcode(7) = "8" Kcode(8) = "7" Kcode(9) = "B" Kcode(10) = "6" Kcode(11) = "5" Kcode(12) = "4" Kcode(13) = "A" Kcode(14) = "3" Kcode(15) = "2" Kcode(16) = "1" Debpos = Nokey ' Nessun tasto premuto in Debouncing Debcnt = 0 ' Inizializza contatore per Debouncing Reppos = Nokey ' Nessun tasto premuto in Autorepeat Repcnt = 0 ' Inizializza contatore per Autorepeat End Sub ' Abbassa solo una delle 4 colonne della tastiera a matrice sulla GMM TST3. ' Ingresso: Kcol = Numero colonna da abbassare (0..3) ' Uscita: Nulla Sub Set_col() If Kcol = 0 Then ' Setta stato colonna 0 Pincol0 = 0 Else Pincol0 = 1 End If If Kcol = 1 Then ' Setta stato colonna 1 Pincol1 = 0 Else Pincol1 = 1 End If If Kcol = 2 Then ' Setta stato colonna 2 Pincol2 = 0 Else Pincol2 = 1 End If If Kcol = 3 Then ' Setta stato colonna 3 Pincol3 = 0 Else Pincol3 = 1 End If End Sub ' Preleva e controlla stato delle 4 righe della tastiera a matrice sulla GMM TST3 ' Ingresso: Nulla ' Uscita: Krow = Numero riga abbassata (0..3, Nokey se nessuna Ë abbassata) Sub Get_row() Krow = Nokey ' Setta stato righe per nessun tasto premuto If Pinrow0 = 0 Then ' Controlla e setta stato riga 0 Krow = 0 End If If Pinrow1 = 0 Then ' Controlla e setta stato riga 1 Krow = 1 End If If Pinrow2 = 0 Then ' Controlla e setta stato riga 2 Krow = 2 End If If Pinrow3 = 0 Then ' Controlla e setta stato riga 3 Krow = 3 End If End Sub ' Verifica stato della tastiera a matrice sulla GMM TST3, abbassando tutte le ' 4 colonne e controllando le 4 righe che la compongono, In caso di diversi ' tasti contemporaneamente premuti, viene restituita la posizione di quello ' collegato alla colonna maggiore. La posizione Ë calcolata con operazioni ' logiche invece che matematiche, in modo da ottimizzare i tempi di esecuzione. ' Ingresso: Nulla ' Uscita: Keypos = Posizione tasto premuto su tastiera a matrice (Nokey se nessun tasto) Sub Scan_keypos() Keypos = Nokey ' Inizializza codice di nessun tasto premuto Kcol = 0 ' Setta colonna attuale=la prima Do Call Set_col() ' Abbassa colonna attuale Call Get_row() ' Preleva stato righe If Krow <> Nokey Then ' Se tasto premuto sulla colonna attuale Keypos = Kcol ' Ottiene posizione tasto premuto da colonna Shift Keypos , Left , 2 ' e riga a partire da 0: moltiplica colonna per 4 Keypos = Keypos Or Krow ' ed aggiunge riga Incr Keypos ' Ottiene posizione tasto a partire da 1 End If Incr Kcol ' Incrementa colonna attuale Loop Until Kcol > 3 ' Ripete fino ad ultima colonna End Sub ' Verifica stato della tastiera a matrice sulla GMM TST3, effettuandone la ' scansione e gestendo un Debouncing. Tale Debouncing evita di riconoscere i ' tipici rimbalzi di ogni pulsante elettrico come pressioni e rilasci dello ' stesso, ottenendo uno stato reale dei tasti premuti. ' Ingresso: Debpos = Posizione tasto premuto in Debouncing ' Debcnt = Contatore per Debouncing ' Uscita: Keypos = Posizione tasto reale premuto (Nokey se nessun tasto) ' Debpos = Posizione tasto premuto in Debouncing aggiornato ' Debcnt = Contatore per Debouncing aggiornato Sub Deb_key() Call Scan_keypos() ' Effettua scansione tastiera a mamtrice ' Gestione Debouncing: controlla se l'eventuale tasto premuto Ë rimasto ininterrottame premuto per tutto ' il tempo di debouncing ed in caso affermativo ne restituisce il codice. Tale controllo viene ' effettuato tramite due variabili: la Debpos memorizza la posizione del tasto precedentemente premuto ' e la Debcnt conta il numero di scansioni consecutive con tasto premuto. AffinchË la durata del ' Debouncing corrisponda al valore definito in Debtime, la procedura Deb_key() deve essere chiamata ad ' intervalli regolari di tempo lunghi Debdt. If Keypos <> Nokey Then ' Se c'Ë un tasto premuto If Keypos = Debpos Then ' Se tasto era gi? premuto, ovvero in Debouncing Incr Debcnt ' Incrementa contatore Debouncing Else ' Tasto non era gi? premuto Debpos = Keypos ' Salva posizione nuovo tasto in Debouncing Debcnt = 0 ' Azzera contatore per Debouncing End If If Debcnt >= Debcycle Then ' Se trascorso tempo durata Debouncing Debcnt = 0 ' Azzera contatore per ripartire con prossimo Debouncing End If Else ' Nessun tasto premuto Debpos = Nokey ' Setta nessun tasto in Debouncing Debcnt = 0 ' Azzera contatore per Debouncing End If End Sub ' Verifica stato della tastiera a matrice sulla GMM TST3, effettuandone la ' scansione, gestendo un Debouncing e l'Autorepeat. L'Autorepeat definisce le ' tempistiche di riconoscimento tasti premuti a Rep1sttime per il primo tasto ' premuto. ed a Repnexttime per i prossimi. ' Ingresso: Reppos = Posizione tasto premuto in Autorepeat ' Repcnt = Contatore per Autorepeat ' Uscita: Key = Codice tasto reale premuto con Autorepeat (Nokey se nessun tasto) ' Reppos = Posizione tasto premuto in Autorepeat aggiornato ' Repcnt = Contatore per Autorepeat aggiornato Sub Rep_key() Call Deb_key() ' Preleva stato tastiera a matrice con Debouncing ' Gestione Autorepeat: controlla se l'eventuale tasto premuto Ë stato appena premuto od Ë rimasto ' premuto per tutto il tempo di autorepeat, ed in caso affermativo ne restituisce il codice. Tale ' controllo viene effettuato tramite due variabili: la Reppos memorizza la posizione del tasto ' precedentemente premuto e la Repcnt conta il numero di scansioni consecutive con tasto premuto. ' Il controllo sulla fine del tempo di Autorepeat viene sempre effettuato sul tempo maggiore ' Rep1sttime, ma il contatore viene inizializzato con un valore diverso a seconda se Ë il primo ' Autorepeat od uno sucessivo. AffinchË le durate dell'Autorepeat corrispondano ai valori definiti ' in Rep1sttime e Repnexttime, la procedura Rep_key() deve essere chiamata ad intervalli regolari ' di tempo lunghi Debdt. Key = Nokey ' Nessun tasto reale premuto If Keypos <> Nokey Then ' Se c'Ë un tasto premuto If Keypos = Reppos Then ' Se tasto era gi? premuto, ovvero in Autorepeat Incr Repcnt ' Incrementa contatore Autorepeat Else ' Tasto non era gi? premuto Reppos = Keypos ' Salva posizione nuovo tasto in Autorepeat Repcnt = 0 ' Azzera contatore per primo Autorepeat Key = Kcode(keypos) ' Preleva codice tasto reale appena premuto End If If Repcnt >= Rep1stcycle Then ' Se trascorso tempo durata primo Autorepeat Repcnt = Nextcycle ' Setta contatore per prossimo Autorepeat Key = Kcode(keypos) ' Preleva codice tasto reale premuto in Autorepeat End If Else ' Nessun tasto premuto Reppos = Nokey ' Setta nessun tasto in Autorepeat Repcnt = 0 ' Azzera contatore per primo Autorepeat End If End Sub '******************* Fine procedure usate dal programma ************************