' ********************************************************************** ' ** Programma: g51ad4ch.BAS - Versione : 1.3 - 16 aprile 2003 ** ' ** Compilatore : BASCOM 8051 DEMO, (IDE e LIB V.2.0.6.0) ** ' ** Scheda : K51-AVR tramite GMB HR84 e GMM 5115 ** ' ** 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 ** ' ********************************************************************** ' ' Questo demo permette di pilotare una periferica I2C BUS a bordo della K51-AVR, ' PCF8591, attraverso il modulo mini-BLOCK GMB HR84 ed un mini modulo grifo(r). ' Il PCF8591 e' dotato di quattro ingressi analogici per conversione A/D con ' risoluzione ad 8 bit, tutte le operazioni di conversione e la lettura della ' combinazione acquisita avvengono tramite interfaccia seriale sincrona I2C BUS. ' Il demo permette di impostare quale canale convertire tramite la tastiera del ' PC, e di leggere la combinazione sui display a 7 segmenti della K51-AVR. ' ' Prima di compilare selezionare nel menu Option/Compiler/Misc/ : ' Byte End 5F. ' ' ' 05.06.2000 by Adriano Pedrielli (per la sola K51) ' ' 16.04.2003 by Graziano Gaiba ' ' Modificato per pilotare la periferica gestita sulla K51-AVR attraverso ' una GMB HR84 e una GMM 5115. ' '*********************************************************************** ' '****************** Direttive del compilatore ************************** ' $regfile = "grifo_mm.dat" $romstart = &H0 ' indirizzo di partenza del codice ' macchina per FLASH $ramstart = &H0 ' indirizzo di partenza della area ' dati $ramsize = &H100 ' pongo a 256 bytes la area dati $crystal = 14745600 ' frequenza di clock del microcontrollore $baud = 19200 ' velocit? di comunicazione RS-232 '$large ' indirizzamento a 16 bit $map Config Sda = P2.0 ' I2C serial DATA Config Scl = P2.1 ' I2C serial CLK ' '****************** Dichiarazione delle costanti *********************** ' Dim Saa1064 As Const &H38 ' Slave address SAA1064 Dim Wsaa1064 As Const &H70 ' Slave address SAA1064 in Write Dim Rsaa1064 As Const &H71 ' Slave address SAA1064 in Read ' ***************** Elenco indirizzi per Saa1064 *********************** Dim Ctb As Const 0 ' Ind. Control byte Dim Dig1 As Const 1 ' Ind. Digit 1 Dim Dig2 As Const 2 ' Ind. Digit 2 Dim Dig3 As Const 3 ' Ind. Digit 3 Dim Dig4 As Const 4 ' Ind. Digit 4 ' ********************************************************************** ' Dim Pcf8591 As Const &H48 ' Slave address PCF8591 Dim Wpcf8591 As Const &H90 ' Slave address PCF8591 in Write Dim Rpcf8591 As Const &H91 ' Slave address PCF8591 in Read ' '****************** Dichiarazione delle variabili ********************** ' Dim Dig As Byte ' valore di un digit Dim Cifh As Byte ' cifra 4 bit alti in HEX Dim Cifl As Byte ' cifra 4 bit bassi in HEX Dim N1 As Byte ' numero 1 byte per DY3 e DY4 Dim Valore As Byte ' numero da convertire Dim C As Byte ' indica il canale da convertire ' '****************** Dichiarazione delle procedure ********************** ' Declare Sub Iniz ' Inizializzazione periferiche Declare Sub Canale ' Gestione numero canale Declare Sub Ad(c As Byte , Valore As Byte) ' Gestione del A/D converter Declare Sub Cifre(valore As Byte , Cifh As Byte , Cifl As Byte ) ' converte un numero in 2 cifre HEX Declare Sub Digit(dig As Byte ) ' Converte un numero da 0-F in 7 segmenti Declare Sub Vis_num(n1 As Byte) ' visualizza un byte in HEX ' '************************* Programma main ****************************** ' Main: ' Ritardo Assestamento segnali Waitms 1 Print Chr(12) Print "Questo demo e' stato progettato per funzionare solo su una GMM 5115" Print "Proseguite nell'esecuzione solo se avete la scheda giusta!" Print "Se intendete proseguire, premete un tasto" Do Valore = Inkey Loop Until Valore <> 0 Call Iniz ' inizializzazioni C = 0 Valore = 0 Print Print "Premere + per incrementare il canale da convertire" Print "Premere - per decrementare il canale da convertire" Print Do Call Ad(c , Valore) ' eseguo la conversione del canale Call Vis_num(valore) ' visualizzo il byte in HEX Call Canale Loop Return End ' '************************ Fine del programma *************************** ' ' '**************************** Procedure ******************************** ' ' Gestione numero canale ' Sub Canale Valore = Inkey If Valore = "+" Then If C = 3 Then C = 0 Else Incr C End If End If If Valore = "-" Then If C = 0 Then C = 3 Else Decr C End If End If End Sub ' ******************* Inizializzazione delle periferiche ***************** ' Questa procedura esegue tutte le inizializzazioni del sistema. ' Parametri: ' Ingresso : nulla ' Uscita : nulla ' ************************************************************************ ' Sub Iniz ' Inizializzazione periferiche Do I2creceive Rsaa1064 , Valore ' leggo il registro di stato Loop Until Valore = 0 ' attendo accensione SAA1064 I2cstart ' sequenza di Start per I2CBUS I2cwbyte Wsaa1064 ' comunico lo Slave address I2cwbyte Ctb ' Punto al registro di controllo I2cwbyte &B00100111 ' bit0 =1 dynamic mode ' bit1 =1 digit 1+3 not blanked ' bit2 =1 digit 2+4 not blanked ' bit3 =0 no test segment ' bit4 =0 no 3mA segment current ' bit5 =1 6mA segment current ' bit6 =0 no 12mA segment current ' bit7 =0 indifferente I2cwbyte 0 ' scrive DY1 off I2cwbyte 0 ' scrive DY2 off I2cwbyte 0 ' scrive DY3 off I2cwbyte 0 ' scrive DY4 off I2cstop End Sub ' ' ***************** Gestione del A/D converter **************************** ' Questa procedura permette di eseguire una conversione analogica su uno ' dei 4 canali disponibili su IC2 (PCF8591). ' Parametri: ' Ingresso : C as byte, indica il canale da convertire (0...3) ' Uscita : Valore as byte, valore da 0 a 255 (0v...+Vref) ' ************************************************************************ ' Sub Ad(ch As Byte , Valore As Byte) ' Gestione del A/D converter C = C And &H03 ' tengo Bit 0 e Bit 1 I2csend Wpcf8591 , C ' indico il canale da convertire I2creceive Rpcf8591 , Valore ' leggo la conversione precedente I2creceive Rpcf8591 , Valore ' leggo la conversione attuale End Sub ' ' ***************** Converte un numero da 0 a F in 7 segmenti *********** ' Questa procedura converte una cifra da 0 a F nel formato 7 segmenti, se ' il valore e maggiore di F il display risulta spento. ' Parametri: ' Ingresso : dig as byte, valore da 0 a F ' Uscita : dig as byte, valore in formato 7 segmenti. ' ************************************************************************ ' Sub Digit(dig As Byte ) ' Converte un numero da 0-F in 7 segmenti If Dig < 16 Then ' il numero risulta minore di 16 Dig = Lookup(dig , Tab_7seg) ' leggo in tabella il valore Else Dig = 0 ' se = 10 o superiore azzero End If End Sub ' ' ***************** Converte 1 byte in due cifre HEX ******************** ' Questa procedura converte 1 byte da 0 a 255 in due cifre esadecimali a ' 4 bit. ' Parametri: ' Ingresso : Valore as byte, valore da 0 a 255 ' Uscita : Cifh as byte, cifra del nibble alto ' Cifl as byte, cifra del nibble basso ' ************************************************************************ ' Sub Cifre(valore As Byte , Cifh As Byte , Cifl As Byte ) ' converte un numero in due cifre HEX Cifh = Valore And &HF0 ' prelevo i 4 bit alti Cifh = Cifh / 16 ' sposto in basso i 4 bit alti Cifl = Valore And &H0F ' prelevo i 4 bit bassi End Sub ' ' *********************** Visualizza un byte in HEX ********************** ' Nel primo display viene visualizzato numero del canale convertito, ' il secondo display risulta spento. ' Questa procedura permette di visualizzare un byte nel formato esadecimale. ' nei 2 display a destra. Es: 255= FFH, 32= 20H ecc. ' Parametri: ' Ingresso : N1 as byte, numero da visualizzare in HEX ' Uscita : nulla ' ************************************************************************ ' Sub Vis_num(n1 As Byte) ' visualizza un byte in HEX I2cstart ' sequenza di START I2cwbyte Wsaa1064 ' slave address I2cwbyte Dig1 ' punto al diplay 1 (DY1) Call Digit(c) ' converto la cifra decine in 7 seg. I2cwbyte Dig ' scrivo il primo display DY1 I2cwbyte 0 ' scrivo il secondo display DY2 Call Cifre(n1 , Cifh , Cifl) ' converto il numero1 in 2 cifre HEX Call Digit(cifh) ' converto la cifra in HEX in 7 seg. I2cwbyte Dig ' scrivo il display DY3 Call Digit(cifl) ' converto la cifra in HEX in 7 seg. I2cwbyte Dig ' scrivo il display DY4 I2cstop ' sequenza di stop End Sub ' ' ************* Tabella conversione per cifra a 7 segmenti da 0 a 15 ******* Tab_7seg: ' num. 0 1 2 3 4 5 6 7 8 9 Data &H3F , &H06 , &H5B , &H4F , &H66 , &H6D , &H7D , &H07 , &H7F , &H6F ' num. A b C d E F Data &H77 , &H7C , &H39 , &H5E , &H79 , &H71 ' ************************************************************************** '