'****************************************************************** '* Nome : gmbiob.bas * '* Autore : Graziano GAIBA * '* Data : 04/05/04 * '* Versione : 1.1 * '* Scheda : GMM 876 + GMB HR84 * '* 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 * '* : sales@grifo.it tech@grifo.it grifo@grifo.it * '****************************************************************** ' ' Questo Demo permette di utilizzare immediatamente sia le uscite che gli ' ingressi bufferati disponibili rispettivamente su CN1 e CN6 di GMB HR84. ' Tramite la console si puo' visualizzare lo stato degli otto ingressi NPN/PNP ' oppure settare lo stato dei quattro rele' di uscita. ' Inoltre vengono applicate le funzionalita' evolute offerte dal Mini Modulo, ' ad esempio: ingressi contati via hardware, ecc. ' ' 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 symbol ADCON0 = $1F symbol ADCON1 = $9F ' banco 1 ' ' Registri dei Timer e dei CCP symbol TMR0 = $01 symbol TMR1L = $0E symbol TMR1H = $0F symbol T1CON = $10 symbol TMR2 = $11 symbol PR2 = $92 ' banco 1 symbol T2CON = $12 ' symbol CCPR1L = $15 symbol CCPR1H = $16 symbol CCP1CON = $17 symbol CCPR2L = $1B symbol CCPR2H = $1C symbol CCP2CON = $1D ' symbol PIE1 = $8C ' 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 ' Usato dall'input di un valore esadecimale symbol ValoreHex = B7 symbol ValoreHexMSB = B8 ' Usata per inizializzare il Baud Rate Generator symbol ValBRG = B9 ' ' ' ********************************************************************* ' * Programma main * ' ********************************************************************* ' Main: gosub Module_init ' Inizializzazione ' Apre tutti i relays B0 = 0 gosub set_relays for i=0 to 35 lookup i,("Demo per GMM 876 e GMB HR84 Rel. 1.1"),usartout gosub charout next i gosub nlcr gosub nlcr ' Scelta delle possibili operazioni ' 1) Input digitali ' 2) Uscite a relays for i=0 to 110 lookup i,("Esempio di utilizzo degli ingressi su CN6 e delle uscite su CN1",13,10,"1) Input digitali",13,10,"2) Uscite a rele'",13,10,"Scelta: "),usartout gosub charout next i ' Attende un carattere tra "1" e "2" e lo stampa Mainloop: gosub CharIn if usartin < "1" or usartin > "2" then Mainloop i = usartin - "0" - 1 usartout = usartin gosub charout gosub nlcr gosub nlcr branch i,(Demo_in, Demo_out) goto main end ' ' ' ********************************************************************* ' * Fine del programma * ' ********************************************************************* ' ' ' Inizializzazione della GMM 876 Module_init: ' Spengo l'A/D converter poke adcon0, 0 ' Imposta Port A come input digitale poke ADCON1, 7 ' Imposta le linee RB4..RB7 come uscite peek trisb, B0 bit4 = 0 bit5 = 0 bit6 = 0 bit7 = 0 poke trisb, B0 ' Imposta le linee RA0,RA1,RB0,RB1,RA4,RC0,RC1 e RC5 come input peek trisa, B1 bit8 = 1 bit9 = 1 bit12 = 1 poke trisa, B1 ' peek trisc, B1 bit8 = 1 bit9 = 1 bit13 = 1 poke trisc, B1 ' peek trisb, B1 bit8 = 1 bit9 = 1 poke trisb, B1 ' ' Inizializza USART per 19200 Baud W0 = 19200 gosub calcolabrg_hs Poke SPBRG,valbrg ' 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 ' Rimettere la pagina 0 prima di uscire dall'asm 'ASM 'ENDASM pause 500 return ' ' ' Demo di utilizzo degli ingressi optoisolati come ingressi digitali e ' ingressi digitali contati via hardware Demo_in: for i=0 to 66 lookup i,("Viene visualizzato continuamente l'input degli ingressi optoisolati"),usartout gosub charout next i gosub nlcr gosub chieditasto gosub nlcr Demo_in_loop: for i=0 to 6 lookup i,("Input: "),usartout gosub charout next i ' Legge gli ingressi optoisolati gosub get_opto ' Stampa il valore letto in esadecimale valore = B0 gosub stampahex ' Torna a capo gosub cr pause 300 ' Verifica se un tasto e' stato premuto gosub charin ' Se nessun tasto e' stato premuto, ripeti if usartin = 0 then demo_in_loop ' Esci gosub nlcr gosub nlcr ' ' Gli ingressi optoisolati 5 e 6 si possono contare via hardware ' rispettivamente usando Timer 0 e 1. for i = 0 to 56 lookup i,("Conteggio ingressi optoisolati 5 e 6 mediante Timer 0 e 1"), usartout gosub charout next i gosub nlcr gosub chieditasto for i=0 to 9 lookup i,("IN 5 IN 6"),usartout gosub charout next i gosub nlcr ' Azzera i contatori poke tmr0, 0 poke tmr1l, 0 poke tmr1h, 0 ' Configurazione di Timer 0 come counter peek option_reg, B0 bit7 = 0 ' Abilita i pull-up su port B bit5 = 1 ' Conta transizioni sul pin 17 bit4 = 1 ' Conta transizioni da livello alto a basso bit3 = 1 ' Nessun prescaler (assegnato a WDT) poke option_reg, B0 ' Configurazione di Timer 1 come counter peek t1con, B0 bit3 = 0 ' Conta transizioni sul pin 16 bit2 = 1 ' Conteggio asincrono bit1 = 1 ' Conta transizioni da livello basso ad alto di pin 16 bit0 = 1 ' Abilita il Timer 1 poke t1con, B0 Demo_in_CountLoop: gosub duespazi peek tmr0, valore gosub stampahex gosub duespazi peek tmr1h, valore gosub stampahex peek tmr1l, valore gosub stampahex gosub cr pause 300 gosub charin if usartin = 0 then Demo_in_CountLoop ' Ferma Timer 1 peek t1con, B0 bit0 = 0 ' Disabilita il Timer 1 poke t1con, B0 gosub nlcr goto main ' ' ' Demo di utilizzo delle uscite a relays Demo_out: for i = 0 to 25 lookup i,("Dato (Hex), 0 per finire: "), usartout gosub charout next i valorehex = 0 gosub inputhex2 ' Imposta lo stato dei relays con il dato appena immesso B0 = valorehex gosub set_relays if valorehex <> 0 then demo_out goto main ' ' ' Calcola il valore per inizializzare il Baud Rate Generator in modalita' ' ad alta velocita'. ' Il Baud Rate desiderato si trova nella variabile W0, il risultato, ' ovvero il valore da scrivere nel registro SPBRG, si trova nella ' variabile ValBRG. ' Si ricorda che per attivare la modalita' ad alta velocita' bisogna ' porre ad 1 il bit 2 del registro TXSTA (BRGH). CalcolaBRG_HS: ' Fquarzo ' ValBRG = -------- - 1 ' 16 * BR valbrg = 0 if W0 = 9600 then val_9600_hs if W0 = 19200 then val_19200_hs if W0 = 38400 then val_38400_hs if W0 = 57600 then val_57600_hs if W0 = 115200 then val_115200_hs goto esci_hs val_9600_hs: valbrg = 129 goto esci_hs val_19200_hs: valbrg = 64 goto esci_hs val_38400_hs: valbrg = 32 goto esci_hs val_57600_hs: valbrg = 21 goto esci_hs val_115200_hs: valbrg = 10 goto esci_hs esci_hs: return ' ' ' Calcola il valore per inizializzare il Baud Rate Generator in modalita' ' a bassa velocita'. ' Il Baud Rate desiderato si trova nella variabile W0, il risultato, ' ovvero il valore da scrivere nel registro SPBRG, si trova nella ' variabile ValBRG. ' Si ricorda che per attivare la modalita' a bassa velocita' bisogna ' porre a 0 il bit 2 del registro TXSTA (BRGH). CalcolaBRG_LS: ' Fquarzo ' ValBRG = -------- - 1 ' 64 * BR valbrg = 0 if W0 = 1200 then val_1200_ls if W0 = 2400 then val_2400_ls if W0 = 9600 then val_9600_ls if W0 = 19200 then val_19200_ls if W0 = 76800 then val_76800_ls goto esci_hs val_1200_ls: valbrg = 255 goto esci_hs val_2400_ls: valbrg = 129 goto esci_hs val_9600_ls: valbrg = 32 goto esci_hs val_19200_ls: valbrg = 15 goto esci_hs val_76800_ls: valbrg = 3 goto esci_ls esci_ls: return ' ' ' Questa procedura imposta lo stato dei relays di una GMB HR84. ' La corrispondenza tra bit del paramertro, linea di I/O e relay e': ' Bit 0 -> RB4 -> A1 ' Bit 1 -> RB5 -> A2 ' Bit 2 -> RB6 -> B1 ' Bit 3 -> RB7 -> B2 ' Il parametro in ingresso e' la variabile B0, viene distrutto il ' contenuto della variabile B1. ' Per ogni segnale, il rispettivo bit ha il seguente significato: ' bit a 0 -> Relay aperto ' bit a 1 -> Relay chiuso Set_relays: B0 = B0 ^ $0F peek portb, B1 bit12 = bit0 bit13 = bit1 bit14 = bit2 bit15 = bit3 poke portb, B1 return ' ' ' Questa procedura imposta lo stato dei relays di una GMB HR84. ' La corrispondenza tra bit del paramertro, linea di I/O e relay e': ' Bit 0 -> RA0 -> Opto Input 1 ' Bit 1 -> RA1 -> Opto Input 2 ' Bit 2 -> RB0 -> Opto Input 3 ' Bit 3 -> RB1 -> Opto Input 4 ' Bit 4 -> RA4 -> Opto Input 5 ' Bit 5 -> RC0 -> Opto Input 6 ' Bit 6 -> RC1 -> Opto Input 7 ' Bit 7 -> RC5 -> Opto Input 8 ' Il parametro in ingresso e' la variabile B0, viene distrutto il ' contenuto della variabile B1. ' Per ogni segnale, il rispettivo bit ha il seguente significato: ' bit a 0 -> Relay aperto ' bit a 1 -> Relay chiuso Get_opto: peek porta, B1 bit0 = bit8 bit1 = bit9 bit4 = bit12 ' peek portb, B1 bit2 = bit8 bit3 = bit9 ' peek portc, B1 bit5 = bit8 bit6 = bit9 bit7 = bit13 B0 = B0 ^ $FF return ' ' ' Stampa due spazi DueSpazi: usartout = " " ' Spazio gosub charout gosub charout 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 ' ' ' Input di un valore esadecimale da 000 a FFF poi va a capo InputHex3: gosub charin if usartin = 0 then InputHex3 usartout = usartin gosub charout usartin = usartin | $20 gosub hexencode valorehexMSB = usartin 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 ' ' ' Attende un carattere dalla porta seriale ChiediTasto: for i = 0 to 33 lookup i,("Premere un tasto per continuare..."),usartout gosub charout next i gosub NLCR return AttendiTasto: gosub charin if usartin = 0 then AttendiTasto 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