' ********************************************************************** ' * File: gmbiob.bas - Rel. 1.1 con Bascom AVR IDE e LIB 1.11.7.4 * ' * Schede: GMB HR84 + GMM AM08 * ' * * ' * 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 * ' * sales@grifo.it tech@grifo.it grifo@grifo.it * ' * by Graziano Gaiba del 13.01.04 * ' ********************************************************************** ' ' Questo Demo permette di utilizzare immediatamente sia le uscite che gli ' ingressi bufferati disponibili rispettivamente su CN1 e CN6. ' 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 che generano interrupt, ingressi contati via hardware, ' uscite comandate da segnali periodici automatici, ecc. ' ' 13.01.04 - Rel 1.1 By Graziano Gaiba per GMM AM08 ' ' Il file compilato non supera i 2048 bytes, quindi puo' essere ' compilato con il demo gratuito di BASCOM AVR. ' ' ' !!!!!!!!!!!!!!!!!!!!!!!!!!! IMPORTANTE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ' Nel menu Options | Compiler | Chip, impostare: ' ' Chip: M8 ' HW Stack: almeno 64 ' Soft Stack: almeno 32 ' Framesize: almeno 64 ' ' '****************** Direttive del compilatore ************************** ' $regfile = "m8def.dat" $crystal = 7372800 $baud = 19200 On Int0 Risp_int0 Nosave On Int1 Risp_int1 Nosave On Timer0 Risp_int_t0 Nosave ' '****************** Dichiarazione delle costanti *********************** ' Const Cret = 13 ' Codice di ritorno di carrello Const Nl = 10 ' Codice nuova linea Const Clrscr = 12 ' codice di clear screen Const Bell = 7 ' codice di Bell ' '****************** Dichiarazione delle variabili ********************** ' ' Uso generico Dim V As Byte , S As Byte , T As Byte ' Byte di uso generico ' Contatore interrupts Dim Cntintr1 As Byte , Cntintr2 As Byte , Cntintt0 As Byte ' '****************** Dichiarazione delle procedure ********************** ' Declare Sub Init() ' Inizializzazione Declare Function Get_inputs() As Byte ' Legge ingressi optoisolati Declare Sub Set_outputs(byval Relays_out As Byte) ' Imposta uscite a rele' Declare Sub Richiedi_tasto() Declare Function Leggi_attesa() As Byte ' '************************* Programma main ****************************** ' Main: Call Init() ' Inzializza il modulo Do Call Set_outputs(0) Print Chr(clrscr); ' Pulisce lo schermo Print "Demo 1.1 per GMB HR84 ds 220503" Print Do Print "Esempio di utilizzo degli ingressi su CN6 e delle uscite su CN1" Print Print "1) Input digitali" Print "2) Uscite a rele'" Print Print "SELEZIONE: "; Do V = Inkey() Loop Until V <> 0 Print Chr(v) If V = "1" Then Print "Ingressi optoisolati su CN6" Do Call Richiedi_tasto() Do T = Get_inputs() Print Hex(t); Printbin Cret S = Leggi_attesa() Loop Until S <> 0 Print Print Print "IN3 e' anche trigger di int0, IN4 di int1." Print "Una transizione H-L attiva l'interrupt che incrementa il relativo contatore." Call Richiedi_tasto() Print "INT0 INT1" Mcucr.0 = 0 ' Int0 scatta sul fronte calante Mcucr.1 = 1 Mcucr.2 = 0 ' Int1 scatta sul fronte calante Mcucr.3 = 1 Enable Int0 ' Abilita int0 Enable Int1 ' Abilita int1 Enable Interrupts ' Abilita gli interrupts Cntintr1 = 0 ' Azzera contatori interrupts Cntintr2 = 0 Do Print Hex(cntintr1) ; " " ; Hex(cntintr2) ; 'Stampa contatori interrupts Printbin Cret ' Torna a inizio riga S = Leggi_attesa() Loop Until S <> 0 ' Esce alla pressione di un tasto Disable Interrupts ' Disabilita interrupts Disable Int0 ' Disabilita int0 Disable Int1 ' Disabilita int1 Loop Until S <> 0 Print Print Print "T0 e' configurato come contatore,IN5 e' il suo trigger" Print "Ogni overflow genera un interrupt" Call Richiedi_tasto() Cntintt0 = 0 ' Bisogna SEMPRE fermare i timer prima di riconfigurarli Stop Timer0 ' Configura Timer 0 come counter sulle transizione H->L del pin T0. Config Timer0 = Counter , Edge = Falling Counter0 = &HD0 ' Valore iniziale Enable Timer0 ' Abilita interrupt overflow timer 0 Enable Interrupts ' Abilita gli interrupt Start Timer0 Print "T0 N.INT" Do Print Hex(counter0) ; " " ; Hex(cntintt0); 'Stampa contatore ' Leggere counter0 ferma automaticamente timer0, bisogna riattivarlo Start Timer0 Printbin Cret ' Torna a inizio riga S = Leggi_attesa() Loop Until S <> 0 ' Esce alla pressione di un tasto Disable Interrupts Disable Timer0 Stop Timer0 End If If V = "2" Then Print Chr(clrscr); Print "Demo uscite rele'" Print Do Print "Digitare cifra hex (0 esce): "; Do S = Inkey() If S.6 = 1 Then S.5 = 0 ' Converte eventuale lettera in maiuscolo S = S - 48 ' Valore numerico If S > 9 Then S = S - 7 ' Aggiusta valore numerico Loop Until S >= 0 And S <= 15 Print Hex(s) Call Set_outputs(s) ' Imposta le uscite Loop Until S = 0 Print Print "I segnali collegati alle uscite di CN1 possono svolgere funzioni evolute" Print "come temporizzatori, PWM, ecc." Print "L'uscita A2 si attiva con una frequenza di circa 1 Hz e duty cicle del 50%." Call Richiedi_tasto() ' ATTENZIONE ' Prima di modificare la configurazione di un Timer, va SEMPRE fermato Tccr1b = 0 ' Ferma il Timer 1 Ddrb.2 = 1 ' Imposta portb.2 come uscita ' Per scrivere nei registri a 16 bit del Timer 1, bisonga prima scrivere il ' byte alto e poi il byte basso. ' Per leggere nei registri a 16 bit del Timer 1, bisonga prima leggere il ' byte alto e poi il byte basso. ' Inoltre l'operazione deve essere atomica, ovvero niente deve interromperla Ocr1ah = &H1C ' Durata periodo Ocr1al = &H71 Ocr1bh = &H0E ' Duty cycle 50% Ocr1bl = &H38 ' Valore iniziale del Timer Tcnt1h = 0 Tcnt1l = 0 ' Modalita' Fast PWM a 10 bit, Prescaler a clock / 1024, complementa ' pin 22 dello zoccolo ad ogni corrispondenza tra i registri OCR1B e ' contatore del timer, attiva il Timer 1. Tccr1a = &H33 Tccr1b = &H1D ' Attesa sospensiva di un tasto S = Waitkey() Tccr1b = 0 ' Ferma il Timer 1 Tccr1a = 0 ' Disbilita PWM Portb.2 = 1 ' Apre l'uscita A2 End If Loop Loop Risp_int0: Incr Cntintr1 ' Incrementa contatore interrupt Return Risp_int1: Incr Cntintr2 ' Incrementa contatore interrupt Return Risp_int_t0: Incr Cntintt0 ' Incrementa contatore interrupt Return End ' '************************ Fine del programma *************************** ' ' '**************************** Procedure ******************************** ' ' ' ' Legge gli ingressi optoisolati. ' Function Get_inputs() As Byte Local Temp As Byte , Temp1 As Byte ' Opto_in.0 <-- PC.0 = IN1 ' Opto_in.1 <-- PC.1 = IN2 ' Opto_in.2 <-- PD.2 = IN3 ' Opto_in.3 <-- PD.3 = IN4 ' Opto_in.4 <-- PD.4 = IN5 ' Opto_in.5 <-- PD.5 = IN6 ' Opto_in.6 <-- PC.2 = IN7 ' Opto_in.7 <-- PC.3 = IN8 '( Get_inputs = Pinc And &H03 Temp = Pind And &H3C Get_inputs = Get_inputs Or Temp Get_inputs = Pinc.2 Get_inputs = Pinc.3 ') Temp = Pinc And &H03 Temp1 = Pind And &H3C Temp1.6 = Pinc.2 Temp1.7 = Pinc.3 Get_inputs = Temp Or Temp1 End Function ' ' ' Imposta uscite a rele' ' Sub Set_outputs(byval Relays_out As Byte) Local Temp As Byte Relays_out = Not Relays_out Portb.0 = Relays_out.0 ' Il bit 0 e' il pin 1 di CN1 Portb.2 = Relays_out.1 ' Il bit 1 e' il pin 3 di CN1 Temp = Portd And &H3F Temp.6 = Relays_out.2 ' Il bit 2 e' il pin 4 di CN1 Temp.7 = Relays_out.3 ' Il bit 3 e' il pin 5 di CN1 Portd = Temp End Sub ' ' ' Inizializza il demo ' Sub Init() Ddrc = Ddrc And &HF0 ' Imposta PC0..3 in input Ddrd = Ddrd And &HC3 ' Imposta PD2..5 in input Ddrd = Ddrd Or &HC0 ' Imposta PD6..7 in output Ddrb = Ddrb Or &H05 ' Imposta PB0 e 2 in output End Sub ' ' ' Stampa il messaggio "Premere tasto per uscire" ' Sub Richiedi_tasto() Print Print "Premere tasto per uscire" Print End Sub ' ' ' Attende 200 msec poi legge un tasto e lo restituisce ' Function Leggi_attesa() Waitms 200 Leggi_attesa = Inkey() End Function