' ********************************************************************** ' * File gmbiob.bas - Rel. 1.1 con Bascom 8051 DEMO IDE e LIB 2.0.11.0 * ' * Scheda: GMM 936 + GMB HR84 * ' * 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 del 01.06.05 * ' ********************************************************************** ' ' ' 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. ' ' 01.06.05 - Rel 1.1 By Graziano Gaiba ' ' '********************** Direttive del compilatore ****************************** 'N.B. Nella finestra Options | Compiler | Misc effettuare i seguenti ' settaggi: Register File = 89LPC936.DAT ' Byte End(Hex) = A0 ' Size warining = 7167 $regfile "89lpc936.dat" $romstart = &H0 ' Ind. inizio codice in FLASH $ramstart = &H0 ' Ind. inizio area dati in XRAM $ramsize = &H200 ' Dimensioni area dati in XRAM $crystal = 11059200 ' Massima Fclock della scheda $baud = 19200 ' Velocità comunicazione seriale $large ' Dimensione codice > 2K $map ' Genera info per debug ' per ogni linea di codice On Int1 Risp_int1 Nosave On Timer1 Risp_int_t1 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 Const Rcint = 7372800 ' Frequenza clock da RC interno Const Qz11m = 11059200 ' Frequenza clock da quarzo esterno ' '****************** Dichiarazione delle variabili ********************** ' ' Variabili ad uso generico Dim I As Byte , V As Byte , S As Byte , T As Byte ' Byte di uso generico Dim Hlpb As Byte , M As Byte ' Byte ad uso generico Dim Hlpw As Word , Ind As Word ' Word ad uso generico Dim Hlpl As Long ' Long ad uso generico ' Variabili per gestione comunicazione seriale, clock e ritardi Dim St As Byte Dim Br As Long ' Buad Rate seriale Dim Cclk As Long ' Frequenza clock della CPU Dim R As Word , Rit1ms As Word , Rit As Word ' Gestione ritardi ' Variabili per gestione Port di I/O digitale Dim M1 As Byte , M2 As Byte ' Contatore interrupts Dim Cntintr As Byte , Cntintt1 As Byte ' '****************** Dichiarazione delle procedure ********************** ' Declare Sub Get_clk ' Acquisizione frequenza clock Declare Sub Init ' Inizializzazione generale Declare Sub Ritardo(rit As Word) ' Effettua ritardo calibrato Declare Sub Iniser(br As Long , St As Byte) ' Inizializzazione seriale Declare Sub Check ' Verifica periferiche Declare Sub Mostra_run ' Visualizza partenza programma ' Declare Sub Set_out(v As Byte) ' Imposta lo stato dei rele' Declare Sub Get_inputs() ' Legge gli input optoisolati ' ' '************************* Programma main ****************************** ' Main: Call Init Call Get_clk ' Preleva frequenza della CPU Call Iniser(19200 , 1) ' Inizializza seriale x console ' ' ' Effettua un ritardo di circa 2 secondi in modo da assicurare la ' partenza del programma di emulazione terminale per console (es. ' HYPERTERMINAL) e contemporaneamente fa` lampeggiare il LED di ' attivita` DL1 della scheda. ' Usa la variabile generale i P0m1 = P0m1 Or &H40 ' Setta P0.6 in modo 3=OpenDrain P0m2 = P0m2 Or &H40 For I = 1 To 16 ' 16 cicli da 125 msec = 2 sec P0.6 = Not P0.6 ' Complementa LED attivita` Call Ritardo(125) ' Ritardo di circa 125 msec Next I Print Print "Demo 1.1 per GMM936 ds300803+GMBHR84 ds220503" Call Check ' Controllo interno Print Print "I/O bufferati" Do Print Print Print "1) Input su CN6" Print "2) Uscite su CN1" Print Print "Scelta:"; V = Waitkey() Print Chr(v) Print "Premere tasto per uscire" If V = "1" Then Print Do Do Call Get_inputs() Printhex "IN1..8: " ; S ; Printbin Cret; S = Inkey Loop Until S <> 0 Print Print Print "IN4 di CN6 e' anche trigger di int1." Print "Una transizione H-L attiva interrupt che ne incrementa il contatore." Print Print "INT1" Tcon.2 = 1 ' Int1 scatta sul fronte calante Enable Int1 ' Abilita int1 Enable Interrupts ' Abilita gli interrupts Cntintr = 0 ' Azzera contatore interrupts Do Printhex " " ; Cntintr ; Chr(cret); 'Stampa contatore interrupts S = Inkey Loop Until S <> 0 ' Esce alla pressione di un tasto Disable Interrupts ' Disabilita interrupts Disable Int1 ' Disabilita int1 Loop Until S <> 0 Print Print Print "T1 e' contatore,IN8 il suo trigger." Print "Ogni overflow genera un interrupt." Cntintt1 = 0 ' Bisogna SEMPRE fermare i timer prima di riconfigurarli Stop Timer1 ' Configura timer 1 come timer a 8 bit, trigger il pin T1, ' con autoreload P0m1 = P0m1 Or &H80 ' Configura P0.7 (T1) in modo P0m2 = P0m2 And &H7F ' input only Tcon.6 = 0 ' Ferma Timer Counter 1 Tl1 = &H00 ' Azzera valore attuale Th1 = &H00 Tamod = Tamod And &HEF ' Setta Timer Counter 1 in modo Tmod = Tmod And &H0F ' 2,gate da TR1, come Counter Tmod = Tmod Or &H60 Tl1 = &HF0 ' Valore iniziale Th1 = &HE1 ' Valore di autoreload Enable Timer1 ' Abilita interrupt overflow timer 1 Enable Interrupts ' Abilita gli interrupt Tcon.6 = 1 ' Attiva Timer Counter 1 Print "T1 N.INT" Do S = Counter1 Printhex S ; " " ; Cntintt1; 'Stampa contatore ' Leggere counter0 ferma automaticamente timer0, bisogna riattivarlo Start Timer1 Printbin Cret ' Torna a inizio riga S = Inkey Loop Until S <> 0 ' Esce alla pressione di un tasto Disable Interrupts Disable Timer1 Stop Timer1 End If If V = "2" Then Print Do Print "Digitare una 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 Printhex S Call Set_out(s) ' Imposta le uscite Loop Until S = 0 End If Loop ' '*************** Procedure di risposta agli interrupts ***************** ' Risp_int1: Incr Cntintr ' Incrementa contatore interrupt Return Risp_int_t1: Incr Cntintt1 ' Incrementa contatore interrupt Return End ' '************************ Fine del programma *************************** ' ' '**************************** Procedure ******************************** ' ' '*********************** Procedure gestione Port I/O *************************** ' ' ' ' P2.2, P2.3 e P2.4 sono disponibili per l'utente ' ' Legge gli ingressi optoisolati e restituisce il valore in S. ' Si tenga presente che gli ingressi funzionano in logica negata. ' IN1 <- P0.0 ' IN2 <- P0.1 ' IN3 <- P0.2 ' IN4 <- P1.4 ' IN5 <- P0.3 ' IN6 <- P0.4 ' IN7 <- P0.5 ' IN8 <- P0.7 Sub Get_inputs() S = P0 S.3 = P1.4 S.4 = P0.3 S.5 = P0.4 S.6 = P0.5 End Sub ' ' ' Imposta le uscite a rele' ' Valogono i primi quattro bit del parametro ' Se il Bit e' 1 il corrispondente rele' viene chiuso, altrimenti viene aperto ' OUT A1 -> P1.6 ' OUT A2 -> P1.7 ' OUT B1 -> P2.1 ' OUT B2 -> P2.7 Sub Set_out(v As Byte) P1.6 = Not V.0 P1.7 = Not V.1 P2.1 = Not V.2 P2.7 = Not V.3 End Sub ' ' ' Inizializza risorse, variabili e periferiche in modo da poter eseguire ' correttamente tutto il programma demo. Sub Init Disable Interrupts ' Disabilita gli interrupts P1m1 = 0 ' Necessario per la seriale RS232 ' IN1 <- P0.0 ' IN2 <- P0.1 ' IN3 <- P0.2 ' IN4 <- P1.4 ' IN5 <- P0.3 ' IN6 <- P0.4 ' IN7 <- P0.5 ' IN8 <- P0.7 ' ' OUT A1 -> P1.6 ' OUT A2 -> P1.7 ' OUT B1 -> P2.1 ' OUT B2 -> P2.7 Pt0ad = 0 ' P0.1-5 come I/O non c. analogico M1 = P0m1 ' Imposta P0.0-5 e P0.7 come solo input M2 = P0m2 M1 = M1 Or &HDF M2 = M2 And &H40 P0m1 = M1 P0m2 = M2 ' M1 = P1m1 ' Imposta P1.4 come solo input e M2 = P1m2 ' P1.6 e P1.7 come open drain output M1 = M1 Or &HD0 M2 = M2 Or &HC0 M2 = M2 And &HEF P1m1 = M1 P1m2 = M2 ' M1 = P2m1 ' Imposta P2.1 e P2.7 come M2 = P2m2 ' open drain output M1 = M1 Or &H82 M2 = M2 Or &H82 P2m1 = M1 P2m2 = M2 End Sub ' ' ' Effettua un ritardo del numero di millisecondi passato nel parametro rit, ' tenendo conto della frequenza di clock salvata nella variabile cclk senza ' usare le istruzioni BASCOM che usano un valore predefinito e costante di ' clock. Sub Ritardo(rit As Word) If Cclk = Rcint Then Rit1ms = 73 ' Valore sperimentale per 1 msec a 7 MHz Else Rit1ms = 110 ' Valore sperimentale per 1 msec a 11 MHz End If Do For R = 0 To Rit1ms ' Ciclo per ritardo di 1 msec Next R Rit = Rit - 1 Loop Until Rit = 0 End Sub ' ' ' Effettua un ritardo di circa 2 secondi in modo da assicurare la ' partenza del programma di emulazione terminale per console (es. ' HYPERTERMINAL) e contemporaneamente fa` lampeggiare il LED di ' attivita` DL1 della scheda. ' Usa la variabile generale i Sub Mostra_run P0m1 = P0m1 Or &H40 ' Setta P0.6 in modo 3=OpenDrain P0m2 = P0m2 Or &H40 For I = 1 To 16 ' 16 cicli da 125 msec = 2 sec P0.6 = Not P0.6 ' Complementa LED attivita` Call Ritardo(125) ' Ritardo di circa 125 msec Next I End Sub ' ' '************************* Procedure gestione seriale ************************** ' Inizializza la linea seriale con: ' Bit x chr = 8 ' Stop bit = 1 o 2 a seconda del parametro ST ' Parity = None ' Baud rate = valore nel parametro BR ' usando l'apposito baud rate generator del micro e la frequenza di clock salvata ' nella variabile globale cclk. ' Usa le variabili generali hlpw,hlpl Sub Iniser(br As Long , St As Byte) Pcon = Pcon And &HBF ' Azzera bit SMOD0 x settare modo If St = 1 Then Scon = &H52 ' Modo 1 (1 stop),No multiproc,Attiva rx Else Scon = &HDA ' Modo 3 (2 stop),No multiproc,Attiva rx End If Brgcon = &H02 ' Imposta baud rate passato Hlpl = Br * 16 ' Calcola divisore per baud Hlpl = Cclk - Hlpl Hlpl = Hlpl / Br Hlpw = Loww(hlpl) Brgr0 = Low(hlpw) Brgr1 = High(hlpw) Brgcon = &H03 End Sub ' ' ' '************************ Procedure di uso generale **************************** ' Legge il byte di configurazione UCFG1 in FLASH grazie alle procedure IAP del ' Boot Rom del P89LPC932. Restituisce la variabile globale cclk settata con la ' frequenza di clock della CPU, senza controllare gli eventuali errori. Sub Get_clk mov A,#&H03 ' Usa comando Misc. Read mov R7,#&H00 ' Legge registro UCFG1 lcall &HFF03 ' Chiama proc. IAP ad ind. PGM_MTP mov A,R7 ' Salva risultato anl A,#&H07 ' Mantiene bit con clock CPU Select Case Acc Case &H00 : Cclk = Qz11m ' Frequenza clock da quarzo esterno Case &H03 : Cclk = Rcint ' Frequenza clock da RC interno End Select End Sub ' ' ' Controllo correttezza periferiche interne con eventuali ritentativi ' Usa le variabili generali st,t,m,ind,hlpw Sub Check Deecon = &H01 T = Peek(&Hff) Deeadr = &HFF T = 1 Ind = &HF7 Do M = Peek(&H07) If M.7 = 1 Then M = M And &H03 Ind = M + &HF8 T = Peek(ind) Else T = 0 End If St = Deecon And &H80 Loop Until St <> 0 St = Deedat Do S = Peek(ind) Incr Ind If Ind = &HFF Then Ind = &HF9 Do M = S If St = 0 Then Incr T End If Loop Until St.0 = 0 Or T > M Loop Until St = 0 End Sub