/********************************************************************** ** Programma: S2DEB7.C - Versione : 1.1 - 28 Ottobre 1999 ** ** Compilatore : GCTR V. 1.1 ** ** Scheda : GPC(r) 188F ** ** Ditta: grifo(r) ITALIAN TECHNOLOGY ** ** Via Dell' Artigiano 8/6 40016 San Giorgio di Piano (BO) ** ** Tel.+39 051 892 052 Fax +39 051 893 661 ** ** http://www.grifo.com http://www.grifo.it ** ** sales@grifo.it tech@grifo.it grifo@grifo.it ** ** ** ** Realizzato da: Graziano Gaiba ** ********************************************************************** Il programma utilizza la sezione 2 della scheda DEB 01 per realizzare un timer completo di controllo dei tempi parziali. La tastiera a matrice assume le seguenti funzioni: A - Inizio/Fine conteggio (non azzera il display) C - Congela/Riattiva il display ma continua a contare 0 - Azzera il display (mai mentre avviene il conteggio) Durante il congelamento del valore sul display il punto decimale delle unita' e' mantenuto acceso. Il valore del conteggio viene mostrato nelle quattro cifre decimali del display, pertanto si azzera automaticamente quando arriva a 9999. */ #include #include #include #include "DEB01.H" // // ********************* Dichiarazione delle costanti *********************** // // Registri del port ppi 8255 const unsigned int PA = 0x0F200; // Valore del port A const unsigned int PB = 0x0F201; // Valore del port B const unsigned int PC = 0x0F202; // Valore del port C const unsigned int RS = 0x0F203; // Registro di controllo // Registri linea seriale B const unsigned int RSB = 0x0F080; // Registro di controllo const unsigned int RDB = 0x0F081; // Registro dati // Pilotaggio dei segmenti // Viene memorizzato lo schema delle cifre da 0 a 9 // La variabile e' memorizzata nel file deb01.h. Non decommentare. // const unsigned short int segmenti[]={0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F}; // // ********************* Dichiarazione delle variabili ********************** // // Le variabili globali sono memorizzate nel file Deb01.h, che quindi deve // Essere incluso con l'istruzione #include "deb01.h" se si trova nella // Directory corrente o #include se si trova nel path di ricerca // Degli header files. // Il nome delle variabili globali inizia sempre con la stringa DEB01, per // Cui fare attenzione ai possibili conflitti. // // ******************** Dichiarazione delle procedure *********************** // //Inizializzazione void init(void); // Legge la tastiera e scrive sul display unsigned char eseguiInOut(unsigned int, unsigned char); // Inizializza la seriale B void iniserb (unsigned long baud,unsigned char bitxchr,unsigned char stopbit,unsigned char parity); // Pulisce lo schermo void clrscr (void); // Attesa void attesa(void); // // **************************** Programma main ****************************** // void main(void) { unsigned char tasti; // Tasto letto. unsigned int n=0, uscita=0; // Conteggio e valore da // Scrivere sul display. unsigned char mostra=1, conta=0, punto=0; // Variabili "booleane": // Mostra il conteggio sul // display o congelalo // Incrementa o non // incrementare il contatore // Stato del punto decimale // per i quattro display: // dal MSB verso il LSB // se il bit ha valore 1 // il punto viene acceso. init(); // Inizializzazioni while(1) // Ripete all'infinito { tasti=eseguiInOut(uscita, punto); // Lettura tasti if(tasti==10) // Tasto A (10 esadecimale) { conta=! conta; // Commuta il flag che // determina se incrementare // o no il contatore. mostra=1; // Mostra il contatore sul // display. punto=0; // Punti decimali spenti. } if(tasti==12) // Tasto C (12 esadecimale) { mostra=! mostra; // Commuta il flag che // determina se mostrare il // contatore sul display o // congelarne il valore. if(mostra) // Se il valore va sul display punto=0; // niente punto decimale, else // altrimenti punto=0x10; // indica tempo parziale. } if(tasti==0) // Tasto zero if(! conta) // Se non e' in corso un n=0; // conteggio, azzera il // contatore. if(conta) // Se e' in corso il conteggio n++; // incrementa il contatore. if(mostra) // Se il contatore va sul uscita=n; // display, mostralo. if(n==10000) // Se il contatore ha raggiunto n=0; // 10000, azzeralo. } } // Questa funzione effettua alcune inizializzazioni void init(void) { iniserb(19200, 8, 1, 0); //Inizializza la seriale B outportb(RS, 0x81); // Inizializza in output i port A, B e C alto // Inizializza in input C basso clrscr(); // Pulisce lo schermo cprintf("Programma di esempio 7 per l'utilizzo della sezione 2 della scheda DEB01."); cprintf("\r\n"); cprintf("\r\n"); cprintf("Il programma fornisce le funzioni di un timer dotato di tempi parziali"); cprintf("\r\n"); cprintf("Sfruttando la tastiera a matrice e il display della DEB 01."); cprintf("\r\n"); cprintf("\r\n"); cprintf("Funzionamento dei tasti : A - Inizio/Fine conteggio"); cprintf("\r\n"); cprintf(" C - Visualizza tempo parziale/conteggio"); cprintf("\r\n"); cprintf(" 0 - Azzera il display"); cprintf("\r\n"); } // Questa funzione rinfresca il contenuto dei display a sette segmenti con il // Valore contenuto nel parametro numero, gestendo separatemente l'accensione // Dei punti decimali usando i 4 bits piu' significativi del parametro dots: // bit 7 pilota il punto delle migliaia (1=acceso, 0=spento) // bit 6 pilota il punto delle centinaia (1=acceso, 0=spento) // bit 5 pilota il punto delle decine (1=acceso, 0=spento) // bit 4 pilota il punto delle unita' (1=acceso, 0=spento) // Viene inoltre letta la tastiera a matrice, effettuando anche il debouncing, // il valore del parametro restituito segue lo schema: // 1=1 2=2 3=3 A=10 // 4=4 5=5 6=6 B=11 // 7=7 8=8 9=9 C=12 // *=14 0=0 #=15 D=13 // 0xFF Nessun tasto premuto unsigned char eseguiInOut(unsigned int numero, unsigned char dots) { unsigned int valore=0; // Situazione della pressione dei tasti sulla // Tastiera a matrice: // 1=bit 0 2=bit 4 3=bit 8 A=bit 12 // 4=bit 1 5=bit 5 6=bit 9 B=bit 13 // 7=bit 2 8=bit 6 9=bit 10 C=bit 14 // *=bit 3 0=bit 7 #=bit 11 D=bit 15 unsigned short int cifra[]={0, 0, 0, 0}; // Scomposizione del numero // Da mettere sul display in // Quattro cifre: migliaia, // Centinaia, decine, unita' // Tabella di traduzione tra l'indice del bit a 1 nella variabile // Che memorizza la pressione dei tasti e il valore associato ad ogni // Tasto: // 1=1 2=2 3=3 A=10 // 4=4 5=5 6=6 B=11 // 7=7 8=8 9=9 C=12 // *=14 0=0 #=15 D=13 // E' memorizzata nel file deb01.h. Non decommentare. // unsigned char tab[]={13, 12, 11, 10, 15, 9, 6, 3, 0, 8, 5, 2, 14, 7, 4, 1}; unsigned char i, j, t, letto=0x10; // Variabili di uso generico if(numero < 10000) { // Scomposizione del numero da scrivere sul display in: cifra[0]=numero / 1000; // migliaia cifra[1]=(numero / 100) - cifra[0]*10; // centinaia cifra[2]=(numero / 10) - cifra[0]*100 - cifra[1]*10; // decine cifra[3]=numero - cifra[0]*1000 - cifra[1]*100 - cifra[2]*10; // unita' } else cifra[0]=cifra[1]=cifra[2]=cifra[3]=0x10; // Scansione delle 4 colonne da 4 tasti della tastiera a matrice e // Allo stesso tempo aggiornamento del display a loro collegato. for(i=0; i<4; i++) { outportb(PC, 1 << (i+4)); // Attivazione dell'i-esima colonna // E dell'i-esimo display a partire // Da sinistra (colonna 147*, display // Delle migliaia) verso destra. outportb(PA, ~(DEB01segmenti[cifra[i]] | (dots & 0x80))); // L'i-esima cifra di numero viene // Usata per pilotare il relativo // Display, l'array segmenti decide // Quali segmenti vanno accesi // (bit 0..6 del port A), il settimo // Bit (punto decimale) viene // Gestito da dots. I valori sono // Negati perche' il display funziona // In logica complementata. dots=dots << 1; // Seleziona il punto decimale del // Display successivo. t=inportb(PC); // Legge la colonna della tastiera // A matrice attualmente attivata. for(j=0; j<4; j++) // 4 tasti da acquisire. { valore=valore << 1; // Fai posto al bit del prossimo // Tasto if(! (t & 0x01)) // Ponilo a 1 se il tasto e' premuto valore=valore | 0x0001; t=t >> 1; // Esamina il tasto successivo } attesa(); // Attesa per aumentare la // Persistenza dei display. } if(DEB01contaChar==10) // Se questo valore e' stato // Raggiunto, il carattere e' // Gia' stato restituito... { DEB01contaChar=0; // ...quindi annullalo e sospendi DEB01inChar=0x10; // La ricezione fino a che non ci } // Sara' piu' alcun tasto premuto. if(valore) // Se almeno un tasto e' stato { // Premuto... for(i=0; i<16; i++) // Decodificalo secondo la // Tabella mostrata in cima. { if(valore & 0x0001) letto=DEB01tab[i]; valore=valore >> 1; } if(DEB01inChar!=0xFF) // Se si era gia' registrata la // Pressione di un tasto if(DEB01inChar!=letto) // Diverso da quello appena letto { DEB01inChar=0x10; // Annulla la digitazione e DEB01contaChar=0; // Sospendi la ricezione } else // Altrimenti { DEB01contaChar++; // Incrementa il contatore del } // Carattere. else { DEB01contaChar=0; // Se non si era registrato alcun DEB01inChar=letto; // Carattere, inizializza } } else { DEB01contaChar=0; // Se non e' stato premuto alcun DEB01inChar=0xFF; // Carattere, riprendi la } // Ricezione. if(DEB01contaChar==10) // Se uno stesso carattere e' return DEB01inChar; // Stato registrato 20 volte, else // Consideralo premuto. return 0xFF; // Altrimenti comunica che } // Nessun tasto e' stato premuto void iniserb (unsigned long baud,unsigned char bitxchr,unsigned char stopbit,unsigned char parity) /* Inizializza la linea seriale ser con il protocollo definito nei parametri baud (150 - 115200), bitxchr (5,6,7,8), stopbit (1,2) e parity (0=none, 1=odd, 2=even). */ { unsigned int timec; unsigned char d; outportb(RSB,0x00A); // seleziona funzionamento standard outportb(RSB,0x000); outportb(RSB,0x00B); // TxC = RxC = Baud Rate generator interno outportb(RSB,0x050); timec=(345600/baud)-2; // Programma Baud Rate con quarzo da 11.0592 MHz outportb(RSB,0x00C); outportb(RSB,(timec & 0x000FF)); outportb(RSB,0x00D); outportb(RSB,(timec >> 8)); outportb(RSB,0x00E); // no local loopback, no auto echo, abilita baud outportb(RSB,0x003); // rate generator interno outportb(RSB,0x00F); // disabilita alcune sorgenti interrupt outportb(RSB,0x000); d=0x040; // clock x 16 if (stopbit==1) d=d | 0x004; // 1 stop bit else d=d | 0x00C; // 2 stop bit switch (parity) { case 0: d=d; // No parity break; case 1: d=d | 0x001; // Odd parity break; case 2: d=d | 0x003; // Even parity break; } outportb(RSB,0x004); outportb(RSB,d); switch (bitxchr) { case 5: d=0x008; // 5 Bit x chr, Tx enable break; case 6: d=0x048; // 6 Bit x chr, Tx enable break; case 7: d=0x028; // 7 Bit x chr, Tx enable break; case 8: d=0x068; // 8 Bit x chr, Tx enable break; } outportb(RSB,0x005); outportb(RSB,d); switch (bitxchr) { case 5: d=0x001; // 5 Bit x chr, Rx enable break; case 6: d=0x081; // 6 Bit x chr, Rx enable break; case 7: d=0x041; // 7 Bit x chr, Rx enable break; case 8: d=0x0C1; // 8 Bit x chr, Rx enable break; } outportb(RSB,0x003); outportb(RSB,d); outportb(RSB,0x001); // Disabilita interrupts outportb(RSB,0x000); } void clrscr(void) /* Effettua la funzione di clear screen per una generica console */ { unsigned char r; putch('\r'); for (r = 0; r < 25 ; r++) { putch('\n'); // Trasmette 25 Line Feed } } // Impone un'attesa void attesa(void) { unsigned long int i; for(i=0; i<300; i++) ; }