Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

7
voti

Display 7 segmenti USB [2] - Una libreria per il display

Dopo aver visto la struttura Hardware del progetto, passiamo alla parte Software, che consta della maggior parte della realizzazione. Oggi vedremo la libreria che ho scritto per gestire il display driver MAX7221. Invito nuovamente a leggere il datasheet di questo integrato, perchè veramente ben fatto e di facile comprensione.

Indice

Il formato dei dati

Il MAX7221 è impostabile tramite due byte, uno per definire l'indirizzo del registro interno da settare e uno contenente il dato da impostare nel registro, per quanto riguarda il byte dell'indirizzo, solamente i 4 bit meno significativi sono veramente utilizzati, gli altri 4 bit vengono semplicemente ignorati.

Formato dei Dati

Formato dei Dati

Ecco l'elenco degli indirizzi dei registri interni al MAX7221.

Indirizzi registri

Indirizzi registri

Comunicazione SPI

Da notare che per la comunicazione SPI il display driver necessita della linea dati, della linea per il clock e della linea per il chip select (attiva a livello basso), quest'ultima deve essere settata a 0 prima di iniziare ogni comunicazione e settata a 1 a comunicazione avvenuta, per far si che il MAX7221 copi i dati ricevuti nel giusto registro, rendendo attivo il comando inviato. Nella libreria che ho scritto, ho implementato due tipologie di comunicazione SPI, una utilizzando il componente hardware presente nel PIC e quindi le linee SDO,SCK e CS standard attraverso la libreria SPI.h del C18, la seconda è pensata per PIC in cui non sia presente la comunicazione SPI hardware o che sia già occupata. In pratica ho preso spunta dalla libreria SPI_SW.h, semplificandone le funzioni e adattandola alla comunicazione col nostro display driver. Se si decide di usare la comunicazione SPI software è possibile definire i PIN da utilizzare per le tre linee necessarie. In ogni caso, sia scegliendo l'implementazione hardware, sia la software, l'interfaccia per gestire il tutto non cambia, praticamente ho definito una funzione per inviare un comando al display driver, che attraverso delle macro utilizza solo il codice opportuno.

Impostazione con SPI HARDWARE

Entriamo nel file "MAX7221.h" e assicuriamoci che le due linee nella parte alta del documento siano in questo modo:

//define if use SPI hardware module or SPI software emulated
#define SPI_HARDWARE
//#define SPI_SOFTWARE

I PIN da utilizzare sono quelli di dafault definiti nel datasheet del PIC.
Nel caso del PIC18F14K50, sono:

  • DOUT : Pin 9
  • SCK : Pin 11
  • CS : Pin 8

Impostazione con SPI SOFTWARE

Entriamo nel file "MAX7221.h" e assicuriamoci che le due linee nella parte alta del documento siano in questo modo:

//define if use SPI hardware module or SPI software emulated

//#define SPI_HARDWARE
#define SPI_SOFTWARE

Successivamente dobbiamo impostare i Pin che intendiamo utilizzare, per ognuno dobbiamo specificare sia il bit del registro LAT, sia il bit del registro PORT, cosicché durante l'inizializzazione sia possibile impostarli nel modo opportuno.

#if defined(SPI_SOFTWARE)

    #define DOUT_PIN LATCbits.LATC7
    #define TRIS_DOUT_PIN TRISCbits.TRISC7

    #define SCK_PIN LATBbits.LATB6
    #define TRIS_SCK_PIN TRISBbits.TRISB6

#endif

#define CS_PIN LATCbits.LATC6
#define TRIS_CS_PIN TRISCbits.TRISC6

Nel caso sovrastante abbiamo impostato gli stessi PIN della SPI hardware.

Attenzione

Da notare che la definizione del pin CS avviene per entrambe le configurazioni, questo perchè la libreria hardware non gestisce il pin SS del PIC, dato che si tratta di un collegamento opzionale e quindi deve essere gestito manualmente dal programmatore.

Le Funzioni

Eccoci al succo della libreria, inizialmente spiegherò le funzioni base del MAX7221, che si riflettono nei comandi che è possibile impartire direttamente al display driver. Successivamente illustrerò alcune funzioni utili per iniziare subito a usare il nostro integrato, che permettono di scrivere numeri, caratteri, stringhe e testo scorrevole.

Osservazione

Per quanto riguarda le funzioni complesse, ho deciso di implementare una variabile di tipo char, la cui definizione è a cura del programmatore, che dovrà essere passata alle varie funzioni per indirizzo (cioè anteponendo al parametro il carattere &).Questa servirà a tenere traccia della codifica di ogni cifra del display in modo da modificare solo quella delle cifre strettamente necessarie, questo perche ogni funzione cambia la codifica a seconda delle necessità.

Basilari

Funzione Basilare per l'invio di un comando al MAX7221, varia in automatico a seconda del tipo di SPI scelto

//invia un comando al MAX7221
void MAX7221_SendCommand(char addr, char data);

Abilita la modalità di test, accende tutti i segmenti, per uscire e tornare alla modalità operativa normale dobbiamo richiamare la funzione MAX7221_TestEnd()

//Accende tutti i segmenti
void MAX7221_TestStart();

Funzione per uscire dalla modilità di test e tornare al modo normale.

//Esce dalla modalità di Test
void MAX7221_TestEnd();

Definisce la luminosità del display, i valori consentiti vanno da 0 a 15. In pratica il refresh dello schermo viene divison in sedici momenti, il numero passato alla funzione definisce quanti di questi momenti il display è acceso. Il valore 0 della luminisità corrisponde alla minima (acceso 1 volta su 16), se si vuole spegnere del tutto dobbiamo usare la funzione MAX7221_Shutdown()

//Imposta la luminosità [0-15]
void MAX7221_Brightness(char br);

Definisce la codifica di ogni cifra del display, il bit meno significativo si riferisce alla cifra 0, il pià significativo alla cifra 7. Un bit a 1 definisce la codifica esadecimale (solo i 4 bit meno significativi del byte dei dati vengono considerati), un bit a 0 definisce la codifica manuale seguendo questo schema.

Corrispondenza bit-segmento

Corrispondenza bit-segmento

//imposta a 0 il bit per la cifra NO CODE e a 1 il bit per la cifra B CODE
void MAX7221_Mode(char md);

Tramite questa funzione spegniamo tutto il display, e l'integrato consumerà il minimo. Tutti i registri interni vengono lasciati come sono, richiamando la funzione MAX7221_PowerON() il display tornerà nella stato precedente. Ecco i codici per accendere e spegnere il MAX7221.

Codici Shutdown

Codici Shutdown

//Spegne il display
void MAX7221_Shutdown();

Ripristina il display a seguito della chiamata della funzione MAX7221_Shutdown()

//Accende il display
void MAX7221_PowerON();

Definisce quante cifre far gestire al display driver. i valori ammessi vanno da 0 (solo al cifra 0) a 7(tutte le cifre)

//Imposta il numero di cifre abilitate, da 0 (solo la prima) a 7 (tutte e otto)
void MAX7221_ScanLimit(char ndig);

Inizializzo il display con le impostazioni che gli passo, la variabile mode deve essere la stessa che userò per memorizzare la codifica delle cifre, in questo caso non dobbiamo passarla per indirizzo, ma per valore. Gli altri parametri seguono le stesse regole delle funzioni descritte prima.

//Inizializza il MAX7221 con le impostazioni date di luminosità(brig), codifica(mode) e numero di cifre(ndig)
void MAX7221_Start(char mode, char brig, char ndig);

Inizializza il display con le impostazioni di default, massima luminosità, 8 cifre, tutte le cifre a codifica esadecimale.

//Inizializza il MAX7221 con le impostazioni di DEFAULT(CODE B, MAX LUMINOSITA', 8 CIFRE)
void MAX7221_StartDefault();

Complesse

Scrive un singolo carattere ch, secondo la notazione ASCII, sulla cifra identificata da ndig. Dobbiamo passargli per indirizzo la variabile per la codifica di cui parlavamo all'inizio del paragrafo attraverso il puntatore char* code.

//scrive un carattere su una cifra e la imposta in NO CODE.
//ch: carattere ASCII
//ndig: cifra su cui scriverlo [0-7]
//code: impostazione di codifica precedente, torna modificato
void MAX7221_WriteChar(char ch, char ndig, char* code);

Scrive un singolo carattere ch, secondo la notazione ASCII, sulla cifra identificata da ndig, se la variabile point è diversa da 0, accende anche il punto sulla cifra selezionata. Dobbiamo passargli per indirizzo la variabile per la codifica di cui parlavamo all'inizio del paragrafo attraverso il puntatore char* code.

//scrive un carattere su una cifra e la imposta in NO CODE.
//ch: carattere ASCII//ndig: cifra su cui scriverlo [0-7]
//code: impostazione di codifica precedente, torna modificato
//point: se 0 il punto della cifra è spento, per qualsiasi altro valore, è acceso.
void MAX7221_WriteCharDP(char ch, char ndig, char* code, char point);

Scrive un numero, secondo la notazione Esadecimale, sulla cifra identificata da ndig. Dobbiamo passargli per indirizzo la variabile per la codifica di cui parlavamo all'inizio del paragrafo attraverso il puntatore char* code.

//scrive un numero su una cifra e la imposta in B CODE, scrive solo i 4 bit meno significativi del numero
//num: numero da scrivere in codifica esadecimale
//ndig: cifra su cui scriverlo [0-7]
//code: impostazione di codifica precedente, torna modificato
void MAX7221_WriteHex(char num, char ndig, char* code);

Scrive un numero, secondo la notazione Esadecimale, sulla cifra identificata da ndig, se la variabile point è diversa da 0, accende anche il punto sulla cifra selezionata. Dobbiamo passargli per indirizzo la variabile per la codifica di cui parlavamo all'inizio del paragrafo attraverso il puntatore char* code.

//scrive un numero su una cifra e la imposta in B CODE, scrive solo i 4 bit meno significativi del numero
//num: numero da scrivere in codifica esadecimale
//ndig: cifra su cui scriverlo [0-7]
//code: impostazione di codifica precedente, torna modificato
//point: se 0 il punto della cifra è spento, per qualsiasi altro valore, è acceso.
void MAX7221_WriteHexDP(char num, char ndig, char* code, char point);

Scrive una stringa sul display, dobbiamo passargli il puntatore alla stringa, la lunghezza della stringa e la cifra da cui iniziare a scriverla. Dobbiamo passargli per indirizzo la variabile per la codifica di cui parlavamo all'inizio del paragrafo attraverso il puntatore char* code.

//scrive una stringa sul display
//str: stringa
//len: lunghezza stringa
//start: cifra da cui partire per scrivere [0-7]
//code: impostazione di codifica precedente, torna modificato
void MAX7221_WriteString(char* str, char len, char start, char* code);

Scrive un numero in base decimale sul display utilizzando tutte le otto cifre, il numero è un unsigned long, dato che è l'unica variabile intera che possa rappresentare un numero ad otto cifre. Dobbiamo passargli per indirizzo la variabile per la codifica di cui parlavamo all'inizio del paragrafo attraverso il puntatore char* code.

//Scrive un numero sul display
//num: numero da scrive, intero senza segno
//code: impostazione di codifica precedente, torna modificato
void MAX7221_WriteNumber(unsigned long num, char* code);

Spegne tutte le cifre, imposta la codifica manuale su tutte, ma non entra in modalità shutdown.

//Pulisce il display
void MAX7221_Clear(char* code);

Forse la funzione più simpatica, permette di scrivere una stringa scorrevole sul display, si occupa di tutto la funzione. Dobbiamo passargli la stringa str, il numero di volte che la scritta deve scorrere interamente sul display ncycle, la direzione dir(0 verso sx, 1 verso dx), il ritardo tra uno passo e il successivo misurato in cicli come per le funzioni Delay(), i cicli di ritardo sono 20000*speed.

//scrive una stringa scorrevole sul display
//str: stringa//len: lunghezza stringa
//code: impostazione di codifica precedente, torna modificato
//ncycle : quante volte far scorrere la scritta
//dir: direzione di movimento (0 verso sx, 1 verso dx)
//speed: numero di cicli di attesa tra uno spostamento e l'altro (speed * 20000 cicli)
void MAX7221_ScrollingText(char* str, char len, char* code, char ncycle, char dir, char speed);


Altro

Nella libreria trovate anche altre due cose molto utili, la prima è una serie di MACRO per richiamare rapidamente gli indirizzi dei registri, eccole qua:

#define DIG0		0x01
#define DIG1		0x02
#define DIG2		0x03
#define DIG3		0x04
#define DIG4		0x05
#define DIG5		0x06
#define DIG6		0x07
#define DIG7		0x08
#define DECODE_MODE	0x09
#define INTENSITY	0x0A
#define SCAN_LIMIT	0x0B
#define SHUTDOWN	0x0C
#define TEST		0x0F

In più è presente un vettore chiamato MAX7221_ascii di 128 elementi, che contiene la codifica dal codice ASCII a 7bit verso la parola binaria che codifica il carattere secondo lo standard del MAX7221. In pratica è sufficiente usare come indice del vettore il carattere da scrivere e inviare il byte selezionato all'opportuno registro della cifra su cui vogliamo scrivere. Le funzioni per scrivere caratteri e stringhe sfruttano questo vettore.

7-Segment Font Creator

Se volessimo ridefinire alcuni caratteri o aggiungerne altri, ho sviluppato un semplice programma che genera in automatico la parola binaria da passare al display driver selezionando i segmenti da accendere.

7-Segment Font Creator

7-Segment Font Creator

SCARICA IL PROGRAMMA

Per Finire

La libreria è stata testata, ma non a fondo, quindi ogni osservazione, correzione o aggiunta è molto gradita! Sperando che vi sia piaciuta vi dico arrivederci alle prossime puntate! Parlerò di comunicazione USB e protocollo di comunicazione. Ciao! Ciao!


SCARICA LA LIBRERIA


Indice Puntate

Display 7 segmenti USB [1] - Progetto, Schema e Primo Prototipo

Display 7 segmenti USB [2] - Una libreria per il display

4

Commenti e note

Inserisci un commento

di ,

Grazie, Paolino!!!

Rispondi

di ,

Bel lavoro!

Rispondi

di ,

Grazie di nuovo Carlo!!!

Rispondi

di ,

Rinnovo i miei complimenti Davide, ottimo lavoro.

Rispondi

Inserisci un commento

Per inserire commenti è necessario iscriversi ad ElectroYou. Se sei già iscritto, effettua il login.