Vai al contenuto
PLC Forum


Settaggio Usart Pic18f4620


Grandegiove

Messaggi consigliati

Buongiorno a tutti

nell'ambito di un progetto sto valutando varie ipotesi fra le quali l'utilizzo di un sensore a ultrasuoni per la misura di distanze.

Per un primo approccio ho comprato questo oggettino superamatoriale:

http://www.futurashop.it/pdf_eng/7300-SRF485.pdf

l'oggetto si interfaccia mediante seriale RS485 con un protocollo dedicato descritto nel datasheet; il problema princicpale risulta questo:

Serial data is fixed at 38400 baud 1 start, 2 stop and no parity bits.

Prensavo di usare un PIC18f4620 per interfacciarmi visto che ho già il DRIVER RS485 montato su una scheda con Lcd ma mi trovo in difficoltà a settare i parametri dell'USART in quanto il DataSheet del micro dice

The Asynchronous mode of operation is selected by

clearing the SYNC bit (TXSTA<4>). In this mode, the

EUSART uses standard Non-Return-to-Zero (NRZ)

format (one Start bit, eight or nine data bits and one

Stop bit).

Come faccio a interfacciarmi? Mi sto perdendo in un bicchier d'acqua?

Anche nella definizione del pacchetto ho qualche dubbio. In particolare in relazione al primo campo dice:

Break - is defined as a continuous low in excess of 22 bit periods, followed by a high of 2 bit periods. Each bit is 26uS at 38400 baud, so 22 * 26uS =572uS, it's ok to be longer.

Che si fa?

Grazie mille

Link al commento
Condividi su altri siti


In ricezione non hai problemi. In trasmissione, trasmetti un carattere alla volta e alla fine della Tx aggiungi una routine di ritardo pari al tempo di trasmissione di un bit.

A cosa ti serve gestire il "break" sulla linea ?

Ciao.

Link al commento
Condividi su altri siti

kappa47+28/05/2011, 11:46--> (kappa47 @ 28/05/2011, 11:46)

Ciao!

Come puoi vedere dal link il breakè il primo campo del pacchetto, devo quindi gestirlo per forza di cose.

Link al commento
Condividi su altri siti

Scusa, ma non avevo aperto il link.

Non ricordo se il 18f4620 gestisce il break (credo di si, ma non come serve a te: 600 uS). Verifica.

In alternativa, per trasmettere potresti:

1) disabilitare la periferica EUSART

2) configurare il pin di Tx come general I/O in output

3) fare l'output a zero per il tempo indicato (600 uS)

4) riabilitare la periferica EUSART (il pin di Tx dovrebbe tornare alto automaticamente)

5) attesa di 50 uS e poi inizi a trasmettere

Per la ricezione (alla fine della trasmissione):

1) disabilitare la periferica EUSART

2) configurare il pin di Rx come general I/O in input

3) testare in polling il fronte di salita del pin Rx

4) riabilitare la periferica EUSART e metterti in attesa dei caratteri.

Piuttosto macchinoso, ma non mi viene in mente altro.

Ciao.

Link al commento
Condividi su altri siti

kappa47+28/05/2011, 13:26--> (kappa47 @ 28/05/2011, 13:26)

Credo proprio che questo non lo si possa fare.

Per usare l'usart è necessario impostare rc6 e rc7 come input.

Credo poi che non si possa cambiare in modo dinamico il trisc disabilitando la seriale ...

Link al commento
Condividi su altri siti

Non e' vero. Provare per credere...

Non ho mai provato con la cella EUSART, ma ti posso assicurare che la modifica run time delle porte (agendo sul "tris") l'ho fatta piu volte.

Ovviamente bisogna tenere in memoria l'immagine della porta per mantenere la stessa direzione (input/output) e livelli sui pin che non si vogliono modificare.

Ciao.

Link al commento
Condividi su altri siti

Non utilizzo PIC ma anche secondo me è vero quello che dice Kappa47 in merito alla modifca runtime della configurazione delle porte ovviamente disabilitando la funzione alternativa che associa il pin a una periferica come ha spiegato sopra Kappa47

Una soluzione alternativa potrebbe essere questa: utilizzi un pin in più che colleghi in and con il TX del micro. (Ti bastano due diodi e una resistenza) quando abbassi uno dei pin porti bassa la linea del TX.Con il pin aggiuntivo generi il break e poi parti con la trasmissione.

Invece per il doppio stop puoi aspettare il tempo maggiore di un bit ogni volta che trasmetti un byte come ti hanno detto oppure vito che la seriale supporta la trasmissione 9bit configura il dato a 9bit e lascia il nono bit sempre a 1 ed è come se tu usassi 2stop bit

Link al commento
Condividi su altri siti

kappa47+1/06/2011, 20:07--> (kappa47 @ 1/06/2011, 20:07)

Ciao

Dal datasheet del PIC18F4620:

The pins of the Enhanced USART are multiplexed

with PORTC. In order to configure RC6/TX/CK and

RC7/RX/DT as a USART:

• SPEN bit (RCSTA<7>) must be set (= 1)

• TRISC<7> bit must be set (= 1)

• TRISC<6> bit must be set (= 1)

Su tuo consiglio ho verificato e in effetti se TRISC.6 lo si inizializza a 0 la USART non funziona.

Modificato: da Grandegiove
Link al commento
Condividi su altri siti

accacca+1/06/2011, 20:29--> (accacca @ 1/06/2011, 20:29)

Sono proprio orientato in questa direzione! Grazie! Ora vediamo..

Link al commento
Condividi su altri siti

Non vorrei fare polemica...

A te non interessa che funzionino contemporaneamente USART e Genaral I/O, quindi in tempi diversi puoi abilitare un modo di funzionamento o l'altro.

Ho capito male ?

Ciao.

Link al commento
Condividi su altri siti

kappa47+3/06/2011, 13:51--> (kappa47 @ 3/06/2011, 13:51)

Assolutamente zero polemica! Ci mancerebbe che mi mettessi a polemizzare con chi cerca di darmi una mano happy.gif. Se mi sono espresso male mi scuso wink.gif

Solo dicevo che durante l'utilizzo dell'usart rc6 e rc7 devono necessariamente essere settati come input se no non funziona. Questa è la prima prova che ho fatto.

Ho quindi provata a modificare run time l'impostazione di I/O (TRISC.6) disabilitando e riattivando l'eusart ma purtroppo la cosa non mi funge..

Problemi di compilazione?

Mumble mumble...

Modificato: da Grandegiove
Link al commento
Condividi su altri siti

Non ho trovato hardware con 18f4620; quello che si avvicina di piu' e' il 18f6622.

Ovviamente ci sono delle differenze, anche se non sono molte...

Prendi spunto dal listato; ti assicuro che e' funzionante.

Ciao.

#include	<p18f6622.h>

typedef	unsigned char  u_char;  // 1 byte
typedef	unsigned int  u_int;  // 2 bytes

// Union/Struttura porta RG: UART 2 (p_com)
union	tag_com
  {
  u_char	com;
  struct
	{
	unsigned char FREE_OUT0	: 1;  // RG0: libero
	unsigned char TX_PC	: 1;  // RG1: RS232-TxD_2
	unsigned char RX_PC	: 1;  // RG2: RS232-RxD_2
	unsigned char FREE_OUT3	: 1;  // RG3: libero
	unsigned char FREE_OUT4	: 1;  // RG4: libero
	unsigned char  : 3;  // pad next 3 locations
	};
  };

union	tag_com  p_com;  	// immagine porta RG

// Routine di attesa (circa 1 milliSec. [at] 16 MHz con "count = 0x01")
void attesa (u_int count)
  {
  u_int  ax0;
  u_int  ax1;
  u_int  ax2;

  for (ax0=0; ax0<count; ax0++)
    {
    for (ax1=0; ax1<7; ax1++)
      {
      //reset_watch_dog ();
      for (ax2=0; ax2<23; ax2++)
        {
        Nop ();
        Nop ();
        Nop ();
        Nop ();
        }
      }
    }
  }

// Init Port G
void init_port_g (void)
  {
  PORTG = 0x00;    // clear output data latches 
  LATG  = 0x00;
  TRISG = 0b11100100;  	// 1=input / 0=output
  p_com.com = 0x06;
  PORTG = p_com.com;
  }

// Enable UART 2
void init_uart_2 (void)
  {
  u_char	dummy;

  IPR3bits.RC2IP = 0;  	// priority: low
  // sempre 1 STOP bit
  //SPBRG2 = 12;  	// 19200 baud at 16 MHz
  SPBRG2 = 25;    //  9600 baud at 16 MHz
  //SPBRG2 = 207;  	//  1200 baud at 16 MHz
  RCSTA2 = 0x80;  	// serial port enabled

  //PIR3bits.TX2IF = 0;  	// non serve
  PIE3bits.TX2IE = 0;

  PIR3bits.RC2IF = 0;  	// reset interrupt pending (flag)
  //PIE3bits.RC2IE = 1;  	// Rx Interrupt enabled
  PIE3bits.RC2IE = 0;  	// Rx Interrupt disable

  TXSTA2 = 0x00;  	// TX disabled, 8-bit, Async.
  dummy  = RCREG2;  	// clear flags from receive.
  }

// Trasmissione di un carattere a UART 2
void car_1pc (u_char car)
  {
  // aspetto Trasmit Shift Register vuoto
  while (TXSTA2bits.TRMT == 0);
  TXREG2 = car;    // trasmetto
  }

void main (void)
  {
  INTCONbits.GIEH = 0;  	// Disable all interrupts high
  INTCONbits.GIEL = 0;  	// Disable all interrupts low

  init_port_g ();
  init_uart_2 ();

  TXSTA2bits.TXEN = 1;    // Enable Tx UART 2
  while (1)
    {
    //reset_watch_dog ();  	// non serve, se disabilitato
    car_1pc ('U');
    attesa (2);
    car_1pc ('1');
    attesa (10);
    TXSTA2bits.TXEN = 0;  	// disable Tx UART 2
    RCSTA2bits.SPEN = 0;  	// disabilito cella UART (posso usare "port_g")
    Nop ();
    PORTGbits.RG1 = 0;
    attesa (10);
    PORTGbits.RG1 = 1;
    attesa (10);
    PORTGbits.RG1 = 0;
    attesa (10);
    PORTGbits.RG1 = 1;
    attesa (10);
    RCSTA2bits.SPEN = 1;  	// ripristino cella UART
    TXSTA2bits.TXEN = 1;  	// Enable Tx UART 2
    }
  }

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...