'****************************************************************** '* Nome : gmbi2c.bas * '* Autore : Graziano GAIBA * '* Data : 17/06/04 * '* Versione : 1.1 * '* Scheda : GMM 876 * '* Linguaggio: PIC BASIC Standard Ver. 1.45 * '* Azienda : Copyright (c) 2004 grifo(r) ITALIAN Technology * '* : All Rights Reserved * '* : Tel.: +39 051 892052 Fax: +39 051 893661 * '* : http://www.grifo.com http://www.grifo.it * '* : E-mail: grifo@grifo.it * '****************************************************************** ' ' Questo demo permette di comunicare con disposivi I2C BUS collegati a CN3. ' E' possibile leggere e scrivere byte ad un qualsiasi slave address ' ed address inseriti da console. In particolare, in lettura il byte ' ricevuto viene visualizzato, mentre in caso di scrittura il dato ' inserito viene spedito. ' ' Per la comunicazione, viene usata la seriale hardware implementata ' nel demo Usart.bas del PIC Basic standard opportunamente ' modificata. ' ' ' ********************************************************************* ' * Definizioni e Costanti * ' ********************************************************************* ' ' Registri del PIC symbol INDF = 0 symbol FSR = $04 ' Port di I/O symbol PORTA = $05 symbol TRISA = $85 ' banco 1 symbol PORTB = $06 symbol TRISB = $86 ' banco 1 symbol PORTC = $07 symbol TRISC = $87 ' banco 1 ' I2C BUS symbol SSPCON2= $91 ' banco 1 symbol SSPBUF = $13 symbol SSPADD = $93 ' banco 1 symbol SSPCON1= $14 symbol SSPSTAT= $94 ' banco 1 ' symbol OPTION_REG = $81 ' banco 1 ' ' Simboli usati dalla seriale hardware implementata ' nel demo Usart.bas del PIC Basic standard ' Definizione registri USART Symbol PIR1 = $0C ' Registro Peripheral Interrupt Flag Symbol RCSTA = $18 ' Registro di stato e controllo ricezione Symbol TXREG = $19 ' Dato da trasmettere Symbol RCREG = $1A ' Dato ricevuto Symbol TXSTA = $98 ' Registro di stato e controllo trasmissione Symbol SPBRG = $99 ' Registro del Baud Rate Generator ' ' ' ********************************************************************* ' * Variabili usate dal programma * ' ********************************************************************* ' ' ' Usate dall'USART SYMBOL UsartST = B0 ' Stato dell'USART SYMBOL UsartOut = B1 ' Carattere da inviare symbol UsartIn = B2 ' Carattere ricevuto ' Valore da stampare come stringa symbol Valore = B3 ' Uso Generico SYMBOL i = B4 SYMBOL c = B5 symbol z = B6 ' Indirizzo e dati in esadecimale per I2C BUS symbol Slave_Address = B7 symbol Indirizzo = B8 symbol DatoIn = B9 symbol DatoOut = B10 symbol Dato = B11 ' Usato dall'input di un valore esadecimale symbol ValoreHex = B12 ' ' ' ********************************************************************* ' * Programma main * ' ********************************************************************* ' Main: gosub Module_init ' Inizializzazione for i=0 to 45 lookup i,("Programma di demo I2C BUS per GMM 876 Rel. 1.1"),usartout gosub charout next i Menu: gosub demoi2cbus goto menu end ' ' ' ********************************************************************* ' * Fine del programma * ' ********************************************************************* ' ' ' Inizializzazione della GMM 876 Module_init: ' ' Inizializza USART per 19200 Baud Poke SPBRG,64 ' Imposta baud rate a 19200 Poke RCSTA,%10010000 ' Abilita porta seriale e ricezione continua Poke TXSTA,%00100100 ' Abilita tramsissione, modalita' asincrona e ' baud rate elevati ' ' Inizializzazione per I2C BUS ' Configura RC3 ed RC4 come ingressi peek trisc, B0 bit3 = 1 bit4 = 1 poke trisc, B0 ' Attiva il modulo SSP in modalita' master I2C BUS, clock 50 kHz poke sspstat, 0 poke sspadd, $63 poke sspcon1, $28 ' Rimettere la pagina 0 prima di uscire dall'asm 'ASM 'ENDASM pause 500 return ' ' ' Demo di utilizzo dellinterfaccia I2C BUS hardware interna del micro DemoI2CBUS: I2CBUSMenu: gosub nlcr for c=0 to 28 lookup c,("1) Leggi",13,10,"2) Scrivi",13,10,"Scelta: "), usartout gosub charout next c ' Attende un carattere tra "1" e "2" e lo stampa I2CBUSLoop: gosub CharIn if usartin < "1" or usartin > "2" then I2CBUSLoop c = usartin usartout = usartin gosub charout gosub nlcr ' Chiede un indirizzo in esadecimale azioneI2CBUS: gosub inputslaveaddress gosub inputindirizzo ' Se l'azione richiesta e' la lettura, la esegue if c = "1" then I2CBUSRead ' Chiede un dato in esadecimale gosub inputdato ' ' Scrive il dato appena inserito all'indirizzo specificato ' ' Genera I2CBUS Start... gosub i2cbusstart '...e attende che venga completato gosub i2cbussynch ' Invia lo Slave Address per scrittura datoout = slave_address gosub i2cbussend ' Se non viene ricevuto l'acknowledge, segnala l'errore peek sspcon2, B0 if bit6 = 1 then notack ' Invia l'indirizzo in cui scrivere il dato datoout = indirizzo gosub i2cbussend ' Se non viene ricevuto l'acknowledge, segnala l'errore peek sspcon2, B0 if bit6 = 1 then notack ' Invia il dato datoout = dato gosub i2cbussend ' Se non viene ricevuto l'acknowledge, segnala l'errore peek sspcon2, B0 if bit6 = 1 then notack ' Invia lo stop gosub i2cbusstop goto I2CBUSDone I2CBUSRead: ' ' Legge un byte dall'indirizzo specificato ' for i = 0 to 7 lookup i,("Valore: "), usartout gosub charout next i ' Genera I2CBUS Start... gosub i2cbusstart '...e attende che venga completato gosub i2cbussynch ' Invia lo Slave Address datoout = slave_address gosub i2cbussend ' Se non viene ricevuto l'acknowledge, segnala l'errore peek sspcon2, B0 if bit6 = 1 then notack ' Invia l'indirizzo da cui leggere il dato datoout = indirizzo gosub i2cbussend ' Se non viene ricevuto l'acknowledge, segnala l'errore peek sspcon2, B0 if bit6 = 1 then notack ' Genera il secondo I2CBUS Start... gosub i2cbusrepstart '...e attende che venga completato gosub i2cbussynch ' Invia lo Slave Address per la lettura datoout = slave_address | $01 gosub i2cbussend ' Se non viene ricevuto l'acknowledge, segnala l'errore peek sspcon2, B0 if bit6 = 1 then notack ' Abilita il ricevitore peek sspcon2, B0 bit3 = 1 poke sspcon2, B0 ' Legge il dato gosub i2cbusget valore = datoin ' Invia l'acknowledge... peek sspcon2, B0 bit4 = 1 poke sspcon2, B0 '...e attende che venga completato gosub i2cbussynch ' Invia lo stop gosub i2cbusstop ' Stampa il dato letto e conservato nella variabile Valore gosub stampahex gosub nlcr I2CBUSDone: for i = 0 to 20 lookup i,("Operazione Effettuata"), usartout gosub charout next i I2CBUSGotoMenu: gosub nlcr goto I2CBUSMenu NotACK: for i = 0 to 23 lookup i,("Acknowledge non ricevuto"), usartout gosub charout next i goto I2CBUSGotoMenu I2CBUSEsci: goto menu ' ' ' Genera uno start I2C BUS I2CBUSStart: peek sspcon2, B0 bit0 = 1 poke sspcon2, B0 return ' ' ' Genera uno start I2C BUS ripetuto I2CBUSRepStart: peek sspcon2, B0 bit1 = 1 poke sspcon2, B0 return ' ' ' Genera uno stop I2C BUS I2CBUSStop: peek sspcon2, B0 bit2 = 1 poke sspcon2, B0 return ' ' ' Invia il valore contenuto in DatoOut su I2C BUS I2CBUSSend: poke sspbuf, datoout gosub i2cbussynch return ' ' ' Legge un dato da I2C BUS e lo restituisce in DataIn I2CBUSGet: gosub i2cbussynch peek sspcon2, B0 bit3=1 poke sspcon2, B0 I2CBusGetLoop: peek sspcon2, B0 if bit3=1 then I2CBusGetLoop peek sspbuf, datoin return ' ' ' Attende il completamento dell'ultima operazione dell'interfaccia I2C I2CBUSSynch: peek pir1, B0 if bit3 = 0 then I2CBUSSynch bit3 = 0 poke pir1, B0 return ' ' ' Trasforma il valore esadecimle nella variabile Valore in caratteri ' ASCII e li invia alla porta seriale. ' Valore deve essere compreso tra 0 e 0FFh. StampaHex: usartout = valore / 16 gosub hexdecode gosub charout StampaNibbleHex: usartout = valore & $0F gosub hexdecode gosub charout return ' HexDecode: Lookup usartout,("0123456789ABCDEF"),usartout return ' HexEncode: lookDown usartin,("0123456789abcdef"),usartin return ' ' ' Manda a capo su una riga sotto NLCR: usartout = 10 ' New Line gosub charout CR: usartout = 13 ' Carriage Return gosub charout return ' ' ' Stampa due spazi DueSpazi: usartout = " " ' Spazio gosub charout gosub charout return ' ' ' Va a capo, stampa il messaggio "Premere un tasto..." e va a capo TastoPerUscire: gosub nlcr for z = 0 to 18 lookup z, ("Premere un tasto..."),usartout gosub charout next z gosub nlcr return ' ' ' Chiede un valore in esadecimale e lo restituisce in dato InputDato: for z = 0 to 11 lookup z,("Dato (Hex): "), usartout gosub charout next z gosub inputhex dato = valorehex return ' ' ' Chiede indirizzo in esadecimale e lo restituisce in indirizzo InputSlaveAddress: for z = 0 to 20 lookup z,("Slave Address (Hex): "), usartout gosub charout next z gosub inputhex slave_address = valorehex return ' ' ' Chiede indirizzo in esadecimale e lo restituisce in indirizzo InputIndirizzo: for z = 0 to 16 lookup z,("Indirizzo (Hex): "), usartout gosub charout next z gosub inputhex indirizzo = valorehex return ' ' ' Input di un valore esadecimale da 00 a FF poi va a capo InputHex: gosub charin if usartin = 0 then InputHex usartout = usartin gosub charout usartin = usartin | $20 gosub hexencode valorehex = usartin * 16 InputHex2: gosub charin if usartin = 0 then InputHex2 usartout = usartin gosub charout usartin = usartin | $20 gosub hexencode valorehex = valorehex + usartin gosub nlcr return ' ' ' Subroutine che invia un carattere al trasmettitore USART ' (sospensiva) CharOut: Peek pir1,UsartST ' Leggi il Flag in UsartST = B0 If Bit4 = 0 Then charout ' Attendi che si svuoti il registro di ' trasmissione Poke TXREG,Usartout ' Metti il carattere nel registro di ' trasmissine Return ' Ritorno al chiamante ' ' ' Subroutine che preleva un carattere dal ricevitore dell'USART ' (non sospensiva) CharIn: UsartIn = 0 ' Preset a nessun carattere ricevuto Peek PIR1,Usartst ' Leggi il Flag in UsartST = B0 If Bit5 = 0 Then ciret ' Se il flag di ricezione e' 0, esci Peek RCREG,UsartIn ' Altrimenti metti il carattere ricevuto ' in UsartIn = B1 ciret: Return ' Ritorno al chiamante