{ **************************************************************** * File: gmbser.ppas - Ver. 1.1 * * Compilatore: mikroPascal for PIC by mikroElektronica * * IDE: mikroPascal for PIC by mikroElektronica * * Versione Compilatore: 2.1.6.0 * * Schede: GMM 4620 + GMB HR168 * * 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 09.03.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' o 'R' determina la gestione della direzione (segnale DIR) per RS 422 e RS 485. Rel 1.1 - by Graziano Gaiba Demo di utilizzo a basso livello della periferica EUSART usando una GMB HR168 pilotata da un Mini Modulo GMM 4620 } { ***************** Definizioni del compilatore ****************** } program gmbser; { *************** Dichiarazione delle contanti ******************* } const ASC_r: byte = 114; const ASC_rU: byte = 82; { ******************* Dichiarazione delle Variabili ******************** } // Variabili di uso generico var d_in: byte; { ******************* Definizione delle procedure ********************* } // Inizializzazione direzione segnali della CPU procedure Init_cpu; begin 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 := trisa or $13; trisb := trisb or $03; trisc := trisc or $23; { 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 and $03; { Le uscite relays di CN4 sono: OUT D1 <-> RA3 OUT D2 <-> RC2 (J10 in posizione 3-4) } trisa := trisa and $f7; trisc := trisc and $fb; // Inizialzza modulo USART (8 bit, 19200 baud rate, // no parity) Usart_init(19200); end; // Invia una stringa di caratteri alla porta seriale procedure print_USART(var txt: string[100]); var temp1, temp2: byte; begin temp1 := txt[0]; for temp2 := 1 to temp1 do begin USART_Write(txt[temp2]); end; end; // Invia CR + LF procedure print_CRLF; begin USART_Write(10); USART_Write(13); end; // Pulisce lo schermo, inviando 25 volte CR + LF. procedure clrscr; var temp: byte; begin for temp := 0 to 24 do begin print_CRLF; end; end; // Chiede la pressione di un tasto procedure wait_key; var temp: byte; begin print_usart('Premere un tasto...'); repeat begin nop; end; until USART_Data_Ready = 1; temp := USART_Read; end; { 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) } procedure set_relays(port_val: byte); begin // I relays sono pilotati in logica complementata , quindi anche port_val // deve essere complementato port_val:=port_val xor $ff; if TestBit(port_val, 0) = 0 then begin ClearBit(portb, 4); end else begin SetBit(portb, 4); end; if TestBit(port_val, 1) = 0 then begin ClearBit(portb, 5); end else begin SetBit(portb, 5); end; if TestBit(port_val, 2) = 0 then begin ClearBit(portb, 6); end else begin SetBit(portb, 6); end; if TestBit(port_val, 3) = 0 then begin ClearBit(portb, 7); end else begin SetBit(portb, 7); end; if TestBit(port_val, 4) = 0 then begin ClearBit(portb, 3); end else begin SetBit(portb, 3); end; if TestBit(port_val, 5) = 0 then begin ClearBit(portb, 2); end else begin SetBit(portb, 2); end; if TestBit(port_val, 6) = 0 then begin ClearBit(porta, 3); end else begin SetBit(porta, 3); end; if TestBit(port_val, 7) = 0 then begin ClearBit(portc, 2); end else begin SetBit(portc, 2); end; end; {Trasmissione di un singolo carattere usando il modulo EUSART a basso livello. Il carattere da trasmettere e' il parametro della procedura. La procedura e' bloccante: attende che si liberi il trasmettitore. } procedure tx_char(char_to_tx: byte); begin // attende che si liberi il trasmettitore repeat begin nop; end; until TestBit(txsta,1) = 1; txreg := char_to_tx; end; {Verifica che sia stato ricevuto un carattere. Se un carattere e' stato ricevuto restituisce 1, altrimenti 0. } function rx_status: byte; var kbhit: byte; begin if TestBit(pir1, 5) = 1 then begin ClearBit(pir1, 5); kbhit := 1; end else begin kbhit := 0; end; Result := kbhit; end; {Ricezione di un singolo carattere usando il modulo EUSART a basso livello. NON check verifica che un carattere si stato effettivamente ricevuto. } function rx_char: byte; begin Result := rcreg; end; { ********************** Programma principale *************************** } begin Init_cpu; // Spegne i relays set_relays(0); // Serve la comunicazione a basso livello perche' il segnale DIR non viene // gestito dalle istruzioni di alto livello del PIC BASIC PRO. // Disabilita rilevazione baud-rate automatica, generatore baud-rate a 8 bit baudctl := 0; { Valore per baud rate 19200 e tenendo conto dei settaggi fatti sopra ' Fosc ' SPBRG = -------------- - 1 ' 16 * BaudRate } spbrg := 31; // Baud rate elevati, modo asincrono, abilta trasmettitore, trasmette a 8 bit txsta := $24; // Abilita ricevitore, ricezione a 8, abilita porta seriale rcsta := $90; clrscr; print_USART('Demo EUSART a basso livello Rel 1.1 per GMM 4620 rel 120304'); print_CRLF; print_USART('e GMB HR168 rel 110104'); print_CRLF; print_CRLF; print_USART('Viene mostrato come configurare la accoppiata per comunicazione seriale'); print_CRLF; print_USART('tipo RS 232, TTL, RS 422, RS 485.'); print_CRLF; print_USART('Seguendo le istruzioni si puo provare la comunicazione RS 232 a basso livello,'); print_CRLF; print_USART('ovvero pilotata da istruzioni assembly anziche da comandi BASIC.'); print_CRLF; print_USART('Poi, RS 422 o RS 485 viene configurato ed utilizzato. Anche un segnale di'); print_CRLF; print_USART('direzione viene usato con il protocollo RS 485.'); print_CRLF; wait_key; print_CRLF; print_CRLF; print_USART('In RS 232: su GMM 4620 mettere ON i dip switch da 1 a 3, mettere OFF gli altri,'); print_CRLF; print_USART('mettere OFF i dip switch 2 e 3, mettere ON i dip switch 4 e 5, per avere'); print_CRLF; print_USART('dei segnali TTL dalla EUSART direttamente sui pin dello zoccolo.'); print_CRLF; print_USART('Collegare J10 in 1-2.'); print_CRLF; wait_key; print_CRLF; print_CRLF; print_USART('Collaudare in RS232, poi configurare GMB per un altro protocollo a scelta:'); print_CRLF; print_USART('Spegnere la accoppiata, impostare i dip switch:'); print_CRLF; print_USART('2=3=OFF,4=5=ON, poi:'); print_CRLF; print_CRLF; print_CRLF; print_USART('RS422:'); print_CRLF; print_USART('-installare SN75176 o MAX483 su IC10 e IC11'); print_CRLF; print_USART('J5=2-3 J6,J7,J8=1-2 J10=1-2'); print_CRLF; print_CRLF; print_CRLF; print_USART('RS485:'); print_CRLF; print_USART('-installare SN75176 o MAX483 su IC10'); print_CRLF; print_USART('-J5=1-2 J6,J7,J8=1-2 J10=1-2'); print_CRLF; print_CRLF; print_CRLF; print_USART('Se la accoppiata si trova allo estremo di una rete -> J3 e J4 vanno connessi'); print_CRLF; print_USART('La ricezione del carattere R commuta lo stato del trasmettitore'); print_CRLF; // Il segnale DIR per RS 485 e' PORTE.2 ClearBit(trise,2); ClearBit(porte,2); repeat begin if rx_status = 1 then begin d_in := rx_char; if (d_in = ASC_r) or (d_in = ASC_rU) then begin if TestBit(porte,2) = 0 then begin SetBit(porte, 2); end else begin ClearBit(porte,2); end; end; tx_char(d_in); end; end; until False; end.