/********************************************************************** ** Programma: S2DEB6.C - Versione : 1.1 - 04 Novembre 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 Sommatore capace di cancellare l'input corrente. I valori vengono inseriti dalla tastiera a matrice della DEB01 e vengono Mostrati sul monitor del sistema di sviluppo. La tastiera a matrice assume le seguenti funzioni: A - Stampa totale e ricomincia l'input D - Cancella l'input corrente * - Punto decimale # - Inserisci il numero nella catasta 1, ..., 9 - Input delle cifre Il display della DEB 01 non viene utilizzato. */ #include #include #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[]; // // ********************* 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 tasto; // Tasto letto. double val=0.0, totale=0.0; unsigned char i=0, punto=0; char *input; init(); // Inizializzazioni input=malloc(21); input[20]='\0'; while(1) // Ripete all'infinito { tasto=eseguiInOut(10000, 0); // Lettura tasti if(i<20) // Se non si sono inserite { // Ancora 20 cifre if(tasto>=0 && tasto<=9) // Se il tasto premuto e' { // Una cifra decimale putch('0'+tasto); // Scrivila e memorizzala input[i]='0'+tasto; i++; } } if(tasto==14 && punto==0 && i<20) // Se il tasto premuto e' * { // E ancora non c'e' il punto punto=1; // Decimale, mettilo putch('.'); // Stampalo input[i]='.'; // Memorizzalo i++; } if(tasto==15) // Se il tasto premuto e' # { // Acquisici il numero input[i]='\0'; // Termina l'input val=atof(input); // Convertilo in numero punto=0; // Stampa e reinizializza input[0]='\0'; // L'input di un numero i=0; cprintf("\r\n"); // Va a capo totale=totale+val; // Aggiungi il numero al } // Totale if(tasto==10) // Se il tasto premuto e' A { // Stampa il totale cprintf(" ----- TOTALE -----\r\n"); cprintf("%lf\r\n\r\n", totale); input[0]='\0'; // Reinizializza l'input i=0; // Per ricevere una nuova punto=0; // Serie di numeri totale=0.0; // Reinizializza il totale } if(tasto==13) // Se il tasto premuto e' D { // Cancella l'immissione cprintf("\r \r"); input[0]='\0'; // Reinizializza l'input punto=0; i=0; } } } // 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 6 per l'utilizzo della sezione 2 della scheda DEB 01."); cprintf("\r\n"); cprintf("\r\n"); cprintf("Il programma simula un sommatore capace di cancelare l'ultimo input"); cprintf("\r\n"); cprintf("Sfruttando la tastiera a matrice della DEB 01."); cprintf("\r\n"); cprintf("\r\n"); cprintf("Funzionamento dei tasti : A - Stampa totale e ricomincia l'input"); cprintf("\r\n"); cprintf(" D - Cancella l'input corrente"); cprintf("\r\n"); cprintf(" * - Punto decimale"); cprintf("\r\n"); cprintf(" # - Inserisci il numero nella catasta"); cprintf("\r\n"); cprintf(" 1, ..., 9 - Input delle cifre"); 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++) ; }