' **************************************************************** ' * File: gmbad.bas - Ver. 1.1 * ' * Compilatore: PIC Basic PRO * ' * IDE: MicroCode Studio Plus * ' * Versione Compilatore: 2.45 * ' * Schede: GMM 4620 + GMB HR168 + K51-AVR * ' * GRIFO(R) via Dell'Artigiano 8/6 * ' * 40016 S. Giorgio di Piano (BO) * ' * Tel. +39 051 892052 Fax. +39 051 893661 * ' * http://www.grifo.com http://www.grifo.it * ' * by Graziano Gaiba 10.02.05 * ' **************************************************************** ' ' Questo demo offre due operativita' per la linea di ingresso analogico su CN7: ' calibrazione o acquisizione. ' La prima calcola un coefficiente di calibrazione grazie ad un segnale di ' riferimento esterno fornito dall'utente, e lo salva nella EEPROM interna del ' Mini Modulo. ' La seconda preleva il coefficiente di calibrazione dalla EEPROM, acquisice e ' rappresenta di continuo sulla console la combinazione dell'ingresso analogico, ' sia calibrato che non calibrato. Il demo puo' essere usato indifferentemente ' con range 0..2,5 V e 0..10 V. ' ' Rel 1.1 - by Graziano Gaiba ' Demo per effettuare conversioni A/D calibrate usando una GMB HR168 ' pilotata da un Mini Modulo GMM 4620 ' ' ' ***************** Definizioni del compilatore ****************** ' DEFINE OSC 10 ' Frequenza oscillatore 9,8304 MHz DEFINE HSER_RCSTA 90h ' Abilita EUSART in ricezione DEFINE HSER_TXSTA 20h ' Abilita EUSART in trasmissione DEFINE HSER_BAUD 19200 ' Baud Rate ' ' *************** Dichiarazione delle contanti ******************* ' RTCSLA con $A0 I2C_BUFFER_SIZE con 10 ' ' ******************* Dichiarazione delle Variabili ******************** ' ' Variabili di uso generico i var byte scelta var byte di var byte do var byte ' ' ' Usate per la calibrazione della conversione A/D Quant_err var word Vref_mV var word Vref_cmb var word sum_cmb var word KCal var word ' ' Usata dalle procedure di gestione I/O port_val var byte ' Valore letto o da scrivere nell'I/O ' ' Usate per la conversione A/D ad_channel var byte ad_result var word ' ' '********************** Programma principale *************************** ' main: gosub Init_cpu ' Spegne i relays port_val = 0 gosub set_relays for_ever: gosub clrscr hserout ["Demo ingresso analogico Rel 1.1 for GMM 4620 rel 120304 e GMB HR168 rel 110104", 13, 10, 13, 10] hserout ["L'ingresso analogico e' il pin 8 di CN7.", 13, 10] hserout ["A seconda di J11 il range di input puo' essere da 0 a 5 V o da 0 a 20 V.", 13, 10] hserout ["La sezione analogic di GMB HR168 e` basata su componenti di precisione", 13, 10] hserout ["comunque soggetti a piccole tolleranze.", 13, 10] hserout ["Per compensarle e` preferibile acquisire l'ingresso analogico tramite", 13, 10] hserout ["calibrazione software.", 13, 10] hserout ["Il coefficiente di calibrazione viene memorizzato nelle ultime 8 locazioni", 13, 10] hserout ["della EEPROM interna della CPU, che sono riservate.", 13, 10, 13, 10] hserout ["Selezione modo: Acquisizione o Calibrazione (a/c): "] hserin [i] hserout [i, 13, 10] adcon1 = 0 adcon2 = $88 ' Abilita A/D converter adcon0.0 = 1 if i == "c" or i == "C" then hserout ["Collegare J11 in 2-3.", 13, 10] hserout ["Collegare segnale di riferimento vicino al fondo scala (20 V) a pin 8 di CN7.", 13, 10] Vref_input: hserout ["Inserire il valore del segnale di riferimento, in mV (19000-20000): "] hserin [dec5 vref_mv] hserout [dec5 vref_mv, 13, 10] if vref_mv < 16000 then hserout ["Il segnale di riferimento deve essere superiore a 16000 mV.", 13, 10] goto Vref_input endif ' Procedura di calibrazione. ' Primo: calcolare la combinazione del segnale di riferimento. ' Si faccia riferimento al manuale Pic Basic Pro per ulteriori info ' sul funzionamento di una catena moltiplicazione 16bit x 16bit e ' istruzione DIV32. ' Qui KCal agisce come una variabile fittizia. kcal = vref_mv * 1023 if vref_mv > 5000 then vref_cmb = div32 20000 else vref_cmb = div32 5000 endif ' Secondo: effettuare 64 misure del segnale di riferimento e calcolarne ' la media. sum_cmb = 0 for i = 0 to 64 ad_channel = 4 gosub ad_conversion sum_cmb = sum_cmb + ad_result next i ' Ultimo: calcolare il coefficiente di calibrazione usando la media ' delle 64 misure e la combinazione teorica del segnale di riferimento sum_cmb = sum_cmb >> 6 kcal = vref_cmb - sum_cmb ' Memorizza il coefficiente di calibrazione nelle locazione 03f8H e ' 03f9H della EEPROM interna. write kcal.highbyte, $3f8 write kcal.lowbyte, $3f9 hserout ["Calibrazione completata.", 13, 10, 13, 10] endif ' ' Acquisizione ' Lettura del coefficiente di calibrazione dalla EEPROM interna. read $3f8, kcal.highbyte read $3f9, kcal.lowbyte quant_err = 1023 / kcal hserout ["Combinazione NON calibrata e calibrata vengono mostrate continuamente.", 13 ,10] hserout ["Premere un tasto per uscire...", 13, 10, 13, 10] hserout ["NON calibrata Calibrata", 13, 10] ' Ciclo visualizzazione vis_loop: ad_channel = 4 gosub ad_conversion hserout [" ", hex4 ad_result] ad_result = ad_result - (ad_result / quant_err) hserout [" ", hex4 ad_result, 13] hserin 200, vis_loop, [i] goto for_ever end ' ' ******************* Definizione delle procedure ********************* ' ' ' Inizializzazione direzione segnali della CPU Init_cpu: ADCON1=$0f ' Imposta come I/O digitale i pin AN0..12 CMCON=$07 ' Imposta come I/O digitale RA0..4 ' Gli ingressi optoisolati di CN1 sono: ' IN1-1 <-> RA0 ' IN2-1 <-> RA1 ' IN3-1 <-> RB0 ' IN4-1 <-> RB1 ' IN5-1 <-> RA4 ' IN6-1 <-> RC0 ' IN7-1 <-> RC1 ' IN8-1 <-> RC5 trisa.0 = 1 trisa.1 = 1 trisa.4 = 1 trisb.0 = 1 trisb.1 = 1 trisc.0 = 1 trisc.1 = 1 trisc.5 = 1 ' Gli ingressi optoisolati di CN2 sono: ' IN1-2 <-> RD0 ' IN2-2 <-> RD1 ' IN3-2 <-> RD2 ' IN4-2 <-> RD3 ' IN5-2 <-> RD4 ' IN6-2 <-> RD5 ' IN7-2 <-> RD6 ' IN8-2 <-> RD7 trisd = $ff ' Le uscite relays di CN3 sono: ' OUT A1 <-> RB4 ' OUT A2 <-> RB5 ' OUT B1 <-> RB6 ' OUT B2 <-> RB7 ' OUT C1 <-> RB3 ' OUT C2 <-> RB2 trisb = trisb & $03 ' Le uscite relays di CN4 sono: ' OUT D1 <-> RA3 ' OUT D2 <-> RC2 (J10 in posizione 3-4) trisa.3 = 0 trisc.2 = 0 return ' ' ' Pulisce lo schermo, inviando 25 volte CR + LF. clrscr: for i= 0 to 24 hserout [13, 10] next i return ' ' ' Chiede la pressione di un tasto chiede_tasto: hserout ["Premere un tasto..."] chiede_tasto_loop: hserin 1, chiede_tasto_loop, [i] return ' ' Conversione del canale A/D memorizzato nella variabile ad_channel. ' Il risultato viene memorizzato nella variabile ad_result. ' Prima di chiamare questa procedura, la periferica A/D converter ' deve essere configurata ed abilitata. AD_Conversion: adcon0.2 = ad_channel.0 adcon0.3 = ad_channel.1 adcon0.4 = ad_channel.2 adcon0.5 = ad_channel.3 adcon0.1 = 1 ad_polling: if adcon0.1 = 1 then ad_polling ad_result.lowbyte = adresl ad_result.highbyte = adresh return ' Procedura per impostare lo stato dei relays sui connettori CN3 e CN4. ' A seconda del valore dei bits di port_val, ogni relay viene attivato ' (contatto chiuso) o disattivato (contatto aperto). ' I bit di port_val hanno il seguente significato: ' -- CN3 ' port_val.0 pilota il relay OUT A1 ' port_val.1 pilota il relay OUT A2 ' port_val.2 pilota il relay OUT B1 ' port_val.3 pilota il relay OUT B2 ' port_val.4 pilota il relay OUT C1 ' port_val.5 pilota il relay OUT C2 ' -- CN4 ' port_val.6 pilota il relay OUT D1 ' port_val.7 pilota il relay OUT D2 ' ' Ogni bit ha il seguente significato: ' bit Significato ' 0 Relay disattivato (contatto aperto) ' 1 Relay attivato (contatto chiuso) set_relays: ' I relays sono pilotati in logica complementata , quindi anche port_val ' deve essere complementato port_val = port_val ^ $ff portb.4 = port_val.0 portb.5 = port_val.1 portb.6 = port_val.2 portb.7 = port_val.3 portb.3 = port_val.4 portb.2 = port_val.5 porta.3 = port_val.6 portc.2 = port_val.7 return