' ********************************************************************** ' * File: Corso_BASCOMAVR_019.BAS * ' * Versione: 1.1 * ' * Data: 19.08.09 * ' * Ambiente sviluppo: Bascom-AVR Demo Ver. 1.11.9.1 + * ' * + AVR bootloader grifo(r) Ver. 1.2 * ' * Schede: GMM AM08 + 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 AVR. ' 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 millisecondi, il primo 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 AVR ' (vedere Configurazioni IDE). ' Il programma funziona solo se la GMM AM08 è 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: Nessuna. ' ' 19/08/09: Corso_BASCOMAVR_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 M8DEF.DAT nella directory di ' installazione del BASCOM-AVR e se non disponibile copiarlo e dopo ' rilanciare l'IDE. ' 2) Nella finestra "Options | Compiler | Chip" impostare: ' Chip: m8def.dat ' XRAM: None ' HW Stack: 64 ' Soft Stack: 32 ' Framesize: 64 ' XRAM waitstate: disattivo ' External Access Enable: disattivo ' 3) Nella finestra "Options | Communication" settare: ' COM port = la linea del PC collegata alla GMM AM08, 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 ' 4) Al termine della compilazione, della programmazione del codice nella ' GMM AM08, aprire la finestra di emulazione terminale del BASCOM AVR con ' l'opzione: Tools | Terminal emulator (Ctrl+T) ed a questo punto resettare ' o riaccendere il Mini Modulo. '********************** Direttive del compilatore ****************************** $regfile "M8DEF.DAT" ' File di definizione microcontrollore usato $romstart = &H0 ' Indirizzo inizio codice in FLASH $crystal = 7372800 ' Frequenza quarzo del microcontrollore $hwstack = 64 ' Spazio per stack hardware $swstack = 32 ' Spazio per stack software $framesize = 64 ' Spazio per frame $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 nella 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 AM08 GMM AM08 usato ' TST1.Row0 33 27 ADC7 ADC7 ' TST1.Row1 32 26 PC0 ADC0 PC0 ' TST1.Row2 31 25 PC1 ADC1 PC1 ' TST1.Row3 30 24 PB1 OC1A PB1 ' TST1.Col0 29 23 PB0 ICP PB0 ' TST1.Col1 28 22 PB2 OC1B /SS PB2 ' TST1.Col2 27 21 PD6 AIN0 PD6 ' TST1.Col3 26 20 PD7 AIN1 PD7 ' ' Segnale pin COMx pin CN5 pin Z1 pin Segnale Segnale ' PC DB9 GMM TST3 GMM TST3 GMM AM08 GMM AM08 uP ' TX 3 3 9 3 RxD RS232 PD0 ' RX 2 2 10 4 TxD RS232 PD1 ' GND 5 5 20 14 GND - ' Da questa 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 7 ' Ingresso A/D collegato a riga 0 tastiera TST1 GMM TST3 Pinrow1 Alias Pinc.0 ' Bit con segnale d'ingresso collegato a riga 1 tastiera TST1 GMM TST3 Pinrow2 Alias Pinc.1 ' Bit con segnale d'ingresso collegato a riga 2 tastiera TST1 GMM TST3 Pinrow3 Alias Pinb.1 ' Bit con segnale d'ingresso collegato a riga 3 tastiera TST1 GMM TST3 Pincol0 Alias Portb.0 ' Bit con segnale d'uscita collegato a colonna 0 tastiera TST1 GMM TST3 Pincol1 Alias Portb.2 ' Bit con segnale d'uscita collegato a colonna 1 tastiera TST1 GMM TST3 Pincol2 Alias Portd.6 ' Bit con segnale d'uscita collegato a colonna 2 tastiera TST1 GMM TST3 Pincol3 Alias Portd.7 ' Bit con segnale d'uscita collegato a colonna 3 tastiera TST1 GMM TST3 Pinrx Alias Ddrd.0 ' Bit con direzione segnale collegato a RxD GMM AM08 Pintx Alias Ddrd.1 ' Bit con direzione segnale collegato a TxD GMM AM08 '************************ 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_keypos() ' Verifica stato tastiera a matrice Declare Sub Deb_key() ' Verifica stato tastiera a matrice con debouncing Declare Sub Rep_key() ' Preleva stato tastiera a matrice con Autorepeat e Debouncing '************************** Programma principale ******************************* Main: Pinrx = 0 ' Inizializza segnali per comunicazione seriale Pintx = 0 ' 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() ' Delle 8 linee necessarie a gestire la tastiera a matrice 4x4, una è ' collegata ad un segnale analogico del microcontrollore e viene quindi ' gestita tramita la corrispondente sezione A/D converter Config Adc = Single , Prescaler = Auto , Reference = Avcc ' Inizializza sezione A/D con conversione su richieta, Start Adc ' miglior prescaler, Vref=5 V e la abilita ' Inizializza rimanenti 7 linee della tastiera a matrice collegate a segnali ' digitali del microcontrollore Ddrc.0 = 0 ' Inizializza segnali digitali collegati a righe della Ddrc.1 = 0 ' tastiera a matrice come ingressi digitali Ddrb.1 = 0 Pincol0 = 1 ' Inizializza segnali collegati a colonne della Ddrb.0 = 1 ' tastiera a matrice come uscite digitali alte Pincol1 = 1 Ddrb.2 = 1 Pincol2 = 1 Ddrd.6 = 1 Pincol3 = 1 Ddrd.7 = 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() Local Adres As Word ' Variabile locale per risultato conversione A/D Krow = Nokey ' Setta stato righe per nessun tasto premuto ' Delle 4 linee per le righe della tastiera a matrice 4x4, una è collegata ' ad un segnale analogico del microcontrollore e viene quindi acquisita ' tramita il corrispondente canale della sezione A/D converter Adres = Getadc(pinrow0) ' Acquisisce stato ingresso A/D collegato a riga 0 If Adres < 100 Then ' Controlla e setta stato riga 0 Krow = 0 End If ' Acquisisce rimanenti 3 righe della tastiera a matrice collegate a segnali ' digitali del microcontrollore 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 ************************