Programació en C del PIC 16F690 amb PICkit 2

.
Referència Trucs Perifèrics  Recursos CITCEA
Tutorial Exemples Projectes   Inici

Pantalla LCD amb connexió sèrie

Anem a afegir una pantalla LCD al nostre microcontrolador. Les pantalles LCD porten normalment un circuit integrat que les controla (un altre microcontrolador) que permet que nosaltres li enviem la configuració i els caràcters a mostrar. Si no hi hagués aquest circuit integrat, nosaltres hauríem de controlar tots els punts (píxels) de la pantalla i ens faltarien ports.

Els controladors de pantalla es poden comunicar amb el microcontrolador en sèrie o en paral·lel.

La comunicació paral·lel requereix un conjunt de quatre o vuit bits de dades i entre dos i quatre bits de control; per tant haurem de reservar entre sis i dotze potes dels ports del microcontrolador. Té l'avantatge que els bits s'envien tots d'un cop i, per tant, la programació és més senzilla.

La comunicació sèrie es fa enviant els bits un darrere l'altre i, per tant, cal gestionar el canal de comunicació. Amb comunicació sèrie la programació és més complexa però es necessiten molt poques potes (normalment dues o tres) per a la comunicació.

Aquest apartat es basa en les pantalles sèrie de 16 per 2 de l'empresa Sparkfun. En el cas de les pantalles, més important que el full de característiques de la pantalla és el full de característiques del controlador. Podeu trobar la taula de caràcters que porta implementats a la pàgina 17 d'aquest full de característiques.

Per connectar la pantalla amb el microcontrolador, cal fer les següents connexions:

Pantalla Microcontrolador
Nom Nom Pota
VDD (+5 V) Vdd (+5 V) 1
GND Vss (+5 V) 20
RX TX (RB7) 10

Per enviar dades a la pantalla ens caldrà una transmissió sèrie a 9600 bauds.

La pantalla ja està preconfigurada de fàbrica. Si ens estan bé els valors per defecte ja podem començar a enviar-li caràcters que ens apareixeran a la primera columna de la primera filera i posicions successives.

Caràcters i posició a la pantalla

El controlador de la pantalla té una memòria per als caràcters que es visualitzen. Cada posició de la pantalla correspon a un byte a la memòria però no tots els bytes de la memòria es visualitzen.

La primera línia de la pantalla comença a l'adreça 0. En pantalles de dues línies, la segona línia comença a la 64 (decimal). Si la pantalla té més línies, la tercera començarà a 20 i la quarta a 84. En una pantalla de 16 caràcters per línia es visualitzaran a la primera línia les posicions 0 a 15.

La taula de caràcters és, en principi, la dels codis ASCII. Per tant per als caràcters normals podem treballar directament en ASCII. Algunes de les adreces que en els codis ASCII no hi són (més de 7Fh) o algunes de les que corresponen a caràcters de control contenen símbols que el fabricant de la pantalla ha decidit posar-hi.

Enviament de caràcters

L'enviament de caràcters és molt senzill, un cop hem configurat la comunicació sèrie. En el següent tros de programa veiem la configuració sèrie i com s'envia un caràcter. A l' exemple PS hi tenim un programa complet.

						// Definició de les funcions que farem servir 
void EnviaL(char Caracter);			// Envia un caràcter
void main (void) {
	ANSEL = 0b00000101;			// Configura AN0 i AN2 com entrada analògica
	ANSELH = 0;				// Desactiva les altres entrades analògiques
	TRISC = 0;				// Tot el port C és de sortida
	TRISB = 0;				// Tot el port B és de sortida
	TXSTAbits.BRGH = 1;			// Configuració de velocitat
	BAUDCTLbits.BRG16 = 0;			// Paràmetre de velocitat de 8 bits
	SPBRG = 25;				// Velocitat de 9600 baud
	TXSTAbits.SYNC = 0;			// Comunicació asíncrona
	TXSTAbits.TX9 = 0;			// Comunicació de 8 bits
	RCSTAbits.SPEN = 1;			// Activa comunicació sèrie
	TXSTAbits.TXEN = 1;			// Activa comunicació
	EnviaL('P');				// Lletra
...
}
void EnviaL(char Caracter) {
	TXREG = Caracter;			// Agafa el caràcter i l'envia
	_delay(5);				// Donem temps
	while (PIR1bits.TXIF == 0);		// Esperem a que s'acabi d'enviar
		;				// No fem res
}
...

Caràcters de control

Hi ha uns quants caràcters que permeten canviar les característiques de la pantalla o de la visualització. Cal enviar un caràcter de control FE (254 decimal) seguit del codi de control que ens fa falta. Els codis estan a la taula següent:

Primer caràcter de control Segon caràcter de control Funció
decimal hexadecimal decimal hexadecimal
254 FE 1 01 Esborra la pantalla i posa el cursor a l'inici
254 FE 20 14 Mou el cursor una posició a la dreta
254 FE 16 10 Mou el cursor una posició a l'esquerra
254 FE 28 1C Desplaça a la dreta
254 FE 24 18 Desplaça a l'esquerra
254 FE 12 0C Activa la visualització
254 FE 8 08 Desactiva la visualització
254 FE 14 0E Activa la visualització del cursor subratllat
254 FE 13 0D Activa la visualització del cursor intermitent
254 FE 12 0C Desactiva la visualització del cursor

Les adreces de la memòria són de set bits (0 a 6). Per dir-li al controlador a quina adreça volem escriure cal enviar-li un caràcter de control FE (254 decimal) seguit del valor de l'adreça però amb el bit 7 a 1. Així per demanar-li que es posi a la primera posició (adreça 0, o sigui 00000000) li enviarem el caràcter de control seguit de 10000000. Un cop li hem dit la posició i hem escrit un caràcter, el següent es posarà al costat. Per tant només hem de canviar l'adreça quan la posició no sigui consecutiva. A continuació hi ha un tros de programa com a exemple:

						// Definició de les funcions que farem servir 
void EnviaL(char Caracter);			// Envia un caràcter
void Esborra(void);				// Esborra la pantalla i posa el cursor a l'inici
void Cursor(char Filera, char Columna);		// Posiciona el cursor (filera 1 a 2 i columna 1 a 32, segons pantalla)
...
	Cursor(2, 1);				// Posició
...
void EnviaL(char Caracter) {
	TXREG = Caracter;			//  Agafa el caràcter i l'envia
	_delay(5);				// Donem temps
	while (PIR1bits.TXIF == 0);		// Esperem a que s'acabi d'enviar
		;				// No fem res
}
void Esborra(void) {
	EnviaL(254);				// Caràcter de control
	EnviaL(1);				// Esborra la pantalla i posa el cursor a l'inici
}
void Cursor(char Filera, char Columna) {
	char Posicio = 0;			// Variable per a calcular la posició
	if (Filera == 2) {
		Posicio = 64;			// La primera columna de la segona fila és 64;
	}
	if (Columna > 0 && Columna < 33) {	// Comprovem que sigui un valor raonable
		Posicio = Posicio + Columna;	// Sumem les adreces
		Posicio = Posicio - 1;		// Restem 1 perquè numera des de 0
	}
	Posicio = Posicio + 128;		// Posa el bit de posicionat a 1
	EnviaL(254);				// Control de la posició del cursor
	EnviaL(Posicio);			// Canvia el cursor de lloc
}

Caràcters especials

La pantalla pot mostrar fins a 8 caràcters definits per l'usuari. Aquests caràcters són adreçables amb els codis ASCII del 0 (00h) al 7 (07h).

Per crear els caràcters cal enviar una seqüencia de vuit bytes amb el patró corresponent. Els caràcters són de 5 per 8 píxels (punts) o sigui que hem d'enviar vuit valors en els que els tres primers bits (5, 6 i 7) són 0 i els altres cinc (0 a 5) són 1 si volem el punt activat i 0 si el volem desactivat. La següent figura mostra els 8 bytes que caldrien per crear la lletra Ω.

Caràcter especial omega

Els caràcters especials es guarden a una altra part de la memòria de la pantalla. El primer caràcter s'ha de colocar a les adreces 00h a 07h, el segon a les 08h a 0Fh i així successivament. El vuitè anirà de la 38h a la 3Fh.

El vuitè byte normalment ha d'estar a zero ja que allí és on ha d'aparèixer el subratllat del cursos. És recomanable que estigui a zero perquè en alguns programes hem detectat caràcters anòmals a la pantalla si no ho estaven.

Les adreces de la memòria on es guarden els caràcters especials són de sis bits (0 a 5). Per dir-li al controlador a quina adreça volem escriure cal enviar-li un caràcter de control (254, o sigui FEh) seguit del valor de l'adreça però amb el bit 7 a 0 i el 6 a 1. Així per demanar-li que es posi a la primera posició (adreça 00h, 00000000) li enviarem el caràcter de control 01000000. Un cop li hem dit la posició i hem escrit un byte, el següent es posarà al costat. Per tant només hem de canviar l'adreça quan la posició no sigui consecutiva.

A continuació hi ha un tros de programa com a exemple:

						// Definició de les funcions que farem servir 
void EnviaL(char Caracter);			// Envia un caràcter
void Esborra(void);				// Esborra la pantalla i posa el cursor a l'inici
void Cursor(char Filera, char Columna);		// Posiciona el cursor (filera 1 a 2 i columna 1 a 32, segons pantalla)
void DefCarac(char Numero, char Fileres[8]);	// Crea un caràcter definit per l'usuari
char Omega[8] = {0b00000000, 0b00001110, 0b00010001, 0b00010001, 0b00001010, 0b00001010, 0b00011011, 0b00000000};
...
	DefCarac(0, Omega);			// Defineix caràcter
...
	Cursor(1, 1);				// Posició
	EnviaL(0);				// Omega
...	
}
void EnviaL(char Caracter) {
	TXREG = Caracter;			//  Agafa el caràcter i l'envia
	_delay(5);				// Donem temps
	while (PIR1bits.TXIF == 0);		// Esperem a que s'acabi d'enviar
		;				// No fem res
}
void Esborra(void) {
	EnviaL(254);				// Caràcter de control
	EnviaL(1);				// Esborra la pantalla i posa el cursor a l'inici
}
void Cursor(char Filera, char Columna) {
	char Posicio = 0;			// Variable per a calcular la posició
	if (Filera == 2) {
		Posicio = 64;			// La primera columna de la segona fila és 64;
	}
	if (Columna > 0 && Columna < 33) {	// Comprovem que sigui un valor raonable
		Posicio = Posicio + Columna;	// Sumem les adreces
		Posicio = Posicio - 1;		// Restem 1 perquè numera des de 0
	}
	Posicio = Posicio + 128;		// Posa el bit de posicionat a 1
	EnviaL(254);				// Control de la posició del cursor
	EnviaL(Posicio);			// Canvia el cursor de lloc
}
void DefCarac(char Numero, char Fileres[8]) {
	char Posicio = 0;			// Variable per a calcular la posició
	if (Numero  < 8) {	// Comprovem que sigui un valor raonable
		Posicio = Posicio * 8;	// Calculem l'adreça de memòria
	}
	Posicio = Posicio + 64;		// Posa el bit de caràcter especial a 1
	EnviaL(254);				// Control de la posició del cursor
	EnviaL(Posicio);			// Canvia el cursor de lloc
	for (int k = 0; k < 8; k++){
		EnviaL(Fileres[k]);			// Canvia el cursor de lloc
	}
}

 

 

Licencia de Creative Commons
This obra by Oriol Boix is licensed under a Creative Commons Reconocimiento-NoComercial-SinObraDerivada 3.0 Unported License.