Libreria per display grafici GLCD con controllore KS0108B

Spesso i sistemi embedded si interfacciano con l'utilizzatore per mezzo di un'interfaccia grafica, al fine di poter comunicare alcune informazioni e permettere all'utente di prendere determinate azioni in risposta alle informazioni ricevute.
L'interfaccia grafica può essere semplicemente realizzata con dei LED o avere dei display alfanumerici che permettono di scrivere direttamente dei messaggi. Quando questo non dovesse essere sufficiente e si dovesse avere l'esigenza di migliorare la comunicazione macchina utente si ricorre spesso a display grafici. In questa Brief Note si introduce la libreria per il controllo di display grafici GLCD basati su controllore KS0108B.
 

Il controllore KS0108B

Il controllore grafico KS0108B, prodotto dalla Samsung, sebbene relativamente anziano viene ancora frequentemente utilizzato grazie alla sua reperibilità, facilità d'uso e costi ridotti. Il controllore possiede tutta  l'elettronica per potersi interfacciare con un microcontrollore e poter decodificare i comandi necessari per poter controllare un display GLCD monocromatico (la retroilluminazione è spesso bianca, verde o blue) . Il controllore sebbene decodifichi i comandi per il controllo del display e rappresenti l'interfaccia del display grafico stesso, al fine di controllare effettivamente il display a cristalli liquidi, è necessario  abbinarlo al controllore KS0107B.  
Il controllore KS0108B possiede al suo interno 512byte di memoria RAM ovvero 4096 bit. Spesso i display GLCD che si trovano in commercio hanno una risoluzione 128x64 pixel ovvero con una risoluzione sull'asse delle X paria a 128 punti mentre sull'asse delle Y una risoluzione di 64 punti.
Moltiplicando semplicemente la risoluzione X ed Y si capisce che un display grafico 128x64 possiede 8192 punti. Dal momento che il controllore KS0108B possiede una memoria RAM interna di 4096 bit, un display GLCD con risoluzione 128x64 necessita di due controllori KS0108B, ai quali sono abbinati un controllore KS0107B. Uno schema a blocchi di un modulo GLCD è riportato in Figura 1.

Figura 1:  Schema a blocchi di un display GLCD 128x64 basato su controllore KS0108B

Figura 1: Schema a blocchi di un display GLCD 128x64 basato su controllore KS0108B.

Sul mercato è possibile trovare GLCD con risoluzione maggiore ottenuti con tre controllori KS0108B. Da quanto detto si capisce che pilotare un display grafico basato su controllore GLCD KS0108B consiste nel pilotare due controllori. Il display grafico è suddiviso in due parti come riportato in Figura 2. La parte I è controllata dal primo controllore mentre la parte II è controllata dal secondo controllore. Da questa prima rappresentazione si capisce anche che se si volesse disegnare un punto con coordinata X pari a 80, bisogna scrivere nel secondo controllore con coordinata X pari a 15. Di questo non ci si dovrà preoccupare troppo perché la libreria introdotta in questa Brief Note, tratterà con questi dettagli mentre l'utilizzatore potrà utilizzare funzioni semplici.
 

Figura 2:  Divisione del display grafico 128x64


Figura 2: Divisione del display grafico 128x64.

Sebbene la Figura 2 mostri che la risoluzione di ogni settore è di 64x64 pixel, per accedere ad ogni punto non basta semplicemente inviare dei comandi per un punto di coordinate x,y compreso tra 0 e 63. Il controllore KS0108B divide infatti ogni settore in 8 pagine, come riportato in Figura 3. Ogni pagina possiede a sua volta una risoluzione 64x8 e può essere scritta solo 8 punti alla volta (verticalmente).
 

Figura 3:  Divisione dei settori in Pagine


Figura 3: Divisione dei settori in Pagine.

Questa divisione, che si ritrova anche in altri controllori, discende dal fatto che per ogni pixel non è associato un byte ma un solo bit, per cui un byte controlla 8 bit. Per tale ragione 8 punti è il numero minimo di pixel che è possibile scrivere. Per poter disegnare un pixel è necessario dunque impostare, il controllore (settore), la pagina e l'indirizzo (nominato Y address). Dal momento che  è possibile scrivere solo 8 punti alla volta, si capisce che, qualora si voglia modificare un solo pixel,  è necessario prima leggere il valore del byte in cui  è raggruppato il nostro pixel e solo successivamente scrivere il valore del nuovo pixel senza alterare il valore degli altri.
Sebbene per ogni pixel si debba posizionare controllore, pagina e indirizzo, qualora si debbano scrivere più punti consecutivi si può sfruttare il fatto che l'indirizzo interno al controllore viene automaticamente incrementato ad ogni scrittura. In questo modo fin tanto che non si debba cambia  controllore o pagina, si può scrivere l'indirizzo iniziale e procedere da sinistra verso destra alla scrittura degli altri bit, evitando di dover effettuare una scrittura d'indirizzo per ogni pixel.

Nota:
Si noti che l'asse delle X (asse orizzontale) viene puntato da Y address del controllore, la ragione è semplicemente legata al fatto che il display dovrebbe essere visto posizionato in verticale, per cui la risoluzione la si dovrebbe leggere come 64x128 e non 128x64.

Ogni controllore KS0108B si interfaccia con un microcontrollore con le seguenti linee di controllo:


DB0-DB7
Data bus per leggere scrivere dati.

E
Linea di Enable, usata per scandire le fasi di lettura scrittura.

R/W'
Linea Read/Write, utilizzata per selezionare la fase di lettura, se impostata ad 1, o fase di  scrittura se impostata a 0.  

D/I'
Linea Dati/Istruzione, utilizzata per specificare se l'operazione sul Bus DB0-DB7 rappresenta un movimento  Dati o Istruzione (Dati se D/I' è pari ad 1, mentre Istruzione se D/I' è pari a 0).

RST'
Linea di Reset. Se impostata a 0 pone in stato di Reset i controllori.

CS1, CS2
Tali linee rappresentano i Chip Select dei due controllori. In particolare le linee precedentemente spiegate sono usate dall'uno o l'altro controllore a seconda del Chip Select abilitato.


Si fa notare che la nomenclatura utilizzata in questa descrizione può variare leggermente a seconda del datasheet utilizzato ma dalla descrizione della funzione del pin stesso si può facilmente individuare la corrispondenza con quelli appena descritti.


La sequenza di scrittura dati è descritta in Figura 4.

Figura 4:  Sequenza di scrittura in un controllore KS0108B

Figura 4: Sequenza di scrittura in un controllore KS0108B.

mentre la sequenza di lettura è riportata in Figura 5.

Figura 5:  Sequenza di lettura in un controllore KS0108B

Figura 5: Sequenza di lettura in un controllore KS0108B.

I vari tempi associati alle sequenze scrittura/lettura, sono riportati in Tabella 1.

Tabella 1: Tempi associati alle sequenze scrittura-lettura su un controllore KS0108B

Tabella 1: Tempi associati alle sequenze scrittura/lettura su un controllore KS0108B.

Qualora i tempi di scrittura lettura non fossero rispettati è possibile che i comandi non vengano riconosciuti per cui l'inizializzazione o la rappresentazione di oggetti sullo schermo avvenga in maniera disordinata (punti mancanti o punti in posizioni errate).
Una mancata inizializzazione è  possibile verificarla osservando un effetto neve sullo schermo, ovvero i pixel dello schermo hanno un valore casuale che riflette il contenuto random della memoria RAM interna al controllore (alcune volte è possibile vedere una correlazione tra i pixel accesi). L'inizializzazione del display, ovvero dei controller, tra le varie operazioni compiute ha il compito di porre a 0x00 o 0xFF il contenuto della memoria RAM, il che equivale a pulire lo schermo.

Al fine di poter utilizzare propriamente il display sono presenti altre linee/pin, in particolare per il LED di retroilluminazione, pin per il contrasto e pin di alimentazione. La piedinatura tipica per un display GLCD basato su controllore KS0108B è riportata in Tabella 2 (normalmente il pin 1 è riportato sulla serigrafia del PCB sul quale è montato il display):

Tabella 2: Piedinatura tipica per un GLCD basato su controllore KS0108B
Tabella 2: Piedinatura tipica per un GLCD basato su controllore KS0108B.

Nota:
La piedinatura riportata fa riferimento al display LCD 64128A LED della ELECTRONIC DATA TECH. La piedinatura potrebbe variare a seconda del modello utilizzato, per cui fare sempre attenzione al datasheet del display che si sta utilizzando.

In Figura 6 è riportato lo schema elettrico con il display LCD 64128A LED utilizzato per testare la libreria con un PIC18F4550 (l'hardware utilizzato è stato Freedom II e la scheda di espansione PJ7007). Lo schema elettrico riporta il dettaglio del collegamento del trimmer necessario per il controllo del contrasto (Rx può variare da display a display e ha valori normalmente compresi tra 2.2ohm-10ohm a seconda della corrente che si vuole avere per la retroilluminazione).

Figura 6:  Schema elettrico per testare la libreria GLCD per controllore KS0108B

Figura 6: Schema elettrico per testare la libreria GLCD per controllore KS0108B.

Libreria C18 per controllore KS0108B

La libreria grafica  descritta in questo articolo è stata scritta per PIC18 ed è testata su PIC18F4550 con quarzo 20MHz. E' pensata per poter essere utilizzata senza dover tenere a mente il funzionamento del controllore KS0108B e poter quindi mantenere l'attenzione sugli aspetti principali dell'applicazione.

La libreria  è composta di un file header in cui sono dichiarate diverse costanti e i prototipi delle funzioni. L'implementazione delle funzioni  è riportata nel file sorgente .c. Entrambi i file devono essere inclusi al fine di poter propriamente compilare un progetto. I percorsi in cui sono contenuti i file devono essere aggiunti ai percorsi di sistema utilizzati dal compilatore.

Nel file header sono presenti le informazioni relative al collegamento del modulo GLCD. Sebbene sia possibile variare a proprio piacimento i collegamenti  è necessario mantenere il Data bus su un'unica porta. In particole, come mostrato dalla seguente dichiarazione,  è necessario anche specificare il nome degli altri registri associati alla porta stessa.

//**************************************************
// GLCD pin constants
//**************************************************

#define GLCD_DATA_WRITE          LATD

#define GLCD_DATA_READ           PORTD
#define GLCD_DATA_DIRECTION      TRISD
#define GLCD_D_I LATAbits.LATA3         
#define GLCD_R_W LATAbits.LATA4                 
#define GLCD_E   LATAbits.LATA5         
#define GLCD_CS1 LATEbits.LATE0         
#define GLCD_CS2 LATEbits.LATE1                 
#define GLCD_RST LATEbits.LATE2
#define GLCD_LED LATCbits.LATC1

Questo risulta necessario poiché il data bus è bidirezionale ed è dunque necessario variare le impostazioni della porta utilizzata al fine di permettere sia la scrittura che la lettura sul data bus. Il cambio di direzione viene effettuato direttamente dalle funzioni che lo richiedono per cui non è necessario avere altri dettagli.

Oltre alla porta per il Data bus sono definiti anche i vari bit di controllo per la gestione del modulo grafico. I pin suggeriti nella libreria sono tali da non creare conflitti o perdita di risorse qualora si faccia uso della scheda di sviluppo Freedom II.

All'interno dell'header file sono dichiarate tutte le funzioni utilizzate. Sebbene il C non permetta di proteggere funzioni interne, dichiarandole private, come è invece possibile in C++, le funzioni sono comunque raggruppate in pubbliche e private. Le funzioni pubbliche sono quelle ad alto livello che  è possibile usare, mentre quelle raggruppate e descritte come private non dovrebbero essere usate visto che entrano nel dettaglio delle specifiche del controllore. Le funzioni pubbliche sono le seguenti:

•    initialize_GLCD
•    clear_GLCD
•    backlight_GLCD
•    set_display_GLCD
•    set_vertical_offset_GLCD
•    plot_xy_GLCD
•    draw_horizontal_line_GLCD
•    draw_vertical_line_GLCD
•    draw_window_GLCD
•    draw_box_GLCD
•    draw_picture_GLCD
•    write_char_GLCD
•    write_string_GLCD
•    write_message_GLCD
•    write_integer_GLCD
•    set_font_GLCD

per brevità non ho riportato il prototipo di funzione ma semplicemente il nome. La descrizione completa è disponibile all'interno della directory doc, presente all'interno della cartella principale della Libreria LaurTec per C18 (scaricabile a fine articolo). La versione attuale della libreria possiede solo le funzioni base per gli oggetti grafici più usati ma versioni future introdurranno ulteriori funzioni. Per tale ragione è sempre bene far riferimento alla documentazione ufficiale della Libreria LaurTec al fine di poter utilizzare la funzione più utile per la propria applicazione.  
La documentazione della libreria è estratta dal codice stesso facendo uso di Doxigen. Questo approccio permette di avere un'unica sorgente per la documentazione e non dover aggiornare più documenti qualora si dovessero apportare modifiche alla libreria.

Faccio notare che avendo a che fare con un display grafico, al fine di visualizzare degli oggetti o semplici caratteri alfanumerici, è necessario specificare le coordinate x,y di origine dell'oggetto stesso. La libreria semplifica il sistema di coordinate emulando un display grafico ad un unico controllore come riportato in Figura 7. Questo permette di avere una più facile visualizzazione degli oggetti in un sistema di riferimento grafico a cui siamo più abituati.

Figura 7:  Modellizzazione del display grafico emulato dalla libreria
Figura 7: Modellizzazione del display grafico emulato dalla libreria.

Facendo riferimento all'esempio riportato a fine articolo è possibile avere una migliore comprensione sul concetto di origine dell'oggetto, posto all'angolo in basso a sinistra dell'oggetto stesso.

Nota:
Prima di poter utilizzare una qualunque funzione della libreria  è necessario richiamare la funzione di inizializzazione.
 

Realizzare immagini e Font per controllore KS0108B

Il controllore KS0108B diversamente dai display alfanumerici non possiede i font di caratteri memorizzai nel controller stesso (alcuni controller grafici possiedono anche un set di font memorizzato all'interno del controller), per cui  è necessario implementarli e memorizzarli all'interno della memoria Flash del microcontrollore utilizzato. La libreria attualmente dispone di un unico font delle dimensioni 5x7. Tale font  è memorizzato all'interno del seguente array:

rom unsigned char font_5x7[96][5]

per mezzo del define ENABLE_FONT_5x7 è possibile includere la tabella del font (normalmente la tabella è inclusa).   

//**************************************************
// Font Tables and Pictures
//**************************************************

#define ENABLE_FONT_5x7
#define ENABLE_LOGO_1


Per non includere la tabella dei font e risparmiare memoria Flash, basta commentare la riga in cui viene definito il define ENABLE_FONT_5x7.

Allo stesso modo dei font è possibile includere delle immagini, a loro volta incluse in array memorizzati in Flash. Per abilitare o meno le immagini  è possibile commentare o meno il define associato al logo d'interesse.

Ogni font  è caratterizzato da una dimensione orizzontale e una verticale. Questa dimensione viene memorizzata all'interno di costanti dedicate. Attualmente essendo disponibile un solo font non ha molto senso questo approccio, ma permette di generalizzare la funzione di scrittura del font, e adattarla ad altre dimensioni semplicemente passando le dimensioni del font stesso.

//**************************************************
// GLCD Font Size
//**************************************************

#define GLCD_FONT_WIDTH_5   5
#define GLCD_FONT_HEIGTH_7  7
#define GLCD_FONT_SPACE 1


Nota:
Variare le dimensioni del font non varia le dimensioni del font disponibile. Una nuova tabella deve essere creata al fine di supportare altri font.

Per realizzare i font sono disponibili molti programmi gratuiti, personalmente ho usato charedit mentre per le immagini ho usato LCD Assistant. Per realizzare una immagine da caricare nell'LCD è necessario prima realizzare un'immagine delle dimensioni 128x64 (per esempio usando Bitmap di Windows). Successivamente bisogna importare l'immagine all'interno di LCD Assistant, o altro programma, ed impostare lo stesso come riportato in Figura 8. Successivamente è possibile salvare l'output.


Figura 8:  Impstazioni di LCD Assistant per realizzare immagini 128x64
Figura 8: Impstazioni di LCD Assistant per realizzare immagini 128x64.

L'immagine viene salvata in una tabella in un file di testo, dal quale è possibile copiare l'array e incollarlo all'interno del proprio progetto. In C18 la definizione dell'array creato da LCD Assistant deve essere cambiato nel seguente modo:

rom unsigned char logo_1 []

In questo modo si garantisce che il compilatore C18 allochi l'array all'interno della memoria Flash. Immagini differenti dovranno naturalmente avere nomi differenti.
Esempi di utilizzo della libreria grafica

Al fine di rendere l'utilizzo della libreria quanto più facile possibile ho evitato di descrivere troppi dettagli relativi al suo funzionamento, ciononostante esorto a leggere i sorgenti della libreria. Spero che il livello di astrazione non abbia creato troppa confusione. Al fine di chiarire il tutto riporto un esempio in cui si fa uso di gran parte delle funzioni e permette di mostrare come sia possibile raggiungere un buon risultato grafico mantenendo il programma piuttosto ordinato. In questo esempio si dovrebbe apprezzare il nome lungo delle funzioni, le quali commentano il codice stesso (Il codice  è scaricabile a fine articolo). L'empio non fa uso di costanti relativamente al posizionamento di un oggetto, cosa che potrebbe essere utile fare in applicazioni professionali.

 

#include "GLCD_KS0108B.h"
#include "GLCD_KS0108B.c"
#include "delay.c"
#pragma config FOSC = HS        
#pragma config WDT = OFF        
#pragma config LVP = OFF        
#pragma config PBADEN = OFF


//OSC = HS      Impostato per lavorare ad alta frequenza
//WDT = OFF     Disabilito il watchdog timer
//LVP = OFF     Disabilito programmazione LVP
//PBADEN = OFF  Disabilito gli ingressi analogici


void main (void){

int i = 0;
// Imposto PORTA
LATA = 0x00;
TRISA = 0x07;
// Set Analog Input come I/O
ADCON1 = 0x0F;
// Imposto PORTB
LATB = 0x00;
TRISB = 0xFF;
// Imposto PORTC
LATC = 0x00;             
TRISC = 0xFD;
// Imposto PORTD tutte uscite

LATD = 0x00;  
TRISD = 0x00;
// Imposto PORTE RE0, RE1, RE2 Output
LATE = 0x00;
TRISE = 0xF8;

initialize_GLCD ();


backlight_GLCD (TURN_ON_LED);


while (1) {

draw_picture_GLCD (logo_1);
draw_window_GLCD ( 0, 0, 127, 63, FILLING_BLACK);
draw_window_GLCD ( 2, 2, 123, 59, FILLING_BLACK);

delay_ms (2000);

clear_GLCD (FILLING_WHITE);

write_message_GLCD (25,28,"Loading...   %");


for (i = 0; i < 100 ; i+= 5) {

write_integer_GLCD (90,28, i, 2);
delay_ms (100);

}

clear_GLCD (FILLING_WHITE);
write_message_GLCD (47,28,"BOOM...");
delay_ms (300);
backlight_GLCD (TURN_OFF_LED);
delay_ms (300);
backlight_GLCD (TURN_ON_LED);
delay_ms (2000);

}

}

 

Il display grafico 128x64 utilizzato per testare la libreria è disponibile alla sezione Servizi del sito.

 

Bibliografia:

1 : Controllore KS0108B: Datasheet

 

Tipo File Scarica File Descrizione

Formato File zip

Download

Esempio di utilizzo della Libreria

Formato File zip

Download Libreria C18 per la gestione di display GLCD basati su controllore KS0108B

 

 

 

 

 

 

 

 

 

 

 

Gravatar
Mauro Laurenti
RE: Libreria per display grafici GLCD con controllore KS0108B
Ottimo lavoro! Vediamo se in futuro riuscirò ad aggiornare la libreria.Saluti,Mauro
0
Gravatar
Antonino
Aggiunta funzione
Ciao Mauro, ho aggiunto una funzione per disegnare loghi o caratteri con dimensioni 16x16https://www.laurtec.it/forum/19-progetti/7837-modifica-libreria-laurtec-glcd-per-pic16f877a-e-glcd-192x64/unreadCiao e grazie
0
Gravatar
Mauro Laurenti
RE: Libreria per display grafici GLCD con controllore KS0108B
...ottimo!Saluti,M auro
0
Gravatar
Antonino
RE: Libreria per display grafici GLCD con controllore KS0108B
Post fatto :-) https://www.laurtec.it/forum/19-progetti/7837-modifica-libreria-laurtec-glcd-per-pic16f877a-e-glcd-192x64#14237
0
Gravatar
Antonino
RE: Libreria per display grafici GLCD con controllore KS0108B
Perfetto in serata lo faccio.Metterò anche una breve spiegazione dei problemi incontrati.Saluti Nino
0
Gravatar
Mauro Laurenti
RE: Libreria per display grafici GLCD con controllore KS0108B
Salve Nino,credo che la seguente sezione sia l'ottimale:Forum -> Sistemi Embedded e Programmazione -> ProgettiSaluti, Mauro
0
Gravatar
Antonino
RE: Libreria per display grafici GLCD con controllore KS0108B
Dimmi dove la devo postare e io la posto lol
0
Gravatar
Mauro Laurenti
RE: Libreria per display grafici GLCD con controllore KS0108B
Ciao Nino,se la libreria discende dalla mia non ci sono problemi di licenza...acconsentendo alla pubblicazione! :)....perche' non la posti sul Forum?Saluti,Mauro
0
Gravatar
Antonino
Grazie Mauro
Volevo ringraziarti per il lavoro che fai per noi.Oltre a questo volevo comunicare che ho modificato con successo la tua libreria per poterla utilizzare, su PIC16F877A e dispaly grafico 192x64 della Winstar WG19264E-YYH-V#N con controller NT7108C (equivalente al KS0108B), eventualmente posso postartela.Ho utilizzato Mplab X e Hi-Tech 9.82.Questo display ha i comandi del Chip Select invertiti ossia si attivano portandoli a 0.Saluti Nino
0

You don`t have permission to comment here!