Creative Commons BY-NC-ND 2.5Questo sito e tutto il suo contenuto sono distribuiti sotto la licenza Creative Commons Attribuzione - Non Commerciale - Non opere derivate 2.5 Italia e con le condizioni d'uso definite nel disclaimer: siete pregati di leggere entrambi questi documenti prima di usufruire dei contenuti di questo sito. Per alcuni contenuti è necessaria una registrazione gratuita: non è necessario pagare e non è necessario accumulare punteggi per accedere agli articoli e scaricare i sorgenti. Basta solo essere onesti. Se volete che questo sito continui a rimanere attivo, a contribuire ogni giorno alla diffusione della cultura libera, non copiate il materiale per ripubblicarlo in altri luoghi : chi fa questo è solo un miserabile e un perdente. Se volete partecipare su settorezero e rendere le vostre idee, i vostri progetti, fruibili da tutti senza limitazioni, come dovrebbe essere in un paese civile e acculturato, potete farlo tranquillamente.

Corso programmazione PICMicro in C – Lezione 10 – L’USART e la comunicazione seriale con il protocollo RS232. Realizziamo un semplice sistema di automazione

Autore: Giovanni Bernardo | Data pubblicazione: 19 gennaio 2010
Categorie: PICmicro 10/12/16

comunicazione_rs232_usart

In questa puntata analizzeremo come è possibile far comunicare il nostro picmicro attraverso il protocollo seriale RS232 e realizzeremo una semplice applicazione che sfrutta tale sistema di comunicazione interfacciandoci col pc: faremo accendere/spegnere dei led impartendo dei comandi da porta seriale e verificheremo da terminale quali pulsanti l’operatore ha premuto sulla scheda. Impareremo quindi anche ad utilizzare il classico programma che Windows mette a disposizione per interfacciarsi con la porta seriale: Hyperterminal. Mettetevi comodi perchè oggi c’è parecchio da leggere e capire: sarebbe semplice mettere un codice già pronto e non imparereste a risolvere eventuali problemi qualora si dovessero presentare, quindi meglio capire per bene tutto quello che c’è dietro prima di cominciare, anche perchè sicuramente procura molta più soddisfazione.

Panoramica sui sistemi di comunicazione seriale

Prendiamo in considerazione la trasmissione di un byte: 8 bit. In una comunicazione di tipo parallelo, per poter inviare un byte abbiamo bisogno di 8 linee dati (non è sempre così, ma la maggior parte delle volte lo è): ogni linea invierà un bit, per cui gli 8 bit saranno trasmessi contemporaneamente. In una comunicazione di tipo seriale, invece, si utilizzerà un’ unica linea sulla quale saranno inviati in sequenza gli 8 bit. Le modalità con cui questi bit vengono inviati variano da protocollo a protocollo: ogni protocollo di comunicazione seriale ha le sue regole ed i suoi limiti e quindi le sue applicazioni.

Come si capisce, a parità di velocità del sistema di trasmissione, una comunicazione di tipo parallelo è sicuramente più veloce: gli 8 bit vengono inviati in contemporanea, ovviamente questo ha anche i suoi svantaggi: c’è bisogno di molte linee dati e le cose si complicano ulteriormente quando su un unico bus (su un’unica linea di trasmissione dati) bisogna collegarvi più dispositivi: una marea di cavi. Per tale motivo le comunicazioni di tipo parallelo stanno pian piano scomparendo: anche nei pc, giusto per fare un esempio, si sta abbandonando lo standard EIDE a favore del SATA: i cavi occupano meno spazio e c’è la possibilità di staccare i dispositivi anche mentre sono in funzione senza influenzare il resto del sistema. Riguardo alla velocità… ormai le velocità raggiunte hanno sorpassato i vecchi sistemi di comunicazione parallela (questo perchè si è deciso di non investire più sulla parallela per i motivi appena detti).

Le modalità di comunicazione (sia di tipo seriale che parallelo) possono essere Full Duplex oppure Half Duplex: si parla di comunicazione full duplex quando lo scambio di dati avviene in entrambi i sensi e in contemporanea. Nel caso di una trasmissione seriale full duplex possiamo immaginare che vi siano due fili che collegano due dispositivi A e B, il dispositivo A comunicherà verso il B attraverso un filo e il B verso l’A attraverso l’altro filo e questo può avvenire in contemporanea essendo le due linee separate.

In ogni tipo di comunicazione abbiamo ovviamente bisogno anche della linea di massa comune.

In una trasmissione Half Duplex abbiamo invece a disposizione un’unica linea di comunicazione: potrà trasmettere un  unico dispositivo per volta, in questo tipo di comunicazione generalmente si individua un dispositivo “master” che comanda la comunicazione e uno o più dispositivi “slave” che ricevono gli ordini impartiti dal master.

Vi sono anche le comunicazioni di tipo simplex, seppur più rare, in cui c’è un solo “filo” (una sola linea di comunicazione) e comunica un unico dispositivo: l’altro riceve soltanto e non comunica.

Oltre alla modalità con cui si determina la direzione dei dati, una trasmissione seriale viene ancora suddivisa in sincrona o asincrona. Si parla di comunicazioni sincrone quando abbiamo un’ulteriore linea destinata al “clock”: un segnale ad onda quadra che scandisce il tempo: ad ogni colpo di clock viene inviato/ricevuto un bit, questo tipo di trasmissione permette di raggiungere elevate velocità.

Abbiamo una comunicazione di tipo asincrona quando non abbiamo un clock che scandisce i tempi e i due dispositivi sono preimpostati per lavorare alla stessa velocità.

Il protocollo RS232

Un protocollo, quindi, definisce il modo e le regole con cui i dati vengono scambiati. Il protocollo RS232 prevede innanzitutto una comunicazione seriale, asincrona, full duplex: abbiamo due linee di trasmissione dati (una di trasmissione e una di ricezione, la linea di trasmissione del terminale A diventa ovviamente la linea di ricezione del terminale B e viceversa), i dati vengono trasmessi in maniera seriale (un bit dopo l’altro) e non abbiamo un clock che scandisce i tempi di trasmissione, per cui i due dispositivi che comunicano devono essere preimpostati alla stessa velocità di trasmissione altrimenti non potranno comunicare. Il protocollo RS232 in realtà è molto più esteso: vi sono infatti altre linee di comunicazione oltre alle due riservate a trasmissione e ricezione, ma non ce ne occuperemo.

Dal momento che la trattazione su tale protocollo di comunicazione è davvero molto lunga (e quindi richiederebbe pagine e pagine di spiegazioni) e dal momento che ritengo ci siano già dei validi tutorial in giro sull’argomento, vi consiglio fortemente di leggere il tutorial sul protocollo RS232 scritto da Mauro Laurenti, che è possibile trovare in questa pagina: http://www.laurtec.com/Italiano/Tutorial/Il%20protocollo%20RS232/Tutorial.html

E’ possibile leggere una trattazione, ancora più estesa, sul protocollo RS232 nelle pagine di Vincenzo Villa a partire da qui: http://www.vincenzov.net/tutorial/rs232/rs232.htm

Una lettura a tali tutorial va fatta sicuramente per apprendere appieno tutto ciò che sta dietro a questo tipo di comunicazione.

I livelli logici di trasmissione e Il MAX232

Un’altra caratteristica, importantissima, del protocollo RS232 sono i livelli di tensione che determinano gli stati logici. Nei picmicro, che sono dispositivi a logica TTL, un livello di tensione di +5 volts corrisponde allo stato logico 1, un livello di tensione pari a 0 Volt corrisponde allo stato logico 0. Nel protocollo RS232 la specifica per i livelli logici è completamente differente: abbiamo un livello logico 1 quando la tensione vale circa -12Volts e un livello logico 0 quando la tensione è circa +12Volts (in realtà il range di tensione è più esteso, questi che ho indicato sono i livelli di tensione medi). Come vedete, quindi non è possibile interfacciare direttamente un dispositivo a logica TTL con una comunicazione RS232: un segnale di +5Volt che dal lato TTL è un livello logico alto, dal lato RS232 può essere interpretato come un livello logico basso, invece un livello TTL basso può non essere interpretato affatto.

Per tale motivo, al fine di poter interfacciare un dispositivo a logica TTL con una comunicazione RS232 esistono quelli che alcuni chiamano traslatori di livello oppure più semplicemente RS232 Drivers. Il driver maggiormente utilizzato in questo campo è il circuito integrato MAX232 prodotto dalla Maxim (datasheet scaricabile in fondo all’articolo) e i suoi cloni, che riesce ad ottenere i giusti livelli di tensione sfruttando un circuito a pompa di carica. Si tratta quindi di un semplice convertitore di livello logico, ne vediamo nel datasheet l’applicazione:

comunicazione_rs232_usart_max232Abbiamo l’integrato suddiviso in due “lati”: un lato TTL/CMOS e un lato RS232. Applicando un segnale logico TTL agli ingressi 11 (T1IN) e 10 (T2IN), avremo in uscita (ai pin 14 e 7 rispettivamente: T1OUT e T2OUT) un segnale logico RS232. Al contrario applicando un segnale logico RS232 agli ingressi 13 (R1IN) e 8 (R2IN), avremo in uscita (ai pin 12 e 9 rispettivamente: R1OUT e R2OUT) un segnale logico TTL. Il circuito è molto semplice, basta soltanto piazzare i condensatori come indicato dallo schema, senza stupirsi del fatto che due condensatori vengono montati al contrario (vedete che C4 ha il positivo verso massa e C3 ha il negativo verso l’alimentazione). In realtà non vengono montati al contrario se si capisce il principio che sta alla base del funzionamento di una pompa di carica.

Guardando la tabella notiamo che se scegliamo un MAX232A (da notare la A finale) possono essere utilizzati condensatori da 0,1μF (100nF), con un MAX232 sono necessari condensatori da almeno 1μF (in realtà io avendo una scorta di condensatori da 10μF uso questi, quindi non vi preoccupate se non li avete: potete mettere anche una capacità più alta, senza esagerare con le dimensioni).

Inoltre, come si vede dallo schema, il MAX232 supporta 4 linee di comunicazione (vi sono pure integrati della stessa famiglia che ne supportano di più), ma a noi per realizzare una comunicazione semplice ne bastano soltanto 2.

In questo nostro articolo è presentata una valida interfaccia TTL/RS232

La porta seriale sui pc

I normali pc fissi di oggi hanno sul retro almeno una porta seriale di tipo RS232 (anzi: dovrebbero avere), identificata esternamente da un connettore maschio a 9 poli a forma di “D” rovesciata (questo tipo di connettore viene generalmente chiamato DSUB9, SUBD9 o DB9):

connettore_DSUB9_maschioFate caso che anche quando acquistiamo uno di questi connettori nuovi da cablare, sia maschio che femmina, è sempre riportato il numero affianco ad ogni pin. Il pinout è possibile vederlo nel documento Piedinatura seriale presente nella sezione risorse (Piedinatura Seriale DB9 (1236)). Come  potete vedere dal pinout il connettore maschio (sul pc) e il connettore femmina (che in genere si trova sul dispositivo da accoppiare al pc) hanno i pin di ricezione (RX) e trasmissione (TX) nella stessa posizione quando vengono accoppiati, per cui innestandoli uno nell’altro non si ha comunicazione: a tale scopo vengono difatti utilizzati dei cavi chiamati null-modem (o semplicemente cavo seriale incrociato) che mettono in comunicazione il pin 3 (trasmissione) con il pin 2 (ricezione) dell’altro.

cavo_nullmodemDifatti per realizzare una semplice comunicazione RS232 tra due dispositivi, basta unicamente un cavo con 3 fili : uno che collega insieme i due pin di massa (il numero 5), uno che collega il pin 2 di uno col pin 3 dell’altro e uno che collega il pin 3 col pin 2 dell’altro. Il cavo avrà il connettore femmina da un lato (da innestare sul pc) e il connettore maschio dall’altro (da innestare sul dispositivo). Se non abbiamo il materiale per realizzarlo, tale cavetto può comunque essere acquistato nei negozi di informatica intorno ai 5 euro se non di meno.

Sui portatili generalmente la porta seriale non è presente.  Per sopperire a tale mancanza la soluzione migliore, anche se abbastanza costosa, è quella di montare una scheda seriale PCMCIA. Altrimenti un’altra soluzione, più pratica ed economica è quella di usare gli adattatori USB/RS232 anche se in effetti in questo modo non si ha una seriale vera e propria ma viene emulata via software: proprio a causa di questo spesso alcuni di questi adattatori (spesso quelli più economici) non funzionano con tutti i dispositivi seriali: io ho una completa sfiducia in questo tipo di adattatori e non li consiglio quasi mai.adattatore_usb_rs232

Personalmente però, ho avuto modo di provarne uno che con questa applicazione mi ha funzionato, lasciandomi stupito, anche se in realtà proprio economico non era (pagato 20 euro, ma ce ne sono alcuni che costano molto di più, la differenza suppongo stia nei chip utilizzati).

In giro si trovano moltissimi progetti per costruirsi da soli un convertitore USB/RS232, la maggior parte sono basati sul noto FDTI232BM,  che è uno dei migliori chip in commercio per fare questa operazione. Trattandosi comunque di un componente SMD non tutti hanno l’attrezzatura adatta per potersi realizzare il circuito.

In una comunicazione RS232, i due dispositivi che comunicano tra loro devono avere impostati alcuni parametri: la velocità di trasmissione, i bit di dati, i bit di stop e la parità.

La velocità di trasmissione viene anche chiamata Baud Rate, e in una comunicazione RS232 rappresenta il numero di bit trasmessi in un secondo. I suoi valori più comuni sono 1200, 2400, 4800, 9600, 19200, 38400, 57600.  Non tutti i chip destinati ad effettuare la comunicazione seriale supportano tutte le velocità e tutte le modalità di trasmissione dati.

I bit di dati rappresentano la quantità di bit inviati per ogni carattere: in una normale comunicazione standard, viene generalmente inviato un byte per ogni dato. Dal momento che ogni byte identifica un carattere secondo il codice ascii (Tabella Ascii estesa (1106)), osservando una comunicazione seriale vedremo che lungo le linee di trasmissione vengono trasmessi dei caratteri: è il modo per rappresentare un byte. In una trasmissione RS232 il bit meno significativo viene trasmesso per primo.

Il bit di stop serve a creare una pausa tra l’invio di un carattere e il successivo.

Il bit di parità serve ad aggiungere eventualmente un controllo di errore sui dati inviati (si veda il tutorial di Mauro per maggiori informazioni). Ho scritto eventualmente perchè tale controllo può anche essere omesso.

La comunicazione RS232 con un picmicro

La comunicazione RS232, anche se tende ad essere soppiantata dall’USB (che sfrutta sempre una comunicazione di tipo seriale ma senza un protocollo ben definito: sull’USB la comunicazione viene fatta via software, quindi ogni dispositivo deve avere necessariamente un suo driver di comunicazione) è quasi sempre presente sui pc fissi, e si trova soprattutto sulle strumentazioni industriali. Difficilmente verrà soppiantata dal momento che comunicare con l’RS232 è molto semplice, difatti su alcuni portatili hanno cominciato a rimetterla.

Il protocollo di comunicazione RS232 sui picmicro si implementa normalmentefacendo uso della periferica chiamata USART (Universal Synchronous Asynchronous Receiver Transmitter), opportunamente coadiuvata dal MAX232  per traslare i livelli di tensione. La periferica USART può essere impostata per lavorare in modalità asincrona full duplex (ed è questa la modalità che ovviamente sfrutteremo per la RS232) oppure per lavorare in modalità sincrona half duplex (come master o come slave), questa ultima modalità non la prenderemo in considerazione.

Esistono comunque in giro dei codici scritti in C che permettono di implementare la comunicazione RS232 anche sui picmicro che non hanno a bordo la periferica USART. Conoscendo perfettamente il protocollo di comunicazione è possibile difatti emulare la comunicazione via software.

Ci sono vari registri del picmicro associati all’USART. Analizziamoli per capire come avviene la comunicazione.

Registro TXSTA

comunicazione_rs232_usart_TXSTA

Tale registro si occupa di una parte dei settaggi dell’USART e dello stato della trasmissione. Vediamo che il bit 4 di tale registro, denominato SYNC, se posto a zero ci permette di realizzare la modalità asincrona, realizzando la modalità asincrona avremo che l’I/O RC6 (situato sul pin n°25 del 16F877) sarà il pin  utilizzato dal picmicro per trasmettere i dati e RC7 (pin 26) sarà il pin destinato a riceverli (in modalità sincrona, invece, il primo avrebbe avuto la funzione di clock e il secondo di linea dati).

Il bit TX9 ci permette di selezionare la modalità di trasmissione ad 8 o a 9 bit. La modalità ad 8 bit è generalmente quella più diffusa.

Il bit TXEN abilita la trasmissione.

BRGH abilita (1) l’alta velocità, questo bit deve essere tenuto in considerazione quando successivamente andiamo a scegliere la velocità di trasmissione.

Il bit TRMT serve ad indicarci lo stato dello shift register di trasmissione: quando vogliamo trasmettere un byte, il byte deve essere caricato nel registro chiamato TXREG, il dato quindi passa in automatico da TXREG allo shift register (TSR) e quindi da qui viene trasmesso, quando il dato viene trasmesso, lo shift register si svuota e viene quindi settato ad 1 il bit TRMT. Tale bit comunque non viene quasi mai utilizzato nei programmi.

Abbiamo infine il bit TX9D nel quale dovremo impostare il nono bit di dati qualora avessimo selezionato la trasmissione a 9 bit. Nel caso stiamo realizzando una trasmissione ad 8 bit, tale bit può essere utilizzato per inviare il bit di parità, ma non ce ne occuperemo.

Registro RCSTA

Tale registro si occupa di un’altra parte del settaggio dell’ USART e dello stato relativo alla ricezione. Per non dilungarmi troppo, dirò che di tale registro ci interessano principalmente i bit:

SPEN, che abilita (1) appunto l’utilizzo del modulo USART, configurando i pin RC6 e RC7 come destinati all’utilizzo dell’USART (dovremo comunque impostare queste due porte anche come ingressi agendo sul registro tristato).

RX9, che abilita la ricezione a 9 bit.

CREN, che abilita la ricezione continua dei dati.

RX9D, nono bit di dati ricevuto eventualmente lo volessimo utilizzare.

Selezionare il Baud Rate

Il baud rate, la velocità di trasmissione, è in funzione del quarzo utilizzato per il clock di sistema, del bit BRGH e del valore caricato nel registro SPBRG. Il suo valore può essere calcolato con le formule fornite sul datasheet:

comunicazione_rs232_usart_calcolo_baudrate

Ovviamente sul picmicro non otterremo mai dei valori di baud rate precisi come quelli impostabili sul computer, ci sarà sempre una certa percentuale di errore, sul datasheet si consiglia comunque di selezionare sempre BRGH=1 anche con baudrate bassi in maniera da ottenere un errore inferiore. Alla pagina successiva del datasheet è riportata un’utile tabella con i valori da impostare nel registro SPBRG (valore x della formula vista poco fa) in funzione del bit BRGH e del quarzo utilizzato. Diamo un occhio alla tabella relativa a BRGH=1 :

comunicazione_rs232_usart_calcolo_baudrate_errori

Tale tabella ci fornisce subito i valori di errore rispetto ai valori standard di baud rate. Vediamo subito che utilizzando un quarzo a 20MHz e BRGH=1, i minori valori di errore di ottengono per un baudrate di 9600 e 19200, difatti in genere è sempre a questi due baudrate che si opera con i picmicro, nella colonna affianco possiamo quindi vedere il valore da assegnare al registro SPBRG.

Una volta settati propriamente i registri per lavorare con la seriale, dobbiamo soltanto sapere che per trasmettere un byte basta semplicemente caricarlo nel registro TXREG (basta fare TXREG=valore del byte), finito di trasmettere il byte viene settato il flag di interrupt TXIF, tale interrupt può essere intercettato nella nostra routine ISR abilitando innanzitutto gli interrupt di periferica (oltre all’interrupt generale) e quindi anche l’interrupt di trasmissione seriale (bit TXIE, che non si trova sul registro INTCON ma sul registro PIE1, che è appunto un registro dedicato all’abilitazione degli interrupt delle periferiche). Generalmente non si abilita mai il flag di interrupt su trasmissione seriale ma si controlla semplicemente il bit TXIF (che viene settato comunque) per verificare che la trasmissione precedente sia finita prima di procedere alla trasmissione di un nuovo dato. Il bit TXIF viene azzerato in automatico appena si caricano nuovi dati nel registro di tramissione.

Eventualmente si voglia effettuare una trasmissione a 9 bit, il nono bit va caricato nel bit TX9D prima di caricare TXREG

Quando invece vorremo ricevere un bit, la cosa migliore da fare è sicuramente intercettare l’interrupt di ricezione seriale, che si abilita portando ad 1 il bit RCIE: nell’ISR intercetteremo quindi il flag di avvenuta ricezione seriale, ovvero il bit RCIF. Il dato ricevuto da seriale lo avremo disponibile nel registro RCREG. Il flag di ricezione su seriale, RCIF, viene resettato in automatico appena si effettua la lettura del registro RCREG, per cui non dovremo preoccuparci di resettarlo (anche perchè non si può dal momento che è a sola lettura).

I flag di abilitazione di ricezione e di trasmissione su  seriale, quindi, si trovano nel registro PIE1.

Come vedete, il buffer di ricezione seriale è limitato ad un byte, il che significa che ogni volta che riceviamo un byte, scatta l’interrupt. Se abbiamo bisogno di elaborare più di un byte è necessario dichiarare un array nel quale memorizzare i byte ricevuti incrementando un contatore. Generalmente per semplici applicazioni un byte basta. Ricordo in questa fase che ogni byte è rappresentato da una lettera secondo il codice ascii.

Applicazione pratica

Il circuito utilizzato è il seguente, tenete conto che non è illustrata la parte relativa al circuito di programmazione e reset, se utilizzate la Freedom 2 non dovrete fare nulla:

schema comunicazione rs232come vedete questa volta abbiamo adottato una soluzione circuitale leggermente differente dalle precedenti lezioni: i 4 pulsanti non hanno le resistenze di pullup (verrà sfruttata la funzione delle resistenze di pullup interne) e presentano invece una (piccola) resistenza verso massa: serve ad evitare che possa succedere qualcosa se si premono i pulsanti durante la programmazione, dal momento che BT4 e BT3 si trovano sulle linee di programmazione.

Se utilizzate una breadboard per i vostri esperimenti, o volete avere una interfaccia RS232 a portata di mano potete anche utilizzare l’interfaccia RS232/TTL presentata in questo nostro articolo.

Cenni preliminari sul programma: le funzioni GETCH, PUTCH e PRINTF

Il programma che andremo a caricare sul picmicro svolge le seguenti funzioni: invia un messaggio sulla seriale quando si premono i pulsanti, resta in ascolto sulla seriale per controllare se vengono impartiti i comandi per l’accensione dei led, suona in un modo quando riceve un comando, suona in un altro modo quando riceve un comando che non riconosce.

Per il settaggio dell’usart utilizzeremo una piccola libreria che si trova nella cartella “samples” dell’hitec-c, costituita da due soli files: usart.c e usart.h. Dovremo editare il contenuto di usart.h per impostare la velocità di trasmissione, la frequenza del quarzo espressa in Hertz (seguita dal prefisso L che sta ad indicare che il numero è un intero lungo) e se vogliamo utilizzare o meno il nono bit di dati:

#define BAUD 9600
#define FOSC 20000000L
#define NINE 0

Ho impostato la velocità a 9600 bit al secondo, il quarzo a 20MHz (attenzione agli zeri!) e la comunicazione ad 8 bit. Fatto questo non ci resta che includere “usart.c” nel main.c e quindi richiamare la funzione “init_comms();” nel main.

Fatto questo, all’avvio del programma sul picmicro, l’usart risulta impostato. Nel settings abbiamo abilitato l’interrupt di ricezione su seriale e le resistenze di pullup sulla porta B:

RBPU=0; // attivo le resistenze di pullup su porta B
GIE=1; // gestione globale interrupt attiva
PEIE=1; // interrupt di periferica attivati
RCIE=1; // interrupt di ricezione su seriale attivato

Adesso, ogni volta che riceveremo un byte sulla seriale, scatterà l’interrupt che intercettiamo nell’ISR testando il bit di avvenuta ricezione su seriale (RCIF):

void interrupt isr(void)
	{
	if (RCIF)
		{

Ricordiamoci che tale bit non va azzerato, verrà fatto in automatico appena viene effettuata la lettura del buffer di ricezione. Ok, ma come si fa la lettura? Abbiamo detto che il byte ricevuto si trova nel registro RCREG. Nel file “usart.c” ci sono 3 comode funzioni utili al nostro scopo:

void putch(unsigned char byte) {
/* output one byte */
while(!TXIF)	/* set when register is empty */
	continue;
TXREG = byte;
}
 
unsigned char getch() {
	/* retrieve one byte */
	while(!RCIF)	/* set when register is not empty */
		continue;
	return RCREG;
}
 
unsigned char getche(void) {
	unsigned char c;
	putch(c = getch());
	return c;
}

La funzione getch ci permette di recuperare il byte ricevuto: vediamo che resta in attesa, tramite il while, fino a che il bit RCIF non è settato, restituisce proprio RCREG. Quindi nel momento in cui avremo bisogno di recuperare il byte ricevuto su seriale ci basterà impostare una variabile di tipo char e fare:

variabile=getch();

La funzione putch ci permette invece di trasmettere un byte su seriale, vediamo che resta in attesa fino a quando la trasmissione precedente non è terminata, dopodichè imposta il registro di trasmissione (TXREG) sul valore passato alla funzione.

La funzione getche non fa altro che effettuare l’eco del byte passato restituendolo come valore di ritorno della funzione: in pratica riceve un byte e lo ritrasmette.

La maniera più comoda di inviare un byte, potendolo rappresentare come un carattere ascii, è proprio quella di scrivere un carattere tra singoli apici:

putch('A'); // invio il carattere A
putch(65); // invio il numero 65, è la stessa cosa che inviare il carattere A, dato che il codice ascii di A è 65
putch(0x41); // lo posso pure scrivere in esadecimale
putch(0b01000001); // o in binario

Come vedete è molto semplice, ma se vogliamo inviare un’intera stringa? Una frase per esempio, da poter leggere sulla seriale? Semplice, si ricorre alla funzione “printf”, che fa parte della libreria standard stdio.h inclusa da usart.c. La funzione printf in c è forse una delle più famose: dirige l’output sulla periferica standard di I/O. In questo caso la periferica standard è la porta seriale: printf infatti utilizza la funzione putch per inviare i caratteri. Ulteriori informazioni sulla funzione printf le potete trovare anche su wikipedia.

Quando avremo bisogno di scrivere qualcosa sulla seriale faremo una cosa del tipo:

printf("Ciao mondo!\n\r");

I caratteri \n e \r sono due caratteri particolari che fanno parte di quei gruppi particolari di caratteri chiamati sequenze di escape. In pratica il carattere \n è il carattere (in genere viene identificato più precisamente come carattere di controllo. Anche se non visualizza niente anche lui ha un codice ascii e quindi occupa un byte di dati) nuova linea (Line Feed o LF) e il carattere \r è il ritorno carrello (Carriage Return o CR). In pratica inserendo \n, il cursore andrà sulla linea successiva, ma rimarrà sulla stessa colonna in cui si trovava prima di cambiare linea, il carattere \r, invece, fa ritornare il cursore alla prima colonna, facendolo rimanere sulla stessa linea, il ritorno a capo completo, quindi, è l’effetto di una nuova linea seguito da un ritorno carrello (o anche prima il ritorno carrello e poi la nuova linea).

In realtà questo è vero soltanto per i sistemi windows ed è una cosa ereditata dalle vecchie macchine da scrivere, che avevano due comandi separati per cambiare linea e per andare all’inizio della linea. Nei sistemi unix il ritorno a capo “completo” (nuova riga+inizio riga) viene eseguito unicamente con  con il line feed \n. Nei sistemi MacOs, invece, il ritorno a capo viene eseguito unicamente con il carriage return \r. Per tale motivo avrete notato che aprendo un file di testo creato su Mac o Linux in Windows, non vedrete le linee andare a capo ma tutto si troverà su un’unica riga, mentre il contrario non da problemi.

Il carattere Line Feed rappresenta il codice ASCII n°10 (0×0A). Il carattere Carriage Return è il codice ascii n°13 (0×0D)

Ovviamente a questo punto sarete impazienti di capire come fare a inviare e ricevere comandi da seriale lato pc.

Hyperterminal

Windows ha un programma chiamato Hyperterminal che ci permette appunto, tra le altre cose, di comunicare con la porta seriale. Su windows XP si trova in Start -> Programmi -> Accessori -> Comunicazioni -> Hyperterminal (cliccate sull’icona del programma e non sulla cartella dal nome hyperterminal!).

Su alcune versioni di Windows tale programma non è presente, oppure lo è nella cartella Programmi\Windows NT\hypertrm.exe ma non è presente il link nel menù Start.

Chi non ha Hyperterminal, oppure utilizza Windows Vista (che non ce l’ha proprio in nessuna versione), può fare riferimento a questo articolo dove vengono illustrate soluzioni alternative ad Hyperterminal, fate riferimento ai siti ufficiali per conoscere il funzionamento di questi altri programmi.

Una volta avviato Hyperterminal si presenta la seguente finestra:

comunicazione_rs232_hyperterminal

Digitiamo un nome da dare alla connessione che stiamo per realizzare e premiamo OK. Si presenta un’altra finestra in cui nel campo “connetti” dobbiamo selezionare la porta seriale (la porta COM) che intendiamo utilizzare per gli esperimenti, con un PC fisso con un’unica seriale o con un portatile con scheda PCMCIA, dovrebbe apparire unicamente COM1, quando invece si utilizza un adattatore USB/RS232 il numero della porta COM varia a seconda della porta USB alla quale è stato collegato (ma comunque non può mai essere COM1 o COM2).

comunicazione_rs232_usart_hyperterminal2

Non spaventatevi se c’è scritto “immettere dettagli per il numero telefonico da comporre”, Hyperterminal difatti serve anche a connettersi in remoto con altri sistemi.

Selezioniamo la porta seriale giusta e premiamo ok, si presenta la seguente finestra:

comunicazione_rs232_usart_hyperterminal3

Per il nostro esempio imposteremo i parametri come illustrato nell’immagine e premiamo OK.

Ci troveremo di fronte una finestra bianca vuota: tenendo la finestra in primo piano e premendo i tasti sulla tastiera, verranno inviati i byte relativi ai tasti premuti sul pin TX della porta seriale. Premendo ad esempio la lettera A maiuscola verrà inviato un byte il cui valore sarà 65 e così via secondo la tabella ascii. Ovviamente premendo i tasti in questa fase, non vedremo niente a video: nella finestra del terminale, infatti, devono apparire unicamente i byte ricevuti sul pin RX della seriale, che in questo momento non è collegato a niente.

Potete fare una prova collegando insieme con uno spezzone di filo i pin 2 e 3 della porta seriale: premendo i tasti, vedremo apparire le lettere corrispondenti nel monitor: questo perchè inviamo il byte sul pin TX e viene ricevuto sull’RX della stessa porta, è una prova stupida sicuramente ma spesso serve a diagnosticare eventuali problemi sulla porta seriale (Vi ho svelato un altro dei miei trucchi!).

Nella finestra di hyperterminal abbiamo due tasti in cima (li ho evidenziati in rosso) col disegno di un telefono:

comunicazione_rs232_hyperterminal4

Il tasto attivo nell’immagine, serve per “riagganciare” : hyperterminal smetterà di monitorare la seriale e si attiverà l’altro tasto con la forma di un telefono a riposo. Premendo questo tasto hyperterminal ricomincerà a monitorare la seriale. Chiudendo Hyperterminal apparirà una finestra che ci permetterà di salvare la sessione: in pratica verranno salvate tutte le impostazioni come le abbiamo definite nella fase iniziale (porta com, baud rate ecc). La volta successiva, anzichè aprire hyperterminal programma, possiamo dare un’occhio alla cartella Hyperterminal (quella che prima ho detto di non cliccare nel menù start): qui ci saranno le sessioni salvate.

Descrizione del programma

Capito come si fa a dialogare con la seriale lato picmicro e lato pc, possiamo passare a descrivere il funzionamento  del programma. All’avvio viene inviata una stringa verso il pc per segnalare che tutto funziona correttamente.

Il programma cicla di continuo per verificare la pressione dei pulsanti: la pressione di un pulsante stampa a video una stringa che indica quale pulsante è stato premuto. Fin qui il funzionamento dovrebbe essere abbastanza chiaro leggendo il codice.

Faccio quindi uso di 3 flag per eseguire routine più “faticose” che non conviene far eseguire nell’ISR, che come detto sempre deve rimanere il più snello possibile:

bit ledmode; // flag per capire se siamo in modalità di accensione dei led
bit statusmode; // flag per capire se dobbiamo stampare a video lo stato dei led
bit errormode; // flag per indicare che abbiamo inviato un comando non riconosciuto
bit okmode; // flag per indicare che abbiamo inviato un comando riconosciuto

Questi flag vengono settati nell’ISR e verificati nel main (tranne il flag ledmode) per attivare le corrispondenti funzioni.

Il flag errormode viene settato per far suonare il cicalino in maniera più “sottile” a segnalare un comando non riconosciuto, il flag okmode viene invece settato per far suonare il cicalino con una tonalità più marcata ad indicare che il comando è stato riconosciuto.

Il flag statusmode viene settato quando da terminale si preme la lettera S maiuscola o minuscola (eh si, se non voglio creare confusione devo controllare sia la maiuscola che la minuscola dal momento che hanno codici ascii differenti):

// premuto S maiuscola o minuscola
case 'S':
case 's':
statusmode=1;
okmode=1;
break;

Questa condizione è verificata in uno switch nell’ISR determinato dal byte ricevuto: se viene ricevuto un byte corrispondente alla lettera S o alla lettera s, allora setto il flag statusmode che mi attiva nel main una routine che stampa a video lo stato dei led:

comunicazione_rs232_usart_esempio01

Il flag ledmode viene attivato alla pressione del tasto L o l (elle minuscola), questo cambia il comportamento dell’ISR: non verrà più verificata la pressione di S o L ma si attiva un’altra routine che  si aspetta la pressione di altri tasti. Viene inoltre stampata a video una stringa che ci ricorda cosa si aspetta adesso il programma:

comunicazione_rs232_usart_esempio02

Bisogna quindi premere un numero da 0 a 4: la pressione dello zero effettua lo spegnimento dei 4 led, la pressione di un numero da 1 a 4 inverte lo stato del led corrispondente. Se si preme un tasto diverso da quelli elencati nella condizione switch, si esce da questa routine e il cicalino suona l’errore. Altrimenti viene stampato “ok” a video e lo stato del led viene invertito.

Tutto questo avviene perchè l’ISR è strutturato in questo modo:

void interrupt isr(void)
 {
 if (RCIF) // abbiamo ricevuto un byte sulla seriale?
   {
   input = getch(); // recupero carattere ricevuto
 
    if (ledmode)
     {
     switch(input)
       {
       //... VARIE CONDIZIONI
       default: // NESSUNA DELLE CONDIZIONI PRECEDENTI
       errormode=1; // segnalo che non è stato premuto un numero di quelli che mi servivano
       break;
       }
     ledmode=0; // esco dalla modalità ledmode
     }
 else // altrimenti non mi trovo in modalità ledmode
  {
  switch(input)
   {
   //... VARIE CONDIZIONI
 
   // premuto un altro carattere che non è né L né S
   default:
   errormode=1; // segnalo che il comando inviato non è  riconosciuto
   break;
   }
  }
 }
}

Leggete il programma per capirne meglio il funzionamento. Come potrete vedere, e come ho spiegato anche in altre occasioni, nell’ISR cerco di eseguire meno compiti possibile: se devo eseguire qualcosa di laborioso mi setto un flag che verrà poi controllato nel main, ovviamente tale flag dovrà essere poi resettato nella stessa routine che lo verifica. L’unico flag che non verifico nel main è appunto ledmode, primo perchè mi deve cambiare il comportamento dell’ISR e quindi necessariamente lo devo verificare qui, e poi perchè non deve eseguire un compito particolarmente gravoso dovendo invertire unicamente un’uscita.

Ovviamente pensate se al posto dei led mettete dei relè e se al posto di hyperterminal vi scrivete un vostro software personalizzato per dialogare con la scheda. Come vedete i meccanismi che stanno alla base di alcuni prodotti commerciali e industriali non sono poi così impossibili da realizzare. Comunicare con la RS232 è una cosa semplicissima come avete visto, e vi permette di creare delle belle cose permettendo al computer di interagire con la vostra elettronica.

File di supporto alla decima lezione del corso di programmazione picmicro in C (611)

Datasheet MAX232 e altri driver RS232 (594)

Articoli che potrebbero interessarti

L'articolo ti è piaciuto o ti è stato utile per risolvere un problema? Supporta e mantieni in vita questo sito, ci basta soltanto un caffè o una birra.
Se desiderate che settorezero continui a rimanere gratuito e fruibile da tutti, non copiate il nostro materiale e segnalateci se qualcuno lo fa

Puoi lasciare un commento, o un trackback dal tuo sito.

  1. #1 da Giorgio il 20 gennaio 2010

    Bel lavoro. Dopo questa fatica una birra ci vuole!

  2. #2 da S.D.R. il 20 gennaio 2010

    Ciao Gianni ,
    penso che dopo il proggettino dell’orologio mi metterò a fare qualche esperimento con la seriale usando LabView , è da molto tempo che volevo farlo , e grazie a te finalmente forse ci riuscirò . :-)

  3. #3 da Akuryu il 29 gennaio 2010

    Ciao Gianni come al solito lavoro superbo, una sola domanda, se si ritiene di dover fare un sistema unidirezionale. Si potrebbero semplicemente usare solo 2 fili esatto ? E se volessimo usare sempre e solo due fili anche per un sistema bidirezionale, c’è il modo ?

    • #4 da Giovanni Bernardo il 29 gennaio 2010

      Se vuoi ottenere che c’è comunicazione solo in un verso (es.: pc invia i dati al picmicro ma non viceversa o tutto il contrario) bastano si solo due fili: massa e trasmissione (o massa e ricezione: dipende da quale punto stai guardando). Se invece vuoi ottenere un sistema bidirezionale ma usando solo due fili (cioè massa+segnale) penso non sia possibile con le periferiche già integrate: devi inventarti tu un protocollo. Gli altri protocolli usati sui picmicro sono l’I2C (che è half duplex ma ha bisogno, oltre della massa e del segnale, anche della linea di clock), o l’SPI (full duplex ma ha bisogno, oltre della massa, di clock, tx e rx e a volte anche di un altro filo ancora per selezionare il dispositivo). Esistono sistemi bidirezionali con solo massa e filo di segnale, come il protocollo 1-Wire della Dallas (quello che usano le sonde di temperatura DS1820) ma lo devi implementare tu via software. La DS1820, infatti, comunica usando solo massa e segnale, l’alimentazione può prelevarla in modalità “parassita” caricando un condensatore direttamente dalla linea dati. Avendo solo due fili (segnale + massa) il sistema deve per forza di cose essere half duplex (comunica un dispositivo per volta), ci vuole un dispositivo master che avvia la comunicazione e c’è bisogno che la velocità di trasmissione sia nota ad entrambi i dispositivi perchè non possiamo mettere una linea di clock… mi viene in mente solo l’1-wire della Dallas…

  4. #5 da Luca il 14 marzo 2010

    Compilando… “cgpic.exe ha smesso di funzionare” => “ok” => ********** Build failed! ********** ! Ma comee?
    E’ tutto sbucato fuori mentre adattavo i tuoi sorgenti, e precisamente dopo tale modifica:

    #if defined(_16F87) || defined(_16F88) //Routine per 16f877a!!!
    #define RX_PIN TRISB2
    #define TX_PIN TRISB5
    #else
    #define RX_PIN TRISB1 //Ho modificato qui per adattarlo al 628a!
    #define TX_PIN TRISB2
    #endif

    wtf?!?! ..direbbe qualche americano medio..

    (Stavolta, avendo utilizzato le porta ho aggiunto la tua dritta: “CMCON=0b00000111;” staremo a vedere se funge)

    Comunque tanto per commentare, ho acquistato un convertitore usb\rs232 di quelli cinesissimi, eppure almeno per il momento, dopo aver caricato hyperterminal su vista secondo le dritte di questo articolo (http://www.techbug.com/en/?p=184) e incrociati i pin 2 e 3, ho la conferma!

    • #6 da Giovanni Bernardo il 14 marzo 2010

      Non penso proprio il problema che “cgpic.exe ha smesso di funzionare” derivi dall’adattamento del codice, se il codice è adattato male c’è un build failed ma non certo si incastra l’eseguibile. Il build failed che ottieni dopo deriva dal fatto che cgpic.exe si è autoterminato, ma non dipende dal codice sorgente.

  5. #7 da Luca il 14 marzo 2010

    Si ma altrimenti mi funziona benissimo…cioè sugli altri sorgenti funziona a dovere…riscontro problemi anche a compilare quelli allegati a questa lezione, ne deduco sia un problema di installazione. Ora provo a reinstallarlo.

  6. #8 da Luca il 14 marzo 2010

    Niente da fare, installato anche in versione PRO stavolta, diverso installer, riavviato, niente di niente. come se avesse problemi con i file usart.c ed .h . D’altronde compila di tutto, tranne il mio ed il tuo progetto. :S qualche idea?

  7. #10 da Luca il 16 marzo 2010

    Ho provato addirittura su un’altro PC…stesso problema! Ma solo a me dà questo problema solo con questo programma? Agli altri tutto ok?

  8. #13 da Luca il 16 marzo 2010

    L’esempio l’ho scaricato, compilato e ricompilato per l’877a ma nada.
    Comunque a mio dispiacere uso MPLAB IDE v8.46 + HI-TECH PICC PRO 9.70
    Quel file indicato ha un link rotto, ho installato una versione successiva ma addirittura quando apro mplab (dopo lo splash) dà lo stesso errore ancor prima di fare “Project Wizard”! Sto cercando una versione più nuova, ti aggiornerò a breve.

  9. #14 da Luca il 16 marzo 2010

    Niente da fare, nemmeno l’ultima versione scaricata da qui: http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en542849 (link diretto: http://www.microchip.com/Microchip.WWW.SecureSoftwareList/secsoftwaredownload.aspx?device=en542849&lang=en&ReturnURL=http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en542849# ). Sempre lo stesso dannato problema, mi chiedo quelle versioni indicate nel forum che mi hai linkato da dove le abbiano prese…

  10. #15 da Luca il 18 marzo 2010

    Tu che versione usi del compilatore? Posso inviarti i sorgenti così confermiamo questo problema del compilatore se magari provi tu a compilarlo?
    Grazie ancora
    L.

    • #16 da Giovanni Bernardo il 18 marzo 2010

      Hai ragione tu… Uso generalmente due computer, uno con su installato Hitec 9.70 : qui crasha cgpic.exe quando vado a compilare l’esempio della rs232, l’altro con Hitec 9.65 non da problemi. E’ chiaro che si tratta di un bug del programma, che a quanto pare è stato già segnalato… Dobbiamo solo sperare che lo risolvono al più presto… Nel frattempo se riusciamo a capire qual è la parte di codice che lo manda in crisi vediamo di rimediare e soprattutto segnalarlo in maniera che abbiano informazioni più precise per poter correggere questo errore. Nel frattempo consiglio di usare l’hitech 9.65 sperando si trovi ancora… Io a quanto pare non ho copie della vecchia installazione, si potrebbe provare a sostituire solo cgpic.exe… faccio qualche prova e ti faccio sapere.

    • #17 da Giovanni Bernardo il 18 marzo 2010

      Difatti come si legge in quel link che ti ho indicato, alcuni ci sono andati proprio male dal momento che hanno acquistato la licenza (che costa un botto) e pure da questo errore, dicono che l’Hitec gli ha detto di provare l’ultima release candidate della 9.70, c’è un indirizzo ftp da cui scaricare ma non c’è nulla. continuo a cercare

    • #18 da Giovanni Bernardo il 18 marzo 2010

      Sul sito della Microchip è possibile scaricare le vecchie versioni di MPLAB IDE, alla pagina : http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en023073 per una strana curiosità, la versione che utilizzo io senza problemi (la 8.33) non è presente in elenco, ma ho scoperto che in realtà sul server c’è ancora, si sono solo dimenticati di metterla in elenco. La versione 8.33 si può scaricare da questo link:
      http://ww1.microchip.com/downloads/en/DeviceDoc/MPLAB_IDE_8_33.zip (non ci è voluto molto a capirlo modificando il link delle altre versioni).

      MPlab IDE 8.33 ha l’hitec-c versione 9.65 che a me non da problemi.
      Delle versioni precedenti alla 8.46 ho appena provato la 8.43 e ha già Hitec-C 9.70 che da problemi.
      La Versione 8.40 di MPLab ha l’ Hitec-C versione 9.65PL1 … Aggiudicata!

      Installati MPLAB ide 8.40 e nel frattempo attendiamo speranzosi che esca la nuova versione… Il primo che la fiuta fa un fischio!

  11. #19 da Luca il 19 marzo 2010

    Allora, ripetendomi, le tue risposte sono perfette, come sempre!

    Allora, qualche news, ho seguito le tue dritte e con il compilatore 9.65 non crasha più, ora lasciamo perdere che anche da compilato il programma non funge. Comunque programmi molto basilari come quello di cui ti parlerò a momenti vengono compilati dal 9.70, quindi il problema non è nelle usart.x bensì in qualche processo richiamato dal main.

    Insomma ho pensato bene di ripartire daccapo. Ho fatto un circuito molto basilare, ovvero solo il pic e il max232 collegato, ho modificato e compilato l’esempio contenuto nella cartella samples…

    Questo per essere chiari:
    void main(void){
    unsigned char input;

    INTCON=0; // purpose of disabling the interrupts.
    TRISA=0; //nell’originale non erano stati messi…
    TRISB=0;

    init_comms(); // set up the USART – settings defined in usart.h

    // Output a message to prompt the user for a keypress
    printf(“\rPress a key and I will echo it back:\n”);
    RB3=1; //led di conferma
    while(1){
    input = getch(); // read a response from the user
    printf(“\rI detected [%c]“,input); // echo it back
    }

    Ora però, ovviamente il prog non funziona, allora ho pensato di fare qualche verifica, cortocircuitando i piedini RX e TX SUL PIC, ho l’echo automatico su hyperterminal che mi conferma che: 1) il max232 funge, 2) l’adattatore usb\com funge 3) la porta com selezionata è quella e 4) hyperterminal sul pc và bene. Ora però mi stupisco, i settaggi su usart.h sono semplici e pochi, ovvero:

    #define BAUD 9600
    #define FOSC 4000000L
    #define RX_PIN TRISB1 //ho eliminato l’if defined…define… ed inserito queste righe
    #define TX_PIN TRISB2
    #define NINE 0

    Ora mi chiedo, se il programma è così banale, il circuito è quello, mi vien da pensare, per caso sto usando un gatto nero al posto della breadboard oppure il mio pic è qualche scarto di tecnologia aliena non funzionante?

    • #20 da Giovanni Bernardo il 19 marzo 2010

      Potrebbe pure essere la breadboard, in molti hanno questi problemi. Hai incluso stdio ? Prova anche a spostare il circuito su un’altra parte della breadboard. Io comunque dell’adattatore non fiderei tanto, ho capito che funziona se incroci 2 e 3, ma bisogna vedere se funziona quando lo interfacci con i circuiti, non hai la possibilità di provare su un pc fisso che ha la rs232? Scusa se lo ripeto ma con questi cosi ho brutte esperienze. Poi potrebbe essere il quarzo che non oscilla oppure oscilla in maniera anomala messo nella breadboard. E poi: avvia prima hyperterminal, sii sicuro di averlo messo alla stessa velocità di comunicazione che hai messo nel pic (9600), avvia la comunicazione e solo allora accendi il circuito.

  12. #21 da Luca il 20 marzo 2010

    Stdio c’è, ho provato anche sul fisso con com nativa 9600baud e tutte le altre configurazioni, stavolta ho l’echo automatico senza incrociare nulla, e a quanto pare è per via dell’integrato stavolta, l’unico modo per non avere l’echo automatico ce l’ho solo se stacco il max232 (altrmenti ho l’echo sempre, con l’alimentazione o meno con il pic o meno..etc), quindi non è un probl della breadboard. Ho anche messo il quarzo esterno da 20MHz invece di quello interno da 4.

    In ogni caso, non funge.

    • #22 da Giovanni Bernardo il 20 marzo 2010

      Allora hai qualche problema col max, o è guasto o hai fatto male il circuito. Due dei condensatori che vanno sul max vanno montati al contrario (cioè uno ha il positivo a massa e l’altro ha il negativo a +vdd), te lo dico perchè un amico “sapientone”, pensando che il circuito era disegnato in maniera errata, pensò bene di “raddrizzarli”. Se hai sempre l’eco, anche ad alimentazione tolta, c’è qualcosa che mette in comunicazione il 2 col 3 dal lato del max. Ricontrolla con attenzione il circuito facendo pure riferimento al datasheet.

  13. #23 da Luca il 20 marzo 2010

    Ho provato e riprovato mille volte, ho rifatto il circuito rispettando il tuo schema, ho cambiato max232, ho cambiato zona della breadboard…ma niente.
    Il problema sul fisso con com nativa che aveva echo ad ogni tasto era perchè non avevo collegato la massa dati ovvero PIN5 della porta com a massa.
    Collegato questo a massa, ho l’echo solo cortocircuitando i pin 2 e 3 ovvero ricezione e trasmissione della com; ma non ho piu echo se collego i due pin di ricezione e trasmissione del pic.
    Una domanda mi sorge, guardando il datasheet, il pin 2 ed il 6 non devono essere collegati rispettivamente a +10V e -10V ? (nel mio caso di un max232n ,versione equivalente della TI e non della maxim, a +8.5V e -8.5V)

    • #24 da Giovanni Bernardo il 20 marzo 2010

      Il pin 2 va collegato a + 5 volt con il condensatore in mezzo (negativo verso il +5), il pin 6 va a massa con il condensatore in mezzo (positivo verso massa), quelli sono i due pin che realizzano la pompa di carica (se tu avessi a disposizione un’alimentazione duale +10 e -10 V non ci sarebbe più bisogno del max232! è il max che ti crea +10 e -10 a partire da solo +5V, è questa la sua funzione principale). La differenza tra max232 e max232N non esiste, è la TI che mette la N solo per indicare il package, ma sono lo stesso integrato. Utilizza condensatori da almeno 1uF. Colleghi il tutto con un cavetto acquistato? Il collegamento dei fili all’interno del cavetto è giusto? Il max 232 arriva sul connettore DB9 nei punti giusti?

  14. #25 da Luca il 20 marzo 2010

    Si uso com nativa e cavetto acquistato, controllato pin to pin, non essendo null ho invertito sulla breadboard i pin 2 e 3 (ovvero collegandoli in maniera inversa a quella indicata dal tuo schema). I condensatori sono da 1uF comprati proprio per tale uso, e tutti seguono la polarità indicata dallo schema e dal datasheet.
    il max 232 sul connettore db9 e sul 16f628a ha questi collegamenti:
    picrb1(rx):max12
    picrb2(tx):max11
    com3:max14 (simulazione hw cavo null modem)
    com2:max13
    gnd:max5
    i due condensatori di cui parli sopra hanno il suddetto collegamento.

    • #26 da Giovanni Bernardo il 20 marzo 2010

      Adesso non so se il cavo che hai tu è maschio/maschio o maschio/femmina. Hai provato a non invertire il 2 e il 3 ma a rimanerli come nello schema? Non vorrei che ti sei confuso con le piedinature, che per maschio e femmina sono speculari.

  15. #27 da Luca il 20 marzo 2010

    Il cavo è maschio\femmina, comunque io ho un connettore femmina volante a cui ho saldato dei fili volanti con capi stagnati che inserisco direttamente nella breadboard, la cui piedinatura l’ho letta stesso sul connettore dove sono numerati i pin uno ad uno. Comunque, ho notato che cortocircuitando a caso i pin rx e tx del pic, ogni tanto compare a video “I detected [I]” o altri caratteri strani, segno che qualcosa in fondo funziona. Forse per caso essendo il pic un 16f628a c’è qualcosa di incompatibile, ho controllato il calcolo del SBPRG è lo stesso…
    News: così mi compaiono ad ogni reset, però senza accettare comandi da tastiera, “Press a key and I will echo it back:”, premo i tasti e nn succede niente:

    picrb1(rx):max11 //invertiti rispetto al tuo schema
    picrb2(tx):max12
    com2:max14 //senza simulazione hw cavo null modem)
    com3:max13
    Praticamente ho invertito tutto!

    Io mi sto ammattendo, ora stacco, riprenderò domattina, intanto ti ringrazio infinitamente per il supporto.

  16. #28 da Luca il 20 marzo 2010

    Problema risolto, pinning errato… Ora veramente dovrò darmi fuoco! In ogni caso questa immagine è molto illuminante a riguardo, ti consiglio di includerla nella tua guida: http://www.siongboon.com/projects/2006-03-06_serial_communication/max232layout.gif

  17. #29 da lodi12 il 3 agosto 2010

    Ho un problema con la seriale:
    con questo sorgente
    #include
    #define XTAL_FREQ 20MHZ
    #include
    #include “delay.c”
    #include “usart.h”
    #include “usart.c”

    void interrupt ISR(void);
    main()
    {
    //Settaggio porte
    TRISA = 0;
    TRISB = 0b11110000;
    TRISC = 0b11000000;
    TRISD = 0;
    TRISE = 0;
    PORTD = 0;

    //settaggio interrput su seriale e resistenze pull-up pulsanti
    INTCON = 0b11000000;
    INTCON2 = 0b00000000;
    INTCON3 = 0;
    PIE1 = 0b00100000;

    /*
    //settaggio seriale
    TXSTA = 0b00100110;
    RCSTA = 0b10010000;
    BAUDCON = 0b00000010;
    SPBRG = 129; //baud 9600
    */
    init_comms();
    DelayMs(50);
    RD0 = 1;
    while(1)
    {
    if(!RB4)
    {
    DelayMs(100);
    if(!RB4)
    {
    putch(‘A’);
    RD0 = RD0^1;
    }
    }
    RD1 = 1;
    }
    }

    void interrupt ISR(void)
    {
    char valore;
    valore = 0;
    if(RCIF)
    {
    DelayMs(1);
    valore = getch();
    putch(valore);
    RD1 = RD1^1;
    }
    }
    hyperterminal , inviato un byte da pc legge poi ° oppure ç…se invece schiaccio il pulsante mi ritorna x° … help!

  18. #32 da lodi12 il 3 agosto 2010

    dimenticavo uso la freedom 2 con il 18f4550 :)

  19. #33 da doghi81 il 24 settembre 2010

    Ciao, non riesco ad acquisire un intero frame di caratteri inviati sulla seriale.
    Qualche dritta?
    Grazie in anticipo.

    • #34 da Giovanni Bernardo il 24 settembre 2010

      Spiegati meglio

      • #35 da doghi81 il 24 settembre 2010

        Ho fatto diverse prove, dove acquisisco un carattere dalla seriale con un PIC, se il carattere è quello voluto allora accendo un led altrimenti invio un errore sulla seriale, adesso vorrei acquisire una stringa di caratteri inserendola in un array, ma sto riscontrando delle difficolta. In pratica il PIC non risponde più e l’array è sempre vuoto.

        • #36 da Giovanni Bernardo il 24 settembre 2010

          Il buffer di ricezione seriale dei pic16 è di 1 byte, per memorizzare più caratteri ci vuole un array e un counter da usare per il puntatore. Nell’RCIF ti prendi il byte, lo memorizzi in un elemento dell’array (nell’elemento n-esimo) e incrementi un puntatore per la ricezione successiva (n++).

          • #37 da doghi81 il 24 settembre 2010

            Ma se io invio un insieme di caratteri tutti in una volta sulla seriale, in questo modo riesco ad acquisire tutto? Ad esempio con hyperterminal utilizzo il comando invia file di testo con una parola inserita nel file, in questo caso il pic non riesce ad inserire ogni carattere della parola nell’array.
            Non so se sono stato chiaro.

  20. #38 da doghi81 il 24 settembre 2010

    Ecco perfetto, inviando le lettere singolarmente riesco ad inserirle nell’array, il discorso cambia quando invio un comando formato da più caratteri contemporaneamente. Tutto questo lo sto cercando di realizzare per un’applicazione che mi permetta di attivare le uscite utilizzando un protocollo di comunicazione, tipo modbus.

  21. #40 da lodi12 il 25 settembre 2010

    chiedo aiuto prima di rompere in due la freedom visto che ancora non sono riuscito a far funzionare la usart…premesso che uso la freedom e il 18f4550 vorrei chiederti se sono impostati giusti i registri:
    TRISC = 0b11000000;
    TXSTA = 0b00100100;
    RCSTA = 0b10010000;
    BAUDCON = 0;
    SPBRG = 129; //baud 9600

  22. #41 da lodi12 il 25 settembre 2010

    aggiungo che per evitare problemi con il max232 ho attaccato RC7 e RC6 al pickit2 e uso l’USART tool!

    • #42 da Giovanni Bernardo il 25 settembre 2010

      Dato che stai usando un pic18 posso solo consigliarti di leggerti il tutorial di Mauro Laurenti sui pic18, e comunque sia di sicuro non dipende assolutamente dall freedomII. Se stai usando l’hitec-c che uso io, con il pic18, il problema potrebbe stare proprio li. In particolare fin’ora le versioni superiori alla 9.40 a me non lavorano bene con l’usart.

  23. #43 da doghi81 il 3 ottobre 2010

    Ciao, rieccomi, sono riuscito a far acquisire al PIC tutto il frame di dati che arrivano dalla seriale, quindi sono riuscito a svilluppare un protocollo (Modbus) per accendere e spegnere dei led collegati alle uscite del PIC, adesso vorrei utilizzare la rs485 per poter gestire dispositivi a maggiori distanze, sai darmi qualche dritta in merito?
    Grazie anticipatamente!

    • #44 da Giovanni Bernardo il 3 ottobre 2010

      Con la RS485 ti basta un semplice convertitore, al quale però devi inviare pure un segnale di abilitazione, quindi ti servirà un altro pin del pic: in pratica il dispositivo che trasmette su RS485 deve occupare la linea inviando questo segnale. Poi il funzionamento è uguale a quello della 232 tranne che per la parte fisica. Inoltre sulla RS485 si utilizzano in genere anche sistemi di codifica che permettono anche l’indirizzamento delle periferiche che devono ricevere il segnale.
      Documentati sull’RS485:
      http://www.vincenzov.net/tutorial/rs485/rs485.htm
      potrebbe esserti utile una basetta del genere:
      http://www.robot-italy.com/product_info.php?products_id=1472

      in pratica li ci colleghi la tua linea RS232 a livelli TTL (in uscita dal pic), più un pin che usi come abilitazione (TXen) e dal connettore a vite ti esce il segnale RS485 che devi collegare ad una scheda uguale. Studiati per bene come funziona la RS485 (temporizzazione soprattutto del segnale TXen, resistenze di terminazione e resistenze di polarizzazione). E’ piu semplice di quello che pensi.

      • #45 da doghi81 il 3 ottobre 2010

        Cosa intendi per sistemi di cofica sull’indirizzamento delle periferiche?

        • #46 da Giovanni Bernardo il 3 ottobre 2010

          La RS485 è pensata, oltre che per le lunghe distanze, per poterci collegare su piu dispositivi, a differenza di solo 2 come sulla RS232. Quindi se sul bus 485 hai da 3 dispositivi a salire, è ovvio che chi trasmette deve in qualche modo far capire a chi è indirizzata la trasmissione. E questo si fa aggiungendo ulteriori informazioni al pacchetto che intendi trasmettere (indirizzo della periferica che deve ricevere). Se sul bus hai solo 2 periferiche, non ti serve e quindi sfrutti la 485 solo per la sua caratteristica di essere immune ai disturbi su lunghe distanze.

          • #47 da doghi81 il 3 ottobre 2010

            OK a questo avevo già pensato tramite il protocollo, mentre per quanto riguarda il Txen, cosa sai dirmi in merito?
            Ciao.

  24. #48 da lodi12 il 3 ottobre 2010

    Funziona!!!Con il C18 funziona!! mi sa che invece il max 232 è andato perchè riesco a comunicare con pickit2+uart tool ma non su seriale “pura”…urge un max nuovo :D

  25. #49 da lodi12 il 3 ottobre 2010

    …senza parole…do solo un consiglio…se lavorate con l’USART siate sicuri che lo zoccolo del max 232 non sia vuoto ed il max non sia ad attendervi sulla scrivania…che pollo :D ora funziona tutto!

  26. #50 da odessos il 24 ottobre 2010

    E’ forse troppo grande il main sorgente di questo corso?
    il compilatore MPLAB IDE in versione lite non lo compila.

    • #51 da Giovanni Bernardo il 24 ottobre 2010

      Ho specificato, nelle prime lezioni, che utilizzo il compilatore in versione LITE, e quindi è così anche per questo programma. Un programma così piccolo poi… sarebbe compilato pure con una versione super-super-lite. Ovviamente se non dici l’errore che viene restituito nessuno potrà mai aiutarti. Guardando nella mia sfera magica potrei dirti di provare a installare una versione di MPLAB precedente, in particolare la 8.40, dal momento che le successive presentavano problemi con la compilazione dei programmi utilizzanti l’UART, argomento di cui abbiamo già abbondantemente discusso.

  27. #52 da Stefano_triv il 26 novembre 2010

    Salve ho programmato il pic16f877a per farlo comunicare con il pc tramite rs232. Ho una Fosc di 8 Mhz e necessito di una comunicazione asincrona a 9600. Quale valore devo assegnare allo SPBRG?

  28. #54 da damiano il 26 dicembre 2010

    buon giorno giovanni, volevo avere delle delucidazioni,
    vorrei realizzare un dispositivo con il pic 16f877, che deve ricevere , trasmettere e memorizzare dei messaggi midi. in particolare note midi e control change.

    per ricevere e trasmettere, i messaggi midi, posso tranquillamente ricevere e trasmettere messaggi midi tramite la USART??
    ci pensa direttamente la usart, a inserire i bit di start e di stop a contorno dei 8 bit di messaggio?

    in un secondo momento volevo anche salvare dei dati tramite in una ” serial data flash memory”, in modo da salvare comodamente dei dati in memoria non volatile, ad esempio questa: http://docs-europe.electrocomponents.com/webdocs/0dc4/0900766b80dc457a.pdf

    ho notato che sia che il pic sia la flash sono compatibili con questo standard: MASTER SYNCHRONOUS
    SERIAL PORT (MSSP), potresti darmi delle spiegazioni su come usare questo standar sul pic ???

    ti ringrazio buone feste
    damiano

    • #55 da Giovanni Bernardo il 26 dicembre 2010

      Il protocollo MIDI non l’ho mai utilizzato e non so se lo puoi implementare con l’UART. Io mi studierei prima come trasmette i dati e poi fare delle considerazioni.

      Quella memoria è una eeprom SPI, equivalente alle 25xx prodotte da microchip, quindi devi utilizzare la periferica MSSP impostata per lavorare come SPI, ma spiegare per commento come si fa è troppo lungo. Cerca delle librerie per la funzione SPI con google.

      • #56 da damosound il 26 dicembre 2010

        ti ringrazio giovanni, ………..un altra cosa, vorrei inserire delle variabili, tipo char( registro a d 8 bit), in modo da integrare facilmente il registro, ma mi servirebbe anche settare i singoli bit di codesto registro, come faccio a implementare il fatto di settare o resettare alcuni dei singoli bit del registro?? MEGLIO SE, con l’ausilio di label?????
        ….per farti capire meglio: più o meno come si fa per le porte A e B del pic, si può incrementare e/o decrementare il registro intero, oppure settare il singolo bit ( ES: RB0=1)
        come si fa???

  29. #59 da Cosimo il 14 febbraio 2011

    Ragazzi ho questo codice come faccio a stampare a video? Il debugger compila ma non stampa nulla a video. Grazie

    #include
    #include

    // Configuration Bit settings
    // SYSCLK = 80 MHz (8MHz Crystal/ FPLLIDIV * FPLLMUL / FPLLODIV)
    // PBCLK = 40 MHz
    // Primary Osc w/PLL (XT+,HS+,EC+PLL)
    // WDT OFF
    // Other options are don’t care
    //
    #pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1, FWDTEN = OFF
    #pragma config POSCMOD = HS, FNOSC = PRIPLL, FPBDIV = DIV_1

    #define SYS_FREQ (80000000L)

    #define DESIRED_BAUDRATE (9600) // The desired BaudRate

    int main(void)
    {
    int pbClk;
    unsigned char data;

    // Configure the device for maximum performance but do not change the PBDIV
    // Given the options, this function will change the flash wait states, RAM
    // wait state and enable prefetch cache but will not change the PBDIV.
    // The PBDIV value is already set via the pragma FPBDIV option above..
    pbClk=SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);

    // Open UART2 with Receive and Transmitter enable.
    OpenUART2(UART_EN, UART_RX_ENABLE | UART_TX_ENABLE, pbClk/16/DESIRED_BAUDRATE-1); // calculate actual BAUD generate value.

    mPORTAClearBits(BIT_7); // Turn off RA7 on startup.
    mPORTASetPinsDigitalOut(BIT_7); // Make RA7 as output.

    putsUART2(“*** UART Simple Application Example ***\r\n”);
    putsUART2(“*** Type some characters and observe echo and RA7 LED toggle ***\r\n”);

    while(1)
    {
    while(!DataRdyUART2()); /* Wait for data in the UARTRx. */

    data = (char)ReadUART2(); /* Read data from Rx. */

    mPORTAToggleBits(BIT_7);

    while(BusyUART2()); /* Wait till the UART transmitter is free. */
    putcUART2(data); /* Write data into Tx. */
    printf(“data\r\n”, data);

    };

    return 0;

    }

  30. #60 da Nany_J il 14 febbraio 2011

    Prima di tutto vorrei precisare che sono novizio in questo ambiente.
    Mi piacerebbe diventare un utente HiTech e ho bisogno di aiuto.

    Ora il mio problema:
    Vorrei scrivere un programma che riceve i dati dal GPS in formato seriale asincrona, pero NON attraverso i pin dedicati RX / TX, perché già utilizzati, ma con qualsiasi altra porta libera.
    La comunicazione dovrebbe essere al 38400 dbaud ed il uC utilizzato e il PIC18F4620.

    Potete indicarmi i primi passi per trovare una soluzione per il mio problema?
    Grazie.

  31. #62 da Cosimo il 16 febbraio 2011

    Giovanni come faccio? E’ la prima volta che uso i PIC

  32. #63 da peppino53 il 7 aprile 2011

    Ciao Giovanni, complimenti per la professionalità e la disponibilità.
    ho un compilatore Hitech 9.71a.
    Quando provo a compilare il sorgente allegato alla lez.10 per l’utilizzo della RS232 mi dà errore:
    undefined identifier “TXIF”
    undefined identifier “TXREG”
    undefined identifier “RCIF”
    undefined identifier “RCREG”
    devo cambiare versione del compilatore? o altro?
    Ti ringrazio in anticipo
    giuseppe

  33. #65 da peppino53 il 8 aprile 2011

    Ho inserito il file pic.h della cartella include del compilatore 9.71a e non ho mai avuto problemi. Visto che ci sono varie versioni del compilatore, quale mi consigli?

    • #66 da Giovanni Bernardo il 8 aprile 2011

      Se non trova quei nomi mnemonici i problemi possono essere tanti: sono sbagliati i percorsi al compilatore, hai fatto il progetto per un pic diverso che non ha quei nomi, i nomi sono cambiati, i nomi non sono quelli corretti, hai incluso pic.h DOPO aver scritto la word di configurazione…

  34. #67 da peppino53 il 8 aprile 2011

    ho tentato di compilare il tuo sorgente senza cambiare nulla.
    ciao peppino53

    • #68 da Giovanni Bernardo il 8 aprile 2011

      L’errore è chiaro e lampante: non riconosce quei nomi mnemnonici. Ora se il file header del pic che stai usando ha quei nomi in elenco, vuol dire che il file h non viene incluso, se invece il file header del pic non ha quei nomi è chiaro l’errore e basta modificare per riflettere i nomi che ci sono.

  35. #69 da peppino53 il 8 aprile 2011

    Caro giovanni, ho risolto:
    nel primo tentativo di compilazione nella fase project wizard io aggiungevo nel progetto, oltre al main
    anche tutti gli altri files presenti nella cartella sorgenti con i risultati che già ti ho indicato.
    inserendo solo il main invece mi dà build successfull.
    Devo confessare che questa fase della programmazione non mi era e non mi è ancora chiara.
    Se mi puoi indicare qualche articolo per chiarirmi le idee te ne sarei grato.
    grazie e cordiali saluti
    giuseppe

    • #70 da Giovanni Bernardo il 9 aprile 2011

      Io questo l’ho specificato chiaramente nelle prime parti della lezione: includere solo e soltanto il main, gli altri file andranno inclusi usando le direttive “include”. Punto. L’Hitech-C ha un comportamento assurdo su questo punto, lo so, ma io non posso farci niente. Il C18 invece puoi includere lo stesso file pure 100 volte sia da file che da progetto che non ti dice nulla.

  36. #71 da peppino53 il 9 aprile 2011

    infatti, sono andato a rivedere la lez.3 e ho notato che tu hai aggiunto solo il main sottolineando di aggiungere solo il main; ho riprovato ed è andato tutto ok . di nuovo grazie .
    peppino53

  37. #72 da a.screm il 23 aprile 2011

    Ciao Giovanni,

    La comunicazione seriale tra MCU e PC e’ un tema molto interessante,
    peccato che ultimamente sono pochi i pc dotati di tale porta (come il mio).
    Googolando un po in rete in cerca di una interfaccia USB con chip FTDI
    ho trovato un programmino interessante che promette di utilizzare
    il PICKit2 come interfaccia seriale TTL (sembra credibile avendo alsuo interno un PIC18xx).

    Il programma sfrutta due porte seriali virtuali collegate in bridge,
    utilizzandone una attraverso il programma PK2USB2UART
    che comunica con il pickit2 e l’altra con hyperterminal o simili.

    Intallato tutto e testato, funziona al 50 % , il pic comunica bene ma non riceve.

    Purtroppo non ho un un oscilloscopio per fare delle prove, ed ho il sospetto che i segnali
    inviati dal pickit2 siano un po bassi, ma non posso esserne certo.

    Credo che possa essere uno spunto interessante per approfondire.

    Ti allego il link.
    Using the PICKit2 as an USB to serial converter
    http://pickit2.isgreat.org/using-the-pickit2-as-an-usb-to-serial-converter/

    Ciao

    Alessandro

    • #73 da Giovanni Bernardo il 23 aprile 2011

      Non penso assolutamente che i livelli siano troppo bassi. Sarebbe semplicemente assurdo. Hai provato ad usare l’uart tool del pickit?

      • #74 da a.screm il 23 aprile 2011

        Non avevo notato l’uart tool presente nel sw del pickit.
        Grazie al tuo suggerimento ho letto le istruzioni del pdf della Microchip, e ho capito dove stava
        il problema…
        Cioe’ occorre collegare oltre il vss anche il vdd.
        Pero il uart tool del pickit non riceve correttamente il newline.
        a differerenza del PK2USB2UART che invece adesso funziona bene.
        Tra l’altro, permette attraverso le seriali in bridge, di usare la cumunicazione seriale
        cun qualsiasi programma adatto allo scopo.

        Grazie mille
        Alessandro

      • #75 da a.screm il 23 aprile 2011

        Scusa, ancora una domanda se posso.

        Utilizzando la cununicazione seriale senza il max232,
        quando non collego il pickit al mio circuito.il pin RX rimane in stato indeterminto e riceve segnali assurdi.

        Secondo te e’ necessario mettere una resistenza di pull-up al pin RX del pic
        per tenerlo allo stato alto quando non c’e’ il collegamento seriale?

        Ciao
        Alessandro

  38. #77 da nero77 il 15 maggio 2011

    ciao, grazie per la lezione. una domandina, ho un portatile con porta femmina DB25; c’è qualche indicazione particolare per creare un cavo DB25maschio-DB9maschio da collegare tra pc e dispositivo?

  39. #79 da Haru il 13 luglio 2011

    Se dovessi creare un programma lato PC per inviare e ricevere dati automaticamente con interfaccia grafica, cosa mi consigli?

    Per creare programmi finora mi son basato su Multimedia Builder, comodo perchè ha un suo scripting semplice ed è totalmente visuale, però non sembra avere il supporto hardware per porte ed altro.

    Per questo sto cercando un qualcosa di visuale facile da imparare… voci danno il visual basic come il più semplice, però è comunque un’altro linguaggio di programmazione diverso dal C.

    • #80 da Giovanni Bernardo il 13 luglio 2011

      Il Visual Basic.NET è orientato agli oggetti ed è molto simile al C#. Se ti piace il C puoi provare con il C#. I programmi scritti in vb.net possono essere convertiti in C# e viceversa. Fanno le stesse cose, cambia solo lo stile di programmazione. Altrimenti potresti provare Processing, almeno sei sicuro che il programma puo girare anche su altri sistemi operativi

  40. #81 da Manuel Colus il 15 luglio 2011

    Non mi è chiara una cosa:mi sto calcolando il valore di SPBRG utilizzando le formule presenti nel datasheet del mio pic, e facendo i calcoli in alcuni baud rate ottengo una percentuale di errore negativa (es. -0,16). in questo caso una percentuale di errore NEGATIVA(quindi inferiore a zero) è cosa positiva o meno? all’atto pratico la domanda è la seguente: devo scegliere un baud rate che abbia una percentuale di errore quanto più vicina allo zero assoluto o un baud rate che abbia una percentuale di errore più bassa possibile(in questo caso un valore negativo è inferiore allo zero)?

    • #82 da Giovanni Bernardo il 16 luglio 2011

      Dovrebbe essere normale, nel senso che hai un baudrate minore di quello che dovresti avere. In ogni caso è importante avvicinarsi allo zero quanto piu possibile, da un senso o dall’altro.

  41. #83 da Manuel Colus il 21 luglio 2011

    Altra domanda leggermente OT poiché riferita ad un pic 18.

    Sto tentando di far funzionare l’EUSART di un pic 18f4685 ma al momento senza successo e non riesco a capire dove sia il problema…
    Preciso che utilizzo il compilatore hi tech c18 e le prove le faccio con l’UART TOOL del pickit 2.
    Nel codice Imposto l’usart utilizzando la libreria interna(ho provato anche a impostare manulamente i registri e non è cambiato niente) dell’hitech “usart.h”.
    nelle impostazioni ho: gli interrupt in ricezione e trasmissione disattivati, modalità Asincrona, 8 bit, ricezione continua, brgh=1, SPBRG=207(lavoro a 32 Mhz e a 9600 baud ho un errore del 0,15%).
    Il problema è che quando invio un carattere(qualunque esso sia) sulla usart, ricevo caratteri errati(solitamente 0×80 e 0xF8).

    Qualche idea di quale possa essere il problema?

    qui il codice:

    #include
    #include
    void main (void)
    {
    //imposto l’oscillatore
    OSCCON = 0b01110000;
    OSCTUNE = 0b01000000;

    //imposto i registri latch
    LATA=0;
    LATB=0;
    LATC=0;
    LATD=0;
    LATE=0;

    //Disattivo l’A/D
    ADON = 0;

    //imposto le porte dell’A/D(tutti ingressi I/O)
    ADCON1 = 0b00001111;

    //imposto il comparatore(comparatore spento)
    CMCON = 0b00000111;

    //imposto i registri tristato(tutte uscite)
    TRISA=0b00000000;
    TRISB=0b00000000;
    TRISC=0b11000000;//RC6 RC7 USART
    TRISD=0b00000000;
    TRISE=0b00000000;

    //imposto l’USART
    OpenUSART(USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH, 207);
    baudUSART(BAUD_8_BIT_RATE & BAUD_WAKEUP_ON & BAUD_AUTO_OFF);

    // Invio il carattere al terminale
    WriteUSART (48);

    while(1){}

    }

    • #84 da Giovanni Bernardo il 21 luglio 2011

      Quando si ha un errore del genere il problema sta nelle differenti impostazioni di comunicazione sul pc. Hai controllato bene che l’impostazione sul PC e quella del pic combaciano? Inoltre dopo aver richiamato le funzioni di settaggio dell’UART, dai un piccolo ritardo. Inoltre la scrittura del carattere di test mettila nel while(1) per fargliela scrivere di continuo, in modo da capire se l’errore ce l’hai solo all’inizio e poi scrive bene oppure ce l’hai sempre.

      • #85 da Manuel Colus il 21 luglio 2011

        il pic è impostato per inviare a 9600 b/s e l’uart tool del pickit2 è settato anche esso a 9600 b/s(comunque anche provando a cambiare la velocità il risltato non cambia).

        Ho già provato ad inserire la scrittura del carattere nel ciclo while(1) ottenendo sempre lo stesso errore in ricezione(0×80 0×80 0×80 0×80 ecc. ecc.).
        Anche cambiando il carattere da inviare(esempio inviando U al posto di A) il risultato è sempre 0×80.
        Ho anche già provato ad inserire un ritardo dopo il settaggio dell’uart(sono arrivato a 1000 millisecondi di ritardo) e il risultato continua a non cambiare.

        Credevo che il problema fosse del pickit o delle tensioni dei segnali del pickit ma documentandomi ho avuto conferma che il pickit riceve in ingresso tensioni TTL(0-5 V), inoltre provando a cortocircuitare RX e TX del pickit invio e ricevo i caratteri corettamente nel uart tool…

        Ho letto e riletto il datasheet e l’erratasheet del mio pic un centinaio di volte e continuo a non capire dove sia il probema…

        • #86 da Giovanni Bernardo il 21 luglio 2011

          La cosa strana è che in uscita ottieni sempre lo stesso carattere nonostante nel firmware lo cambi… Se l’UART tool funziona correttamente allora il problema deve stare nel circuito o nel firmware

        • #87 da Giovanni Bernardo il 21 luglio 2011

          0×80 è 128 … ovvero 10000000 … mi viene da pensare a qualche problema di tipo elettrico.

          • #88 da Manuel Colus il 21 luglio 2011

            Mumble mumble, sta sera provo a ricontrollare i collegamenti e controllo con l’oscilloscopio cosa mi arriva esattamente dal pic…

            Ci sto diventando pazzo…

  42. #89 da Manuel Colus il 21 luglio 2011

    Gianni,
    Problema all’usart “risolto” se così vogliamo dire:

    Dopo ore e ore di test con oscilloscopio e pickit ho trovato l’inghippo!

    Il pic “funziona” e manda perfettamente i dati via usart, MA…

    I dati inviati nel firmware NON corrispondono alla tabella ASCII standard:
    Per esempio se invio all’usart il valore 0×30 equivalente al numero 0 nella tabella ASCII il pic invia il valore 0×3E corrispondente a >.
    Se invio 0×31 il pic manda 0×3A. Inviando 0×32 il pic trasmette 0×36.
    Se guardi la tabella ascii noterai che in questo modo il pic invierà un valore della tabella ascii ogni 4…

    Ora mi resta da capire se il problema lo causa il compilatore o il pic stesso….

    • #90 da Giovanni Bernardo il 21 luglio 2011

      uhmm… ma avevi detto che ottenevi sempre 0×80 indipendentemente dal carattere che inviavi. Si tratta quindi di un problema al firmware o c’è qualche impostazione sbagliata. Per curiosità hai provato a lavorare ad una frequenza più bassa? Tipo ad 8MHz, giusto per cercare di escludere uno alla volta tutti i problemi.

      • #91 da Manuel Colus il 22 luglio 2011

        allora, credevo che inviasse 0×80 con qualunque carattere, in realtà, come ho detto precedentemente ho scoperto che riesco ad inviare solo 1/4 della tabella ascii(ovviamente inviando via firmware un altro valore non corrispondente alla tabella stessa), i restanti 3/4 dei caratteri “non vengono riconosciuti” e risultano essere 0×80.

        Ho provato ad aggiornare mplab e l’hitec c18 all’ultima versione ed il risultato non è cambiato…
        Ora provo con il compilatore c18 della microchip e vediamo se cambia qualcosa…

        • #92 da Manuel Colus il 22 luglio 2011

          altro aggiornamento, ho provato a cambiare il pic(avevo un 18f452 in un cassetto), e SENZA cambiare di una virgola il codice(eccetto per i configuration bits ed eliminando il settaggio avanzato del baud rate dato che il 452 ha una periferica USART invece di EUSART) la seriale ha funzionato perfettamente al primo colpo.

          Quindi escludo un problema del circuito e/o di interferenze definitivamente ed escludo un problema di firmware…

          a sto punto o il pic 18f4685 che usavo prima è danneggiato oppure mi è sfuggita qualche impostazione che mi da questo problema(anche se mi sembra assurdo…)

          • #93 da Giovanni Bernardo il 23 luglio 2011

            Allora il pic che stai usando di sicuro ha qualche altra impostazione sull’usart, perchè non penso abbia qualcosa di guasto

          • #94 da Giovanni Bernardo il 23 luglio 2011

            Ho letto pure le errate corrigi… Ma relativamente all’USART non viene segnalato niente… Urge una chiamata a capitan ventosa

          • #95 da Giovanni Bernardo il 23 luglio 2011

            Dato che utilizzi una funzione del C18 per settare l’USART, ti dovresti controllare le funzioni su quali bit vanno ad influire, perchè nulla vieta che ti setta un bit al posto di un altro. A me è capitato con le librerie integrate del C30 e il modulo A/D. C’erano alcuni bit che non c’entravano niente col pic24f che usavo io, perciò decisi di scrivere quel documento. Con la funzione e il datasheet alla mano devi vedere se viene impostato tutto in modo corretto… è l’unico sistema per togliersi i dubbi

  43. #96 da Valentino il 19 ottobre 2011

    Salve Giovanni,
    montata basetta, programmato il micro, collegato il pc ….
    funziona tutto!!! Sei un mito!
    Spero di riuscire nell’impresa di aggiungere alla stessa basetta una eeprom I2C e l’LM35 in modo da fare una monitorizzazione delle temperature ambiente con archiviazione storica. Naturalmente il tutto scaricabile tramite RS232 su PC!

    Ci sentiamo presto.

    Grazie per ora.

    Saluti
    Valentino

  44. #97 da Giuseppe il 23 ottobre 2011

    Salve,io ho un problema con la seriale:ogni quattro secondi invio un pacchetto che viene ricevuto e viene anche data una risposta a questo punto il pic riceve il pacchetto ma dal secondo pacchetto in poi non riesco a ricevere piu….

  45. #98 da mattopino il 2 febbraio 2012

    Salve,
    nel mio codice utilizzo il controllo di alcuni flag che vengono settati nell’ISR e verificati nel main per attivare le corrispondenti funzioni.
    Ho creato un gestore di eeprom 3-wire attraverso un pic16f88 il quale attravesro l usart fa da tramite fra un programma java e una eeprom 93c46.
    Il programma invia dei comandi via seriale che il pic legge nel ISR e interpreta nel main applicandoli all’ eeprom tipo leggerne in contenuto, scrivere una determinata cella di memoria, visualizzare la memoria sullo schermo ecc.
    Tutto funziona bene però ho dei problemi di tempistiche, nel main mi trovo a gestire anche lo schermo di un nokia3310 sul quale visualizzo dei loghi attraverso delle funzioni che impiegano del tempo per scrivere sullo schermo quindi quando mando un comando al pic che viene letto attraverso l interrupt su usart prima di vederlo applicato devo attendere che termini una di queste funzioni con il conseguente risultato che mando un comando passa un certo tempo più o meno lungo e vedo gli effetti del comando.
    Come potrei oviare a questo?
    Esiste un modo per far si che dopo l ISR il pic esegua la porzione di codice dove verifica i flag e poi prosegua con quello che stava facendo??

    Grazie.
    Saluti Matteo

  46. #99 da Giovanni Bernardo il 24 settembre 2010

    Ho capito. Prova ad inviare questa parola da hyperterminal digitando le lettere da tastiera e vedi se così funziona, se non ti funziona nemmeno così hai qualche problema nel codice.

  47. #100 da doghi81 il 24 settembre 2010

    OK grazie!

  48. #101 da Giovanni Bernardo il 3 ottobre 2010

    Un bus 485 va “occupato” prima di trasmettere, per cui oltre ai 2 pin tx/rx c’è sempre bisogno di un terzo pin che ha una funzione di TXEN (altri indicano tale funzione col nome DIR). Tale pin serve appunto per occupare la linea: in pratica gli integrati che convertono i segnali per le linee 485 hanno appunto questo terzo pin che va pilotato opportunamente: lo si deve portare a livello alto in maniera tale che l’integrato predisponga la linea 485 per occuparla. in pratica devi usare un terzo pin del pic per pilotare questo ingresso dell’integrato convertitore: lo porti a livello alto, aspetti un microsecondo e quindi trasmetti i dati come ritieni opportuno, finito di trasmettere, attendi 100mS e porti TXEN a livello basso cos’ liberi la linea. Se porti TXEN a livello basso subito dopo la trasmissione, non funziona nulla, finito di trasmettere devi attendere un certo tempo prima di riportarlo a livello basso, ho scritto 100mS ma potrebbero essere pure di meno, con 100 dovresti stare piu che sicuro che vada tutto bene. Alla fine non è niente di complicato: anziche il max 232 usi un integrato per la 485, solo che in piu devi usare questo terzo pin. Dopodichè ci vuole la resistenza di terminazione sul primo e sull’ultimo dispositivo della linea. se poi la linea è molto disturbata usi pure le resistenze di polarizzazione, altrimenti non sono strettamente necessarie, le puoi comunque aggiungere per maggiore sicurezza.

  49. #102 da Manuel Colus il 21 luglio 2011

    Aggiorno…

    Ho controllato con l’oscilloscopio il segnale inviato dal pic.
    Effettivamente i segnali che arrivano hanno una durata totale di 1,04 millisecondi.
    essendo 10 bit(8 bit+ bit di start e stop) inviati per scrittura significa che ogni bit ha una durata di 0,104 millisecondi, euqivalenti a 9615 bit per secondo.
    Quindi se non ho sbagliato qualcosa nel mio ragionamento, direi che la velocità di 9600 b/s sulla usart è impostata correttamente.

    Altra cosa che ho potuto constatare è che il pic invia effettivamente il valore 0×80(anche se con i bit invertiti ovviamente) e di conseguenza NON è l’uart tool del pickit a sbagliare la lettura…

    Quindi, tirando le somme direi che l’uart è impostata correttamente ma nonostante questo mi invia valori errati…
    Da cosa potrebbe dipendere?

  50. #103 da Manuel Colus il 23 luglio 2011

    Gianni, non ho parole…

    Questa mattina sono andato a comprare un altro 18f4685, collegato sulla scheda, programmato, e la usart HA FUNZIONATO!

    Era proprio il pic che aveva qualcosa che non andava nel modulo usart…
    5 giorni di test su test nei quali sono quasi impazzito e tutto a causa del pic…

    Grazie mille per l’aiuto che mi hai dato.

  51. #104 da Giovanni Bernardo il 23 luglio 2011

    E’ molto molto strano… Non mi è mai capitata una cosa del genere

Devi essere collegato per lasciare un commento.

  1. Ancora nessun trackback
settorezero.com e il logo Zroid™ ©2007÷2012 Giovanni Bernardo - E' vietata la copia e la distribuzione anche parziale dei contenuti di questo sito web senza l'esplicito consenso dell'autore.
I contenuti di settorezero.com sono distribuiti sotto una licenza Creative Commons Attribuzione-Non Commerciale-Non Opere derivate 2.5 Italia a cui vanno aggiunte le condizioni d'uso definite nel disclaimer.
settorezero.com e tutti i suoi contenuti sono tutelati dalla legge sul diritto d'autore per cui i trasgressori sono perseguibili a norma di legge.
Creative Commons BY-NC-ND 2.5
Il tema di questo sito è basato sul tema Fusion per wordpress, realizzato originariamente da digitalnature e fa uso del plugin Wassup per il computo delle statistiche. Per contattare l'autore siete pregati di utilizzare la sezione contatti.
Per essere aggiornato con tutte le novità di settorezero.com seguici anche anche su Facebook Twitter Tumblr Blogspot Youtube.