sabato 8 novembre 2014

Studio PIC 18F (18F4431) #7 :: "Comunicare con il PIC via seriale (RS-232)"


Vai al precedente POST della serie

Possiamo scambiare informazioni (dati) con un PIC? Certo che si!
I PIC 18F, in particolare, mettono a disposizione diverse soluzioni hardware per la comunicazione: UART-USART, I2C, SPI, e perfino USB (18F2550 e affini).
La scelta del protocollo dipende in primis dal tipo di dispositivo che deve interfacciarsi con il nostro PIC: un altro micro-controllore, un modulo GPS, un dispositivo MIDI, un PC, il Raspberry PI, il Lego Mindstorm, ecc... ecc...

Direi di procedere in ordine di complessità crescente e quindi di affrontare per prima, in questo articolo, la comunicazione seriale asincrona o UART.
Tale interfaccia:
  1. è di tipo asincrono (bit start/bit stop)
  2. permette colloquio FULL-DUPLEX tramite due linee distinte: una per l'invio (TX) e l'altra per la ricezione (RX)
  3. permette il colloquio tra due soli dispositivi: un master e uno slave (detto TERMINAL).
  4. la velocità di invio dei bit è detta BAUD-RATE e può essere scelta in un range da 300 a 115200 bit al secondo.

Tramite la UART possiamo interagire ad esempio con un PC (se dispone ancora dell'interfaccia RS-232) o con il RaspberryPI.
I fili necessari vanno da un minimo di 3 a un massimo di 5 a seconda che implementiamo o meno i l controllo hardware di flusso: GND, TX, RX di base, CTS, RTS per il controllo di flusso hardware.

Dato che voglio controllare il PIC dal PC avrò bisogno di un dispositivo intermedio per adeguare il livello dei segnali TTL del PIC con quello richiesto dalla RS-232 del PC: ad esempio un Max232 o un Max233

A tale scopo ho realizzato questo semplice modulo:



Ecco il suo schema elettrico:


La linea RX del modulo sarà connessa al pin TX del PIC, mentre la linea TX del modulo al pin RX del PIC: in questo modo i bit trasmessi dal PIC saranno ricevuti dal PC e viceversa.

Implementazione UART del PIC

Il modulo hardware per la gestione UART (o USART) è chiamato EUSART e permette di implementare sia l'interfacciamento asincrono che sincrono, l'autodetect del BAUD-RATE, l'auto wakeup in ricezione dati, ecc...: insomma è un modulo veramente flessibile e potente.

Per i nostri scopi dobbiamo concentrarci sulle specifiche relative alla sola modalità asincrona a 8 bit dati in full-duplex (non trattando al momento il wakeup e l'auto baud rate); i registri da utilizzare sono:

RegistroDescrizioneBit utilizzati
TXSTAConfigurazione e status del modulo TXTX9=0, TXEN=1, SYNC=0, SENDB=0, BRGH=X,
RCSTAConfigurazione e status del modulo RX, attivazione modulo serialeSPEN=1, RX9=0, CREN=1,
BAUDCTLConfigurazione e status del baud rate e del wakeupBRG16=X, WUE=0, ABDEN=0
SPBRGH:SPBRGConfigurazione generatore del baud ratetutti
TXREGScrittura byte da inviaretutti
RCREGLettura byte ricevutotutti
(X=vedere paragrafo sulla configurazione del baud rate)

Per attivare e gestire gli interrupt associati al modulo i registri sono:

RegistroBit utilizzati
INTCONGIE/GIEH, PEIE/GIEL
PIE1TXIE, RCIE
IPR1TXIP, RCIP
PIR1TXIF, RCIF

Configurazione del baud rate

La scelta della velocità di trasmissione/ricezione dei singoli bit può essere libera o vincolata dal dispositivo con il quale ci dobbiamo collegare.
Una volta determinato il BAUD rate dobbiamo far riferimento alle tabelle sul datasheet del PIC per capire quale è la configurazione ideale dei bit BRG16 e BRGH in relazione alla FOSC e all'errore riportato.
Ad esempio: volendo un BAUD rate di 9600 con un FOSC di 8 MHZ riscontro sempre un errore dello 0,16% a prescindere dalla configurazione a 16 o a 8 bit e alla modalità High/Low speed.
Pertanto imposterò BRG16=0 e BRGH=0 calcolando il valore di SPBRG con la formula:

SPBRG = ((FOSC/BAUD)/64) - 1

Quindi: SPBRG = ((8000000/9600)/64) -1 = 12,02083 (arrotondato a 12).
Visto che il valore è inferiore a 256 posso impostare il solo registro SPBRG.


Trasmissione

La trasmissione di uno o più byte avviene tramite la loro scrittura sequenziale del registro TXREG avendo ovviamente l'accortezza di attendere che il byte precedente sia stato preso in carico dal modulo EUSART prima di scrivere quello successivo.
Per fare ciò possiamo utilizzare gli interrupt oppure leggere lo stato del bit TXIF del registo PIR1 tenendo presente che TXIF :

  1. viene settato a 1 quando il TXREG può essere scritto (e quindi non appena abilitiamo la trasmissione settando il bit TXEN del registro TXSTA
  2. non può essere resettato via software: vuol dire che viene settato a 0 direttamente, dopo la scrittura del registro TXREG, dal modulo stesso quando il valore è stato trasferito in un altro registro interno per lo shift dei singoli bit e la  loro trasmissione .
  3. può essere testato solo dopo aver atteso almeno un ulteriore ciclo di clock (nop) dalla scrittura di TXREG


Ricezione 

Quando il modulo ESUART ha ricevuto un byte (gestendo internamente tutta la logica di ricezione) ne trasferisce il valore dal registro interno al registro RCREG settando l'interrupt flag RCIF a 1.
A questo punto, prima che arrivi un altro byte dalla seriale, dobbiamo leggere il registro RCREG in modo da evitare un OVERRUN (bit OERR settato nel registro RCSTA).


Mano al codice

Unendo due precedenti post (il #5 e il #6) realizziamo quindi un PWM controller che sia però comandabile da remoto via RS-232 in modo da poter variare il colore prodotto da un led RGB semplicemente inviando il valore dei singoli colori.
Inoltre aggiungiamo un display LCD dove indicare lo stato dei valori correnti.

Il progetto è scaricabile qui.


Circuito elettrico



Realizzazione pratica




Utilizzo

Nel mio caso, non disponendo della presa seriale sul PC, ho acquistato una comoda interfaccia USB-RS232.
Per inviare i comandi al Pic in esadecimale in modo facile e intuitivo consiglio l'ottimo software gratuito 'Ultra serial port monitor'.
Le immagini che seguono sono invece tratte da un altro programma non gratuito che ho potuto provare prima che scadesse il periodo di valutazione.


1: invio i tre byte alla prima linea: 00 FF 00 (colore verde)
2: vengono ricevuti dal Pic aggiornando il display lcd e lo stato del led rgb

3: invio ora i tre byte alla seconda linea per produrre il colore giallo
4: ricevuti e processati

5: infine invio l'ultima sequenza per ottenere il colore rosso
6: ricevuti e processati anche questi



Stay tuned!
ap

Vai al successivo POST della serie

NB: l'autore non risponde di eventuali danni causati da omissioni, inesattezze o errori eventualmente presenti nell'articolo pubblicato.
Prego, segnalare suggerimenti e migliorie commentando questo post o inviando una email a padnest@gmail.com.

1 commento :