' **************************************************************** ' * File: gmbiob.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 11.02.05 * ' **************************************************************** ' ' Questo Demo permette di utilizzare immediatamente sia le uscite che gli ' ingressi bufferati disponibili rispettivamente su CN3, CN4 ' e CN1, CN2 di GMB HR168. ' Tramite la console si puo' visualizzare lo stato dei sedici ingressi NPN/PNP ' oppure settare lo stato degli otto relays di uscita. ' Inoltre vengono applicate le funzionalita' evolute offerte dal Mini Modulo, ' ad esempio: ingressi contati via hardware, ecc. ' ' ' Rel 1.1 - by Graziano Gaiba ' Demo di utilizzo delle periferiche bufferate di I/O 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 ' ' Usata dalle procedure di gestione I/O port_val var byte ' Valore letto o da scrivere nell'I/O ' ' ' Usate dagli interrupts cnt_int0 var byte cnt_int1 var byte ' ' ' Usate per gestire i Timer 0 e 1 val_tmr0 var word val_tmr1 var word cnt_tmr1_int var byte ' ' '********************** Programma principale *************************** ' main: gosub Init_cpu ' Spegne i relays port_val = 0 gosub set_relays for_ever: gosub clrscr hserout ["Demo I/O bufferato Rel 1.1 per GMM 4620 rel 120304 ed GMB HR168 rel 110104", 13, 10, 13, 10] hserout ["1) Ingressi digitali", 13, 10] hserout ["2) Uscite relays", 13, 10] hserout [13, 10, "Scelta: "] input_scelta: hserin [dec1 scelta] if scelta < 1 and scelta > 2 then input_scelta hserout [dec1 scelta, 13, 10] if scelta = 1 then gosub digital_inputs if scelta = 2 then gosub relay_outputs goto for_ever end ' ' **************** Procedures definition ****************** ' ' ' 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 ' ' ' 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 ' ' ' Procedura che legge lo stato degli ingressi optoisolati del connettore CN1. ' I bit di port_val hanno il seguente significato: ' port_val.0 indica lo stato di IN1-1 ' port_val.1 indica lo stato di IN2-1 ' port_val.2 indica lo stato di IN3-1 ' port_val.3 indica lo stato di IN4-1 ' port_val.4 indica lo stato di IN5-1 ' port_val.5 indica lo stato di IN6-1 ' port_val.6 indica lo stato di IN7-1 ' port_val.7 indica lo stato di IN8-1 ' ' A seconda del valore dei bits di port_val, ogni input viene indicato come. ' aperto o chiuso. Ogni bit ha il seguente significato: ' bit Significato ' 0 Contatto aperto ' 1 Contatto chiuso get_opto_1: port_val.0 = porta.0 port_val.1 = porta.1 port_val.2 = portb.0 port_val.3 = portb.1 port_val.4 = porta.4 port_val.5 = portc.0 port_val.6 = portc.1 port_val.7 = portc.5 ' Gli ingressi optoisolati sono pilotati in logica complementata, ' quindi anche port_val deve essere complementato port_val = port_val ^ $ff return ' ' ' Procedura che legge lo stato degli ingressi optoisolati del connettore CN2. ' I bit di port_val hanno il seguente significato: ' port_val.0 indica lo stato di IN1-2 ' port_val.1 indica lo stato di IN2-2 ' port_val.2 indica lo stato di IN3-2 ' port_val.3 indica lo stato di IN4-2 ' port_val.4 indica lo stato di IN5-2 ' port_val.5 indica lo stato di IN6-2 ' port_val.6 indica lo stato di IN7-2 ' port_val.7 indica lo stato di IN8-2 ' ' A seconda del valore dei bits di port_val, ogni input viene indicato come. ' aperto o chiuso. Ogni bit ha il seguente significato: ' bit Significato ' 0 Contatto aperto ' 1 Contatto chiuso get_opto_2: port_val = portd ' Gli ingressi optoisolati sono pilotati in logica complementata, ' quindi anche port_val deve essere complementato port_val = port_val ^ $ff return ' ' ' Demo degli ingressi digitali optoisolati digital_inputs: gosub clrscr hserout ["Demo sezione ingressi optoisolati", 13, 10, 13, 10] hserout ["Viene visualizzato continuamente lo stato degli ingressi di CN1 e CN2.", 13, 10] hserout ["Premere un tasto per uscire.", 13, 10, 13, 10] hserout ["CN1 CN2", 13, 10] digital_inputs_loop: gosub get_opto_1 hserout [" ", hex2 port_val] gosub get_opto_2 hserout [" ", hex2 port_val, 13] pause 200 hserin 1, digital_inputs_loop, [i] hserout [13, 10, 13, 10] ' ' hserout ["IN3 e IN4 di CN1 sono collegati rispettivamente agli interrupt INT0 e INT1.", 13, 10] hserout ["Ogni fronte calante sugli ingressi attiva il rispettivo interrupt, che", 13, 10] hserout ["incrementa un contatore. I contatori sono visualizzati continuamente.", 13, 10] hserout ["Premere un tasto per uscire.", 13, 10, 13, 10] hserout ["Conteggio di: INT0 INT1", 13, 10] on interrupt goto Interrupts_manager ' Disabilita priorita' degli interrupts rcon.7 = 0 ' Attiva INT0 e INT1 sui fronti calanti intcon2.6 = 0 intcon2.5 = 0 ' Abilita INT0 e INT1 intcon.4 = 1 intcon3.3 = 1 ' Abilitazione interrupt periferiche e globale intcon.6 = 1 intcon.7 = 1 ' Inizializza contatori interrupts cnt_int0 = 0 cnt_int1 = 0 enable interrupts_loop: hserout [" ", hex2 cnt_int0, " ", hex2 cnt_int1, 13] pause 50 hserin 1, interrupts_loop, [i] disable ' Disabilitazione interrupt periferiche e globale intcon.7 = 0 intcon.6 = 0 ' Disabilita INT0 e INT1 intcon3.3 = 0 intcon.4 = 0 hserout [13, 10, 13, 10] ' ' hserout ["IN5 e IN6 di CN1 sono collegati rispettivamente al clock esterno di", 13, 10] hserout ["Timer 0 e Timer 1.", 13, 10] hserout ["Ogni fronte calante per Timer 0 e fronte crescente per Timer 1 attivano", 13, 10] hserout ["la periferica che incrementa il ripsettivo registro di contatore hardware.", 13, 10] hserout ["Inoltre, gli overflow di Timer 1 generano un interrupt che viene contato.", 13, 10] hserout ["Tutti i contatori sono visualizzati continuamente.", 13, 10] hserout ["Premere un tasto per uscire.", 13, 10, 13, 10] hserout ["Valore di: Timer 0 Timer 1 Conteggio di: Timer 1 overflow interrupt", 13, 10] ' Inizializza contatori tmr0h = 0 tmr0l = 0 tmr1h = $ff tmr1l = $f0 ' Inizializza contatore interrupt di Timer 1 cnt_tmr1_int = 0 on interrupt goto Timer_int_manager ' Configura Timer 0 a 16 bit, trigger fronti calanti di T0CKI, no prescaler t0con = $b8 ' Configura Timer 1 per trigger fronti calanti di T13CKI, no prescaler t1con = $83 ' Disabilita priorita' degli interrupts rcon.7 = 0 ' Abilita interrupt su overflow di Timer 1 pie1.0 = 1 ' Peripheral interrupts enable and global interrupts enable intcon.6 = 1 intcon.7 = 1 enable timer_loop: val_tmr0.lowbyte = tmr0l val_tmr0.highbyte = tmr0h val_tmr1.lowbyte = tmr1l val_tmr1.highbyte = tmr1h hserout [" ", hex4 val_tmr0, " ", hex4 val_tmr1] hserout [" ", hex2 cnt_tmr1_int, 13] pause 50 hserin 1, timer_loop, [i] disable ' Disabilitazione interrupt periferiche e globale intcon.7 = 0 intcon.6 = 0 ' Disabilita interrupt su overflow di Timer 1 pie1.0 = 0 return ' ' ' Gestore interrupts Interrupts_manager: if intcon.1 = 1 then intcon.1 = 0 cnt_int0 = cnt_int0 + 1 endif if intcon3.0 = 1 then intcon3.0 = 0 cnt_int1 = cnt_int1 + 1 endif resume ' ' ' Gestore interrupts del Timer Timer_int_manager: if pir1.0 = 1 then pir1.0 = 0 cnt_tmr1_int = cnt_tmr1_int + 1 endif resume ' ' ' Demo gestione uscite a relay relay_outputs: gosub clrscr hserout ["Demo gestione uscite a relay", 13, 10, 13, 10] repeat hserout ["Inserire due cifre MAIUSCOLE esadecimali per stato relays (00 esce): "] hserin [hex2 do] hserout [hex2 do, 13, 10] port_val = do gosub set_relays until do == 0 return