' ********************************************************************** ' * File gmbser.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 * ' ********************************************************************** ' ' Il demo e' un semplice esempio di comunicazione in grado di operare con tutti ' i protocolli elettrici disponibili su CN2 (RS 232, RS 422, RS 485, ' current loop o TTL). In dettaglio, tramite funzioni a basso livello, ' e' possibile programmare il baud rate da console, poi ogni carattere ricevuto ' dalla seriale viene ritrasmesso sulla stessa; la ricezione del carattere 'r' ' determina la gestione della direzione (segnale DIR) per RS 422 e RS 485. ' ' 01.06.05 - Rel 1.1 By Graziano Gaiba ' ' Il file compilato non supera i 2048 bytes, quindi puo' essere ' compilato con il demo gratuito di BASCOM 8051. ' '****************** 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 $map ' Genera info per debug ' '****************** 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 Const Attivo = 1 ' Valore per attivare il driver 422 o 485 Const Disattivo = 0 ' Valore per disattivare il driver 422 o 485 ' '****************** Dichiarazione delle variabili ********************** ' ' Variabili ad uso generico Dim S1 As String * 1 ' Stringhe di un carattere Dim S0 As Bit ' Bit di uso generico Dim I As Byte Dim Hlpb As Byte , M As Byte ' Byte ad uso generico Dim M1 As Byte , M2 As Byte ' Byte ad uso generico Dim T As Byte , S As Byte , V As Byte ' Byte di uso generico Dim Hlpw As Word , Ind As Word ' Word ad uso generico Dim Hlpl As Long ' Long ad uso generico Dim Scelta As String * 1 ' Stringa di un carattere ' Variabili per gestione comunicazione seriale, clock e ritardi Dim Chav As Bit Dim St As Byte , Chser As Byte Dim Br As Long ' Buad Rate seriale Dim Cclk As Long ' Frequenza clock della CPU Dim R_cnt As Word , Rit1ms As Word , Rit As Word ' Gestione ritardi ' '****************** Dichiarazione delle procedure ********************** ' Declare Sub Init() ' Inizializzazione 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 Demoser() ' Gestione UART in tutti i protocolli Declare Sub Txser(chser As Byte) ' Trasmette carattere Declare Sub Rxser ' Verifica e riceve carattere ' ' ' ' 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 ' Inzializza il modulo 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 Do Print Chr(clrscr); ' Pulisce lo schermo Print "Demo 1.1 per GMM936 ds300803+GMBHR84 ds220503" Call Check ' Controllo interno Call Demoser() Loop End ' '************************ Fine del programma *************************** ' ' '**************************** Procedure ******************************** ' ' Sub Demoser Print Print "Seriale RS 232,RS 422,RS 485,current loop o TTL su CN2" Print Print "Il demo riceve e ritrasmette a basso livello, se riceve F torna a 19200 Baud, 1 stop." Print "Se riceve r complementa lo stato della linea dir. Jumper J7 deve essere in 1-2." Input "Baud Rate= " , Br Input "Stop Bit= " , St ' Pone in output (push pull) P2.0 P2m1.0 = 0 P2m2.0 = 1 S0 = Disattivo P2.0 = 1 Call Ritardo(10) ' Attende fine tx ultimo chr Call Iniser(br , St) ' Inizializza seriale con dati inseriti Chser = 0 ' Per non uscire subito Do Call Rxser ' Verifica se chr ricevuto If Chav = 1 Then ' Se chr disponibile Call Txser(chser) ' Lo trasmette If Chser = "r" Then If S0 = Disattivo Then S0 = Attivo P2.0 = 0 Else S0 = Disattivo P2.0 = 1 End If End If End If Loop Until Chser = "F" ' Attende ricezione F Call Ritardo(10) ' Attende fine tx ultimo chr Call Iniser(19200 , 1) ' Inizializza seriale per console End Sub ' ' Trasmette sulla seriale hardware della scheda il carattere salvato ' nel parametro char. Sub Txser(chser As Byte) Bitwait Scon.1 , Set ' Attesa trasmettitore libero Scon.1 = 0 ' Resetta bit fine trasmissione Sbuf = Chser ' Trasmette carattere End Sub ' ' ' Verifica se ricezione dalla seriale hardware della scheda e ' restituisce l`eventuale carattere ricevuto nella variabile chser; ' restituisce inoltre flag booleano chav che indica se il carattere ' e` disponibile. Sub Rxser If Scon.0 = 1 Then ' Controlla se chr ricevuto Scon.0 = 0 ' Resetta bit chr ricevuto Chser = Sbuf ' Preleva carattere ricevuto Chav = 1 Else Chav = 0 ' Nessun carattere ricevuto End If End Sub ' ' 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 ' ' ' 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_cnt = 0 To Rit1ms ' Ciclo per ritardo di 1 msec Next R Rit = Rit - 1 Loop Until Rit = 0 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 ' ' '************************* 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 If Acc = &H00 Then Cclk = Qz11m ' Frequenza clock da quarzo esterno Else Cclk = Rcint ' Frequenza clock da RC interno End If 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 St = St And &H80 Loop Until St <> 0 T = St St = Deedat Do M = Peek(ind) Incr Ind If Ind = &HFF Then Ind = &HF9 Hlpw = 0 T = T + M Hlpw = Ind + T M = Peek(t) If St = 0 Then Incr T Else Call Ritardo(1) ' Pausa 1 msec End If Loop Until St = 0 End Sub