venerdì 14 agosto 2015

DIY #2 :: connettore pickit2/pickit3 per breadboard

Oggi realizziamo un altro accessorio (dopo quello del precedente POST della serie) molto utile per connettere alla BB il nostro programmatore di PIC in modo sicuro, stabile e pulito.

Io personalmente utilizzo da sempre i programmatori originali della microchip: dal primo pickit2 all'ultimo pickit3.
Il kit base prevede però il solo programmatore con il cavo USB da connettere al PC.


Per connetterlo alla BB ho deciso di progettare e realizzare questo modulo:



Materiale occorrente

Per la realizzazione del modulo occorre:

  • basetta millefori (un quadratino da 6x5 fori utili)
  • pin header femmina da 1x6
  • pin header maschio da 1x3 + jumper
  • pin header maschio da 1x4
  • pin header maschio da 1x2




Schema del modulo

A sinistra la vista superiore lato componenti, a destra quella inferiore lato saldature.



Le etichette indicano chiaramente i segnali verso il programmatore (header a destra da 6) e quelli verso la BB (header in basso da 4).
Il modulo si deve applicare dal lato della BB con il positivo all'esterno e il negativo all'interno.


Realizzazione pratica


Passo 1: ritagliare dalla basetta millefori una parte come evidenziato nella foto.





Passo 2: fissare tutti gli header con qualche punto di stagnatura.



Consiglio: non stagnare adesso tutti i terminali ma solo quelli sufficienti a mantenere fermi i componenti: sarà poi più facile saldare i fili per costruire le piste.


Passo 3: aggiungere il ponticello come da foto.





Passo 4: completare le saldature delle piste nella faccia inferiore della basetta.



Consiglio: per costruire le piste utilizzare del filo di rame sottile accostandolo il più possibile ai terminali dei vari componenti.


Utilizzo del modulo

Aggiungere il modulo alla BB dal lato corretto: positivo esterno, negativo interno.



Spostare il jumper (come nella foto) a sinistra se la VDD della breadboard deve essere collegata alla 'VDD Target' del programmatore; altrimenti spostarlo a destra verso il ponticello arancio.


Stay tuned!
ap

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.

mercoledì 1 aprile 2015

DIY #1 :: modulo oscillatore per breadboard

Inauguriamo oggi, con questo primo post, la nuova serie DIY (do it yourself o fai da te) con questo semplice e utile accessorio per la nostra basetta sperimentale (breadboard o BB).

Risulta, infatti, sempre un po' scomodo piazzare i componenti, che costituiscono l'oscillatore esterno, sulla BB soprattutto se dobbiamo lavorare con delle MCU (micro controller unit) di grandi dimensioni (tipo il 4431 utilizzato nella serie "Studio PIC 18F").

Solitamente i pin relativi all'oscillatore esterno sono adiacenti (due posti) e quindi non compatibili con la piedinatura dei quarzi (che ha un passo di tre posti).
Inoltre vanno anche previsti due condensatori tra VSS e i terminali del quarzo esterno.

Piegando i piedini del quarzo il risultato è, generalmente, questo:





Invece con questo modulo il risultato sarà molto più ordinato e soprattutto stabile:


Grazie ai due jumper (rosso e blu nella foto) il modulo è compatibile con tutte le MCU: basta solo che abbiano i due terminali OSC (oscillatore esterno) adiacenti.

Grazie ai ponticelli (fili rosso e blu) il modulo può essere posizionato su qualsiasi lato della BB.


Materiale occorrente

Per la realizzazione del modulo occorre:
  • basetta millefori (un quadratino da 7x6 fori utili)
  • n. 3 pin header femmina da 1x2 (oppure un pin header femmina da 2x3)
  • pin header femmina da 1x3
  • n. 2 pin header maschio da 1x3 + jumper
  • pin header maschio da 1x4 (modificato come da foto)
  • pin header maschio da 1x2 (modificato come da foto)
  • due condensatori da 22 pF

Notare che i terminali del primo condensatore sono stati piegati per il passo da 3 pin.

Schema del modulo

A sinistra la vista superiore lato componenti, a destra quella inferiore lato saldature.



Se la MCU (tipo il PIC 18F4431) richiede anche la VDD e la VSS nei pin che precedono quelli OSC, spostiamo i jumper in avanti.


Realizzazione pratica

Passo 1: ritagliare dalla basetta millefori una parte come evidenziato nella foto.


Consiglio: tagliare con il seghetto prima un quadrato intero e solo dopo rifinire la sagoma.


Passo 2: fissare tutti gli header con qualche punto di stagnatura.


Consiglio: non stagnare adesso tutti i terminali ma solo quelli sufficienti a mantenere fermi i componenti: sarà poi più facile saldare i fili per costruire le piste.


Passo 3: aggiungere i due condensatori da 22 pF come da schema.




Passo 4: completare le saldature delle piste nella faccia inferiore della basetta.


Consiglio: per costruire le piste utilizzare del filo di rame sottile accostandolo il più possibile ai terminali dei vari componenti.


Utilizzo del modulo

Aggiungere il modulo oscillatore alla BB applicandovi il quarzo desiderato.



Prestare attenzione a:
  1. posizionare il modulo in modo che i segnali OSC corrispondano a quelli dalla MCU
  2. settare i ponticelli (fili rosso e blu) in modo da rispettare la polarità delle piste della breadboard
  3. spostare il jumper rosso verso la MCU (come da foto) se questa richiede la VDD; altrimenti spostarlo verso l'esterno della BB.
  4. spostare analogamente quello blu per la VSS

I ponticelli permettono di posizionare il modulo in qualsiasi lato della breadboard:


A sinistra la configurazione dei ponticelli quando il modulo si trova nel lato della BB con il negativo all'esterno e il positivo all'interno; a destra per il lato della BB con il negativo all'interno e il positivo all'esterno.




Stay tuned!
ap

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.

domenica 22 marzo 2015

Studio PIC 18F (18F4431) #8 :: "Comunicare con il PIC via i2c (pic slave, raspberry pi master)"


Vai al precedente POST della serie

Il protocollo i2c (Inter Integrated Circuit), inventato da Philips nel lontano 1982, permette, con solo due connessioni (più la massa), la comunicazione bidirezionale tre due o più dispositivi.
In rete troviamo ovviamente ampia documentazione in merito ma non sempre troviamo chiare indicazioni per implementarlo con successo con i PIC.

In questo articolo vediamo come poter controllare il nostro PIC, via i2c, da qualsiasi altro dispositivo esterno che possa comportarsi da MASTER.
L'i2c infatti prevede, per i dispositivi connessi, due ruoli: il MASTER (padrone) e lo SLAVE (servo).

Entrambi possono ricevere e inviare i dati ma solo il MASTER inizia il dialogo e decide la frequenza di lavoro generando il segnale di sincronismo del BUS.

Il BUS è composto da soli due segnali o linee : la linea di clock (SCL) e quella di dati (SDA).
Sul BUS possono coesistere fino a 127 dispositivi SLAVE in quanto il protocollo prevede di poter assegnare ad ogni dispositivo SLAVE un proprio indirizzo (ADDR): sarà il MASTER a decidere con chi parlare ogni volta che vuole inviare o ricevere dei dati.

E' anche possibile che uno SLAVE possa diventare MASTER occupando il BUS in modo da poter a sua volta dialogare con un altro SLAVE: questa modalità però non è oggetto del presente articolo.

Quindi, riassumendo, il protocollo i2c:
  1. è di tipo sincrono (linea SCL)
  2. permette il colloquio bidirezionale su un'unica linea (linea SDA)
  3. permette il colloquio tra un MASTER e molti SLAVE (ma uno alla volta)
  4. la velocità di scambio dati si esprime indicando la frequenza degli impulsi di clock e può essere: 100KHZ/sec (standard), 400KHZ/sec (fast), 3,4MHZ/sec (high)
Come dispositivo MASTER andrò ad utilizzare il Raspberry Pi configurato come indicato in questo mio precedente post.
Il Raspberry Pi supporta l'i2c con clock a 100KHZ/sec.

Da notare che i resistori di pull-up, necessari per mantenere sempre a livello logico alto i segnali SCL e SDA (in assenza di traffico dati), sono già integrati dal Raspberry Pi e pertanto, e solo in questo caso, possono essere omessi nel circuito.


Implementazione i2c dei PIC 18F

I PIC 18F dispongono internamente di un modulo hardware dedicato ai protocolli seriali sincroni chiamato SSP: Synchronous Serial Port.
Tale modulo consente di implementare, con estrema semplicità, sia l'i2c che lo SPI (che vedremo in futuro).

I registri di cui abbiamo bisogno per implementare uno SLAVE i2c sono:
  • SSPCON: dove impostare la configurazione del modulo SSP e controllare il bit CKP
  • SSPADD: dove impostare l'indirizzo i2c del nostro PIC SLAVE
  • TRISC o TRISD: dove configurare i pin scelti come uscite digitali
  • INTCON: dove abilitare gli interrupt settando i bit GIE e PEIE
  • PIE1: dove abilitare gli interrupt della periferica SPP settando il bit SSPIE
  • PIF1: dove verificare che la fonte dell'interrupt sia la eriferica SPP leggendo e azzerando il bit SSPIF
  • SSPBUF; dove leggere e scrivere i byte da ricevere o da inviare sul BUS
  • SSPSTAT: dove verificare lo stato del modulo SPP e intraprendere il corretto comportamento per portare a termine con successo il dialogo i2c con il MASTER 

Ci sono alcuni punti di attenzione, da tenere presente, quanto utilizziamo il modulo SPP come SLAVE i2c:
  1. versione del PIC 18F
  2. configurazione dei pin i2c
  3. tempo limite operativo durante gli interrupt SSP (timing)
La prima trappola da evitare riguarda il fatto che l'implementazione del modulo SPP è leggermente diversa tra alcuni (più vecchi) 18F (tra cui il mio 4431 e famiglia) e i più recenti 18F..
Tali differenze, riportate nel documento Microchip AN734 (appendice C), riguardano gli stati dei bit del registro SSPSTAT in particolare per le operazioni RA (read address) e NACK.
Quindi è sempre bene verificare il datasheet del particolare modello di PIC che intendiamo utilizzare e leggere il documento AN734.

La seconda trappola riguarda il PIC 4431 che permette di scegliere, tra due porte diverse, i pin che vogliamo impegnare per l'i2c: questi posso essere o la coppia RC4(23) e RC5(24) o la coppia RD2(21) e RD3(22).
E' bene quindi non ignorare il settaggio di tale configurazione tramite il bit SSPMX del registro CONFIG3H: se 0 saranno i pin RD2-RD3; se 1 quelli RC4-RC5.

La terza trappola fa proprio la differenza tra successo e fallimento dato che ad un evento i2c dobbiamo rispondere entro un tempo limite altrimenti la comunicazione non va a buon fine.
E' importante quindi avere ben chiaro di quanti cicli operativi (istruzioni PIC) si dispone per gestire un evento i2c.

Operazioni i2c

L'i2c nasce per permettere di impostare o leggere i registri interni ad un dispositivo.

Tipicamente l'operazione di scrittura richiede prima di specificare quale registro scrivere (o da quale iniziare a scrivere) i byte che seguiranno.
Lo SLAVE deve disporre quindi di un registro indice il cui valore viene indicato dal primo byte ricevuto.

Ovviamente possiamo utilizzare l'i2c anche per trasferimenti seriali con una diversa struttura dei dati; ad esempio questo display OLED si controlla via i2c inviando dei comandi e non specificando dei registri interni.

Ogni byte trasferito richiede nove impulsi di clock: 8 per i bit del dato + 1 per il bit di ACK/NACK.
Il bit di ACK/NACK è impostato dalla controparte: MASTER scrive SLAVE risponde ACK/NACK e viceversa SLAVE scrive e MASTER risponde ACK/NACK.
Lo scopo del nono bit di ACK/NACK è quello di indicare di procedere (ACK) o meno (NACK) con l'invio di altri dati.

La sequenza di WRITE, inviata dal MASTER, è composta dai seguenti comandi: 


La prima riga in azzurro mostra i livelli della linea dati (SDA), la seconda in giallo quelli della linea di clock (SCL) e l'ultima in verde gli eventi di interrupt generati dal modulo SSP del PIC.
Il timing, indicato in basso, ha lo scopo di mostrare di quanto tempo (micro secondi) si dispone prima che venga generato da SSP l'interrupt successivo.

Il primo byte inviato è l'indirizzo dello SLAVE, nel mio caso 0x20, spostato però a sinistra di un bit (0x40) in quanto il bit 0 indica se il MASTER vuole inviare dati allo SLAVE (0=WRITE) o riceverne (1 = READ): quindi 0x40 sta per "scrivo sul dispositivo 0x20", mentre 0x41 sta per "leggo dal dispositivo 0x20".

Il secondo byte indica allo SLAVE il valore da impostare nel registro puntatore: è in pratica l'indce del primo registro delle SLAVE che il MASTER vuole impostare.

I restanti byte sono i valori da impostare nel corrente registro che lo SLAVE determina incrementando il suo registro puntatore per ogni byte ricevuto.
In questo caso il MASTER non vuole scrivere in altri registri oltre al primo e chiude il colloquio con un segnale di STOP.


L'operazione di lettura richiede prima una scrittura in modo che lo SLAVE imposti il registro puntatore al registro dal quale iniziare a leggere
.
La sequenza di READ, inviata dal MASTER, è quindi preceduta da una sequenza di WRITE:


Come visto sopra il MASTER invia una sequenza di scrittura verso lo slave 0x20 di un solo byte dati:l'indice del primo registro da leggere.

Dopo lo STOP il MASTER invia una seconda sequenza stavolta di lettura dello SLAVE 0x20.
Sarà adesso lo SLAVE a scrivere sulla linea dati (SDA) i bit corrispondenti al valore da trasmettere al MASTER.
Lo SLAVE è sempre vincolato dal segnale di clock (SCL) generato dal MASTER che legge lo stato della SDA nei punti indicati dalla freccetta in su.
Come sa lo SLAVE se il MASTER vuole ricevere il valore del successivo registro?
Il MASTER, dopo aver letto tutti gli otto bit dal dato al nono impulso setta SDA a 0 (ACK) se vuole ricevere il successivo valore/registro, a 1 (NACK) se non vuole ricevere ulteriori dati.

Stati del modulo SPP

Di seguito il dettaglio di tutti i possibili stati gestiti dal modulo SPP:
  • S: start
    SPP monitora il BUS e genera questo evento non appena un MASTER impegna il BUS per iniziare una sequenza W o R (anche se destinata ad altro SLAVE)
  • WA: write address
    SPP colleziona i bit indirizzo inviati sul BUS per controllare se destinati a lui; il valore ricevuto è quindi l'indirizzo i2c che verrà comparato da SPP con quanto scritto in SSPADD; solo se uguali SPP genera l'evento WA e tutti i successivi fino allo stop.
  • WD: write data
    SPP genera questo evento per ogni byte ricevuto successivamente all'indirizzo i2c
  • P: stop
    SPP genera questo evento quando un MASTER libera il BUS avendo terminato la sequenza di invio o ricezione
  • RA: read address
    Come per WA solo che il MASTER vuole leggere il valore del corrente registro
  • RW: read data
    Come per WD solo che il MASTER vuole leggere il valore del successivo registro

ACK e NACK

In ricezione dati SSP genera per noi i segnali di ACK, al nono impulso di clock, ogni volta che riesce a caricare il registro SPPBUF con gli 8 bit dati ricevuti.
E' importante far sempre trovare il buffer SPPBUF scarico/libero leggendo il precedente valore ricevuto prima che arrivi del successivo: in caso contrario SPP andrà in errore di "write collision":
  1. generando un segnale di NACK sul BUS
  2. impostando il bit WCOL in SSPCON (che va poi azzerato manualmente per ripristinare il funzionamento di SPP)
In invio dati invece siamo noi che dobbiamo verificare che il MASTER abbia segnalato un ACK o un NACK e questo verificando il bit CKP di SSPCON: se 0 ACK, se 1 NACK.


Mano al codice

Il codice di prova, ben commentato, lo trovate qui.
Si tratta di un esempio d'implementazione i2c slave dove il PIC espone 3 registri:
  • add1 (indirizzo 0x00)
  • add2 (indirizzo 0x01)
  • sum  (indirizzo(0x02)
Scrivendo in 'add1' e in 'add2' due valori si potrà leggere la loro somma tramite il registro 'sum'.


Circuito elettrico

Da notare che il quarzo del PIC è, in questo caso, da 16  MHZ.
VDD deve essere 3.3 volt per garantire la compatibilità con i livelli logici del RaspberryPi.

Attenzione: non interfacciate mai dispositivi a 3.3 volt con altri a 5.0 volt senza adattare i livelli tramite appositi circuiti.
Non prelevate mai la VDD a 3.3 volt direttamente dal Raspberry: rischiate di danneggiarlo seriamente.

Utilizzo

Dalla console del Raspberry Pi:
  1. digitare il comando  "sudo i2cset -y 1 0x20 0x00 0x0A 0x0B i"
    questo imposta entrambi i registri add1=0x0b (10) e add2=0x0B (11)
  2. digitare il comando "sudo i2cget -y 1 0x20 0x00"
    questo ci ritorna il valore di add1 cioè 0x0A (10)
  3. digitare il comando "sudo i2cget -y 1 0x20 0x01"
    questo ci ritorna il valore di add2 cioè 0x0B (11)
  4. digitare il comando "sudo i2cget -y 1 0x20 0x02"
    questo ci ritorna la somma di add1 e add2 ciaoè 0x15 (21)

Partendo da questa semplice base, possiamo realizzare interessanti funzioni, controllabili via i2c, con il nostro PIC 18F.

In un prossimo articolo andrò a realizzare, con il PIC 18F, un controller per servomotori basato su i2c.



Stay tuned!
ap


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.

venerdì 2 gennaio 2015

Luci tremolanti con il PIC16F84

Recuperiamo dal cassetto il buon vecchio 16F84A (o 16F84) e utilizziamolo magari per aggiungere alle luci del nostro presepio un realistico effetto torcia o fiaccola: tremolante appunto.

In questo post si affrontano diversi argomenti utili anche come base per ulteriori sviluppi:
  • generare 8 segnali PWM via software
  • generare numeri casuali in asm
  • polarizzare correttamente un transistor utilizzato come interruttore

Materiale necessario:
  • PIC18F84A o in alternativa il PIC16F84
  • quarzo da 4 MHZ
  • resistenze e condensatori qb
  • otto NPN BC337 o similari
  • lampadine a filamento da 5/6 volt (recuperate magari da vecchie catene luminose)

ATTENZIONE: nel caso si voglia utilizzare dei diodi LED al posto delle lampadine a filamento si dovrà limitare la corrente inserendo, per ogni NPN, una resistenza tra il collettore e il LED.
Pilotare dei diodi LED tramite il circuito qui realizzato comporta la loro immediata distruzione in quanto la corrente di collettore non è affatto limitata.
Ovviamente tutti i calcoli sotto riportati andranno rifatti in relazione alla diversa corrente erogata.

Nota: sarà necessario modificare il tipo di pic nelle proprietà del progetto e le dichiarazioni in testa al main.asm se si vuole programmare con successo il vetusto PIC16F84 (quello senza la A finale); il codice invece funzionerà senza problemi e senza bisogno di modifiche per entrambi i modelli.

Schema elettrico

La sezione logica mostra le connessioni del PIC con le otto uscite PWM e le linee riservate alla programmazione (MCLR/VPP, PGD, PGC):


La sezione di potenza mostra un singolo canale PWM; gli altri sono identici:



Scelta del transistor NPN

La scelta è guidata principalmente dalla corrente assorbita dalla lampadina a filamento.
Per determinarla alimentiamola a 5 volt e in serie colleghiamo l'amperometro del nostro multimetro o tester impostandolo sulla scala più alta: 200 mA dovrebbe garantirci di non fare danni...

Nota: misurare con il tester la resistenza della lampadina non serve a nulla in quanto "a freddo" il valore è notevolmente più basso (anche di 20 volte) rispetto a quando il filamento è incandescente.

Nel mio caso ho verificato che le mie lampadine, alimentate a 5 volt, assorbono circa 90 mA.
Sceglierei quindi un transistor NPN che sopporti almeno il doppio della corrente richiesta: nel mio caso andrebbe bene anche un 200mA (2N3904 o similari).

Avendo nel cassetto numerosi BC337-25 ho verificato dal loro datasheet che questi sopportano fino a 800 mA (Ic o corrente di collettore): più che bene per pilotare una sola luce per canale.

Nota: ho scelto di alimentare le lampadine a 5 volt per non complicare il progetto e soprattutto perchè dispongo di un trasformatore che mi eroga 5 volt a 2 ampere ben livellati; adattate ovviamente il circuito alle vostre esigenze aggiungendo eventualmente la sezione di alimentazione per il PIC separata da quella per le lampadine.



Pilotare correttamente i transistor NPN come interruttori

La scelta della valore corretto della resistenza da applicare alla base del transistor è fondamentale per fare in modo di spremere tutti i mA necessari ed ottenere così la massima luminosità delle nostre lampadine.
Dobbiamo in pratica far scorrere la giusta corrente di base ( Ib ) in modo da saturare il transistor ( Ib(sat) ) ed ottenere la massima corrente di collettore ( Ic ) cioè nel mio caso 90 mA.

Per determinare quindi la Ib(min) ci servono poche informazioni:
  • conoscere la hFE del transistor (o anche βdc cioè il rapporto tra Ic e Ib o guadagno in continua)
  • sapere che la corrente di saturazione Ib(sat) = Ic / hFE
  • la legge di Ohm: R = V/I
  • sapere che la caduta di tensione tra base e emettitore è di 0,7 volt (per tutti i transistor a giunzione bipolare o BJT)

Il parametro più incerto è la hFE che può variare, anche per lo stesso modello, sia per ragioni tecniche di produzione e sia in funzione della temperatura di esercizio.
Dal datashhet del BC337-25 leggo che la hFE va da un minimo di 160 ad un massimo di 400; suggerisco di utilizzare in questo caso il valore inferiore: 160

La Ic che vorrei è di 90mA e quindi sapendo che Ib(sat) = Ic / hFE avrò che Ib(sat) =  90mA / 160 = 0,090A / 160 = 0,00056 A (5,6 uA).

Aumentiamo la Ib(sat) di un 20% in modo da compensare le varie tolleranze in gioco: Ib(sat) = 6,3uA

La Rb è quindi = VBB - 0,7 / Ib(sat) = 5volt - 0,7volt / 6,3uA = 4,3volt / 0,00063A = 6825 Ohm che arrotondata ai valori standard fa 6,8 K.



Mano al codice ASM 

Il progetto MPASM-X lo trovate qui: https://sourceforge.net/p/padnest/svn/HEAD/tree/pic16f/pic16f_flickering_lights.X

Premetto subito che questa è solo una base di partenza personalizzabile a piacere per quanto concerne i tempi di lampeggio e quindi l'effetto finale.
Ogni canale PWM genererà un proprio livello di luminosità in modo indipendente dagli altri.

I sorgenti si dividono in tre parti:
  • main.asm: la parte principale che include tutte le altre
  • macros.inc: alcune macro di utilità riprese da quelle scritte per il 18F
  • interrupts.inc: la parte di gestione degli interrupt
  • subs.inc: la parte con le sub routine utilizzate dal main

Il codice è ben commentato in ogni sua parte e non sarà difficile modificarlo a piacimento.
Ricordiamoci solo che, a differenza dei 18F, i 16F sono molto diversi in termini di organizzazione della memoria e di tipo e di numero di istruzioni a nostra disposizione.


Realizzazione pratica

Ecco la BB di sviluppo con 3 canali PWM di prova.


Dettaglio della schedina di sviluppo per il 16F84 realizzata molto tempo fa!


Dettaglio della sezione di potenza.

Risultato

Ecco il risultato finale...








Stay tuned!
ap

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.

sabato 15 novembre 2014

RaspberryPi #1: setup completo per sperimentazioni

In questo articolo vado a riassumere tutti i passaggi necessari per utilizzare il RaspberryPi nei nostri progetti o esperimenti di elettronica.
Per chi non sapesse che cosa sia il RaspberryPi consiglio di iniziare a documentarsi sul sito ufficiale

I passi che andiamo ad eseguire sono riassumibili nei seguenti punti:
  1. Installazione del sistema operativo
  2. Configurazione del sistema operativo
  3. Installazione delle componenti aggiuntive utili allo scopo

Il materiale necessario è:
  1. RaspberryPi (nel mio caso il modello B rev 2)
  2. SD card dedicata da almeno 8 GB
  3. SD card reader
  4. WI-FI dongle usb (compatibile con il RaspberryPi)
  5. Monitor/TV (solo per i primi passaggi)

Installazione del sistema operativo

Per prima cosa scarichiamo l'immagine della distribuzione 'Raspbian Debian Wheezy' disponibile qui.
Nel mio caso ho scaricato l'ultima versione disponibile al momento della scrittura di questo post cioè quella con release date 2014-09-09.

Di seguito scarichiamo e installiamo sul PC il software gratuito Win32DiskImager.

Colleghiamo il card reader al PC e inseriamo la scheda SD: attenzione tutti i dati presenti sulla SD verranno eliminati in modo definitivo!
Scompattiamo l'immagine Raspbian e tramite il programma Win32DiskImager salviamola sulla SD.
Al termine chiudiamo il programma e smontiamo, in modo pulito, la SD da Windows prima di rimuoverla dal card reader.

Inseriamo la SD nel RaspberryPi ancora spento, colleghiamolo ad un monitor o alla TV, colleghiamoci una tastiera usb e accendiamolo.

Dopo alcuni istanti comparirà il menu del tool di configurazione 'raspi-config'.


Configurazione del sistema :: raspi-config

Il raspi-config è accessibile in qualsiasi momento lanciando il comando 'sudo raspi-config'.

Con il tasto TAB si può passare dalla lista a i pseudo-tasti (Select, Cancel, ecc.) in modo ciclico.
Con il tasto invio si entra direttamente nella voce di menu selezionata.

Procediamo quindi a:
  • espandere il file system in modo da sfruttare tutto lo spazio possibile della SD card
    • selezionare la voce 'Expand File System' e seguire le istruzioni a video
  • cambiare (se vogliamo) la password dell'utente 'pi' che di default è 'raspberry'
    • selezionare la voce 'Change User Password' e seguire le istruzioni a video
  • impostare il time-zone
    • selezionare la voce 'Internationalization Options'
    • selezionare poi 'Change Time Zone' e seguire le istruzioni a video
  • impostare il layout della tastiera connessa
    • selezionare la voce 'Internationalization Options'
    • selezionare poi 'Change Keyboard Layout' e seguire le istruzioni a video (il layout si imposta dopo aver confermato il modello di tastiera)
  • abilitare il servizio SSH per il controllo remoto (via putty.exe)
    • selezionare la voce 'Advanced Options'
    • selezionare poi 'SSH'  e seguire le istruzioni a video
  • abilitare il supporto SPI
    • selezionare la voce 'Advanced Options'
    • selezionare la voce 'SPI'
  • abilitare il supporto I2C
    • selezionare la voce 'Advanced Options'
    • selezionare la voce 'I2C'
Torniamo al menu principale e usciamo selezionando Finish.
Acconsentiamo al reboot del sistema se ce lo chiede...


Configurazione del sistema :: aggiornamento

Installiamo gli ultimi pacchetti aggiornati disponibili post rilascio della distribuzione:
  • eseguire il comando 'sudo apt-get update'
  • al termine eseguire il comando 'sudo apt-get upgrade' (confermare con Y e invio)
  • attendere che termini l'esecuzione dell'upgrade

Configurazione del sistema :: ip statico

Dato che vogliamo accedere al RaspberryPi comodamente dal nostro PC (tramite putty) e preferibile assegnargli un ip di rete statico (per default è attiva la configurazione in dhcp):

  • eseguire il comando 'sudo nano /etc/network/interfaces'
  • cambiare la riga 'iface eth0 inet dhcp' in 'iface eth0 inet static'
  • subito sotto alla riga cambiata aggiungere le seguenti linee (i valori sono solo di esempio):
    • address 192.168.1.10 
    • netmask 255.255.255.0
    • gateway 192.168.1.1
  • uscire salvando le modifiche al file ('CTRL+X' poi 'Y' poi invio)
  • eseguire il comando 'sudo reboot'
  • dopo il riavvio eseguire il comando 'ifconfig' verificando che l'ip della eth0 sia quello impostato
  • avviare putty.exe sul PC e verificare che non ci siano problemi a connettersi via SSH alla porta 22

Installazione componenti :: configuratore rete wi-fi

Un adattatore usb per la connessione WI-FI è sicuramente l'ideale per accedere da remoto al RaspberryPi senza lo scomodo cavo di rete:
  • eseguire il comando 'sudo apt-get install wicd-curses'
  • avviare con 'sudo wicd-curses'
  • configurare la rete WI-FI selezionandola dalla lista (e premento il tasto freccia destra)
    • settare ip statico, netmask e gateway
    • settare il DNS#1 a 8.8.8.8 e DNS#2 a 8.8.4.4 (o altro a piacere)
    • settare il DHCP Hostname a 'raspberrypi' (o altro a piacere)
    • settare 'Automatically connect... network'
    • settare 'Use Encryption' e impostare la password WPA della rete WI-FI
    • confermare con F10
  • selezionare la rete WI-FI e premere C (Connect) per verificare che si connetta
  • se tutto ok uscire premento Q
  • staccare il cavo di rete
  • avviare putty.exe sul PC e verificare che non ci siano problemi a connettersi via SSH alla porta 22
Da questo momento il RaspberryPi utilizzerà la rete WI-FI configurata in assenza di una connessione via cavo in automatico.
A questo punto possiamo liberare il Raspberry da tutte le connessioni a monitor/TV, tastiera e cavo di rete... e proseguire con i prossimi passi via putty dal PC.

Installazione componenti :: server ftp

Avere un server ftp a bordo del RaspberryPi ci permette di trasferirci dei file senza doverli copiare sulla SD.
Da PC posso connettermi utilizzando uno dei diversi client ftp gratuiti disponibili in rete.
Io, fra tutti, preferisco il FileZilla ftp client.

  • colleghiamoci via putty al RaspberryPi
  • eseguire il comando 'sudo apt-get install vsftpd' e completare l'installazione
  • eseguire il comando 'sudo nano /etc/vsftpd.conf'
    • decommentare e impostare 'anonymous_enable=NO'
    • decommentare e impostare 'local_enable=YES'
    • decommentare e impostare 'write_enable=YES'
    • aggiungere in fondo 'force_dot_files=YES'
  • salvare il file modificato ('CTRL+X' poi 'Y' poi invio)
  • eseguire il comando 'sudo service vsftpd restart'
A questo punto siamo in grado di connetterci, al RapsberryPi tramite il nostro client ftp, alla porta di default (21) e vedere la lista dei file presenti nella cartella dell'utente 'pi'.

Connessi con successo al server ftp del RaspberryPi

Installazione componenti :: i tool per i2c

Il RaspberryPI può anche essere un utile strumento di debug delle nostre applicazioni i2c grazie a questi tool: qui trovate la documentazione completa per l'utilizzo.

  • eseguire il comando 'sudo apt-get install i2c-tools'
  • eseguire il comando 'sudo nano /etc/modprobe.d/raspi-blacklist.conf'
    • commentare linea 'blacklist i2c-bcm2708'
    • salvare il file modificato
  • eseguire il comando 'sudo nano /etc/modules'
    • aggiungere la linea 'i2c-dev'
    • aggiungere la linea 'i2c-bcm2708'
    • salvare il file modificato
  • eseguire il comando 'sudo reboot'
Non appena il RaspberryPi ha terminato il riavvio ci possiamo riconnettere per provare a lanciare il comando 'sudo i2cdetect -y 1' che dovrebbe presentarci la mappa dei dispositivi connessi al bus i2c con successo.

Nessun dispositivo connesso al bus i2c al momento

Installazione componenti :: java (jdk8 + pi4j)

Per chi come me intende sviluppare applicazioni in java per i RaspberryPi provare a lanciare in comando 'java -version'.
Se il comando non è riconosciuto eseguire 'sudo apt-get install oracle-java8-jdk'.

Procedere quindi all'installazione di pi4j: 
  • eseguire il comando 'curl -s get.pi4j.com | sudo bash'
  • eseguire il comando 'cd /opt/pi4j/examples'
  • eseguire il comando 'javac -classpath .:classes:/opt/pi4j/lib/'*' -d . ControlGpioExample.java'
A questo punto verificare che venga eseguito con successo la classe di esempio ControlGpioExample lanciando il comando: sudo java -classpath .:classes:/opt/pi4j/lib/'*' ControlGpioExample



Il nostro RaspberryPi è adesso pronto per i futuri post della serie...


Stay tuned!
ap

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.

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.

sabato 1 febbraio 2014

padnest-mpasm-structs: libreria di macro per semplificare i loop e i salti condizionati

Ho realizzato questa libreria di macro che ci permetterà di gestire con estrema facilità loop e salti condizionati in MPASM.

La trovate come singolo file include (padnest-mpasm-structs-vX.x.inc) nel progetto ad essa dedicato qui: https://sourceforge.net/p/padnest/svn/HEAD/tree/mpasm/Padnest_MPASM_structs.X

Nel file test.asm trovate i vari casi di test che fungono anche come validi esempi di utilizzo.
Nel file della libreria trovate tutte le possibili istruzioni ben commentate.

Grazie ai blocchi strutturati la scrittura del codice ASM risulterà più semplice, elegante, leggibile e manutenibile rispetto al solito.

La libreria mette a disposizione
  • i cicli do-until, do-forever, while e for-next
  • i blocchi condizionati if-else-otherwise e switch-case


Do-Until (Do-Forever)

Permette di definire un blocco di istruzioni da eseguire sicuramente almeno un volta e da ripetere finchè non si verifica una determinata condizione valutata alla fine del blocco stesso.

Esempio:
    movlf 0x01, REGX
    do
        incf REGX
    untilfl REGX, EQ, 0x03
    nop
Il loop verrà ripetuto fino a quando il valore del registro REGX non sarà uguale a 3.
L'esecuzione proseguirà poi alla linea 5.

Esempio di loop infinito:
    do
        ...
    forever
Il blocco do verrà ripetuto all'infinito.

Si può comunque forzare l'uscita dal blocco do corrente utilizzando le istruzioni break e exitdo:
    movlf 0x01, REGX
    do
        do
            ifl REGX, EQ, 0x03
                exitdo
            endi
            incf REGX
        forever
        incf REGX
    untilfl REGX, EQ, 0x04
    nop


While

Simile al do-until solo che la valutazione della condizione avviene all'inizio del blocco.
Il blocco viene pertanto eseguito solo se la condizione è vera e ripetuto fintanto che essa rimane vera:
    movlf 0x01, REGX
    whilefl REGX, LT, 0x04
        incf REGX
    endwhile
Quando il valore del registro REGX sarà uguale a 4 l'esecuzione del loop terminerà.


For-Next

Il classico ciclo dove si utilizza un registro come contatore:
    for REGX, 1, 3
        for REGY, 1, 3
            incf REGZ
        next REGY
    next REGX
Il registro REGZ verrà incrementato 9 volte. Anche da un ciclo for si può forzare l'uscita tramite l'istruzione break o l'istuzione exitfor.


Switch-Case

Molto utile per eseguire blocchi di istruzioni al verificarsi di una condizione potendo anche definire un comportamento di default se nessuna condizione si verifica:
    switchf REGX
        casel 0x01
            nop
            break
       casel 0x02
       casel 0x03
            nop
            break
       casel 0x04
       casel 0x05
            nop
            break
       default
            nop
    endswitch
Si valuta il contenuto del registro REGX: se vale 1 si esegue il nop alla linea 3; se vale 2 o 3 si esegue il nop alla linea 7; se vale 4 o 5 si esegue il nop alla linea 11; altrimenti si esegue il nop alla linea 14.


Per altri esempi fare riferimento al file test.asm nel progetto MPLAB-X della libreria. 
La libreria sarà utilizzata nei prossimi post della serie "Studio PIC 18F".

Stay tuned!
ap

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.

sabato 25 gennaio 2014

MPLAB-X #2 :: Aggiungere l'icona alla barra di avvio su Windows 7 x64

Volete aggiungere l'icona di MPLAB-X sulla barra di avvio di Windows 7 a 64 bit ma non sembra possibile?
Avete creato manualmente il link sulla barra di avvio ma ogni volta che avviate MPLAB-X vi ritrovate con una fastidiosa seconda icona?

In attesa di tempi migliori seguiamo questa semplice procedura (verificata con MPLAB-X v.2.0.0):
  1. scaricare l'ultima versione del jre 7 per x86 (quindi a 32 bit) dal sito della Oracle.
  2. installare scegliendo come cartella di destinazione 'C:\Java\jre1.7.0_x86'.
  3. nella cartella di installazione di MPLAB-X portarsi in 'mplab_ide/etc'
  4. editare il file 'mplab_ide.conf' in modo da cambiare il valore del parametro jdkhome:
    # default location of JDK/JRE, can be overridden by using --jdkhome <dir> switch
    jdkhome="C:\Java\jre1.7.0_x86\"
  5. salvare il file
  6. avviare MPLAB-X: adesso avrete una sola icona 'pinnabile' sulla barra di avvio!


Stay tuned!
ap

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.

domenica 12 gennaio 2014

Studio PIC 18F (18F4431) #6 :: "Hello World su LCD HD44780"

Vai al precedente POST della serie

Per poter utilizzare un display LCD dobbiamo prima di tutto conoscere qual è il controller che lo pilota.
Esistono diverse tipologie di controller: testuali, grafici, paralleli, seriali...
Iniziamo con quello che è di fatto uno standard per gli LCD testuali: il controller HD44780 sviluppato da Hitachi.
Il controller HD44780 rende estremamente semplice l'interfacciamento (di tipo parallelo) richiedendo un numero limitato di connessioni (e quindi di pin utilizzati).

Frugando nel cassetto ho trovato questo LCD prodotto dalla Powertip: trattasi del modello PC1602-D che permette di visualizzare 16 caratteri su 2 righe:



Di seguito la descrizione dei pin di interfacciamento:

POWERTIP PC 1602-D
PinSimboloDescrizione
1VssPower supply (GND)
2VddPower supply (+)
3VoContrast Adjust
4RSRegister select signal
5R/WData read / write
6EEnable signal
7DB0Data bus line
8DB1Data bus line
9DB2Data bus line
10DB3Data bus line
11DB4Data bus line
12DB5Data bus line
13DB6Data bus line
14DB7Data bus line / BF (busy flag)
15APower supply for LED B/L (+)
16KPower supply for LED B/L ( )

Generalmente tutti gli LDC HD44780 hanno i pin disposti secondo questo schema ma ovviamente verificate il datasheet del vostro display per adattare le connessioni in modo corretto...
I pin 15 e 16 servono per alimentare i led di retro-illuminazione... ma il mio LCD non ne è provvisto e quindi non verranno utilizzati.

Interfacciamento (BUS dati a 4 bit)

Per ridurre al minimo il numero di connessioni necessarie si utilizza solitamente la modalità con BUS dati a 4 bit  (in alternativa a quella con BUS dati a 8 bit) forzando la linea R/W a 0 cioè in sola scrittura (rinunciando pertanto a leggere lo stato del display).
Per evitare la perdita di comandi si utilizzano specifici tempi di delay in modo da essere sicuri che il controller abbia terminato l'esecuzione di un comando prima di inviare il successivo.

Questa configurazione richiede solo 6 linee di segnale: RS, E, DB4, DB5, DB6, DB7.
I rimanenti pin del controller saranno connessi a VSS secondo il seguente schema:


Inizializzazione del display

Dopo aver dato tensione al display questo di configura automaticamente in modalità BUS a 8 bit e quindi è necessario inviare una speciale sequenza di reset per poter cambiare questa configurazione di default.
Tale sequenza di reset è descritta nel datasheet del controller HD44780 e qui di seguito riassunta:
  1. attesa di almeno 40 msec dall'accensione
  2. BUS dati impostato a 0011
  3. strobe su linea E
  4. attesa di almeno 5 msec
  5. strobe su linea E
  6. attesa di almeno 160 usec
  7. strobe su linea E
  8. attesa di almeno 160 usec
  9. BUS dati impostato a 0010
  10. strobe su linea E
  11. attesa di almeno 160 usec
  12. seguono invii dei normali comandi per le configurazioni

Invio dei comandi al controller

Dato che non possiamo controllare lo stato del bit BF (come visto prima R/W è forzato a 0 per risparmiare una linea di controllo) bisogna attendere il tempo indicato per l'esecuzione di ogni comando prima di inviare il successivo (abbondando un po' per sicurezza rispetto a quanto indicato nel datasheet).
Nella modalità a 4 bit i comandi vanno inviati in due parti: prima i bit 7-4 e poi i bit 3-0 (most significant niblle first).
Quando il BUS dati è impostato con il valore da trasmettere bisogna inviare un impulso alto-basso sulla linea E (strobe) in modo che il controller prenda in carico il dato.
In pratica la sequenza corretta di invio di un comando per la modalità con BUS a 4 bit sarà la seguente:
  1. setto il 4 bit alti (DB7-DB4)
  2. strobe su linea  E
  3. setto i 4 bit bassi (DB3-DB0)
  4. strobe su linea E
  5. delay di attesa esecuzione comando

Elenco comandi controller HD44780
Comando Codifica linee Descrizione Tempo max esecuzione
(con fcp=270 kHz)
RS R/W D7 D6 D5 D4 D3 D2 D1 D0
Clear display 0 0 0 0 0 0 0 0 0 1 Pulisce il display e posiziona il cursore in linea 1 colonna 0 (indirizzo 0 della DDRAM) 1.52 ms
Cursor home 0 0 0 0 0 0 0 0 1 0 Posiziona il cursore in linea 1 colonna 0 (indirizzo 0 della DDRAM). Inoltre riporta il display shift in posizione originale. Il contenuto della DDRAM non viene modificato. 1.52 ms
Entry mode set 0 0 0 0 0 0 0 1 I/D S Imposta il modo di inserimento dei caratteri.
I/D = puntatore DDRAM dopo scrittura di un carattere: 0=decrementa, 1=incrementa
S = scroll dello schermo: 0=off, 1=on
37 μs
Display on/off control 0 0 0 0 0 0 1 D C B Imposta lo stato del display e del cursore.
D = display: 0=off, 1=on
C = cursore: 0=off, 1=on
B = lampeggio cursore: 0=off, 1=on
37 μs
Cursor/display shift 0 0 0 0 0 1 S/C R/L 0 0 Sposta il cursore o lo schermo di una posizione.
S/C = modo: 0=cursore, 1=schermo
R/L = direzione: 0=sinistra, 1=destra
37 μs
Function set 0 0 0 0 1 DL N F 0 0 Imposta i parametri di base del display.
DL = bus dati: 0=4 bit (DB4-DB7), 1=8 bit (DB0-DB7)
N = numero linee: 0=una linea, 1=due linee
F = dimensioni font: 0=5x8 (N=0 o 1), 1=5x10 (N ignorato: sempre una linea)
37 μs
Set CGRAM address 0 0 0 1 CGRAM address Inizio scrittura o lettura CGRAM all'indirizzo specificato. 37 μs
Set DDRAM address 0 0 1 DDRAM address Inizio scrittura o lettura DDRAM all'indirizzo specificato. 37 μs
Read busy flag &
address counter
0 1 BF CGRAM/DDRAM address Lettura stato controller.
BF = stato busy flag: 0=inviare nuovo comando, 1=attendere termine esecuzione comando
CGRAM/DDRAM = indirizzo attuale del puntatore alla ram in uso corrente.
0 μs
Write CGRAM or
DDRAM
1 0 Write Data Scrive il dato nella ram in suo corrente (CGRAM o DDRAM). 37 μs
Read from CG/DDRAM 1 1 Read Data Legge il dato dalla ram in uso corrente (CGRAM o DDRAM). 37 μs

La CGRAM è la ram che il controller usa per la generazione di caratteri extra definibili dall'utente: questo argomento verrà approfondito più avanti in un futuro post...
La DDRAM invece è la ram che il controller usa per memorizzare i codici dei caratteri da mostrare sul display) ed lo spazio utile è sempre di 80 bytes (anche se il display ne mostra meno).
I byte della DDRAM sono organizzati nel seguente modo: dall'indirizzo 0x00 a 0x27 troviamo le prime 40 locazioni e da l'indirizzo 0x40 a 0x67 le seconde 40 locazioni.
Come poi vengono organizzate fisicamente per mostrare i caratteri sul display dipende da quante linee un determinato modello può visualizzare: un'ottima spiegazione si trova qui.

Nel caso di un display a 2 linee la seconda linea inizia alla locazione 0x40.

Inviando più comandi di shift con S/C a 1 (scroll di tutto lo schermo) si possono mostrare i caratteri contenuti nelle locazioni 'nascoste' per entrambe le righe.

Scrittura sul display

Per mostrare un carattere sul display bisogna scrivere il codice del carattere sulla DDRAM.
Inviando il comando di scrittura il controller salverà il codice del carattere nella locazione corrente della DDRAM incrementando (o decrementando) il puntatore alla successiva locazione secondo quando configurato dal comando 'Entry mode set'.

In caso di incremento:
  • se il puntatore si trovava alla locazione 0x27 verrà spostato alla locazione 0x40
  • se si trovava alla locazione 0x67 verrà riportato alla locazione 0x00.
In caso di decremento:
  • se il puntatore si trovava alla locazione 0x40 verrà spostato alla locazione 0x27
  • se si trovava alla locazione 0x00 verrà spostato alla locazione 0x67.

Mano al codice

Il progetto ASM lo trovate qui.
Le sub di delay sono tutte calcolate per un FOSC di 8 MHZ: ovviamente se necessario andranno adattate (consiglio questo utile generatore di routine di delay on line: da evitare però i 'goto $').
Utile notare come, in questo esempio, ho utilizzato la lettura delle stringhe dalla memoria programma tramite la nuova e comodissima istruzione TBLRD.
Ogni funzione è ben commentata e non credo richieda ulteriori spiegazioni...

Realizzazione pratica

Una volta connesso il tutto (come da schema sopra indicato) e programmato il PIC (che anche in questo caso va autoalimentato) non rimane che regolare il contrasto, agendo sulla resistenza variabile VR1, fino a vedere scorrere i caratteri nel display.



Risultato






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.