Programació en C del PIC 16F690

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

Exemple PS - Pantalla LCD amb connexió sèrie

En aquest exemple volem enviar unes lletres a la pantalla. En el programa següent enviem "PIC" a la primera línia i "kit" a la segona. Hem posat els caràcters a enviar en el propi cos del programa però els podíem haver posat a la memòria de programa o a la memòria EEPROM i fer el programa més curt.

#pragma config FOSC = INTRCIO, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP = OFF
#pragma config CPD = OFF, BOREN = OFF, IESO = OFF, FCMEN = OFF
#include <xc.h>					// Carrega el fitxer de funcions necessari per al compilador XC8
#define _XTAL_FREQ  4000000			// La freqüència del rellotge és 4 MHz
						// 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 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
	__delay_ms(2000);			// Esperem que arrenqui la pantalla
	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ó
	Esborra();				// Esborra la pantalla i posa el cursor a l'inici
	EnviaL('P');				// Lletra
	EnviaL('I');				// Lletra
	EnviaL('C');				// Lletra
	Cursor(2, 1);				// Posició
	EnviaL('k');				// Lletra
	EnviaL('i');				// Lletra
	EnviaL('t');				// Lletra
	while (1)				// Mentre el contingut del parèntesi sigui 1
		;				// repetirà aquesta línia (es bloqueja aquí)
}
void EnviaL(char Caracter) {
	TXREG = Caracter;			// Agafa el caràcter i l'envia
	__delay_ms(1);				// Donem temps
	while (PIR1bits.TXIF == 0)		// Esperem 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
}

Atenció: en alguns casos hem detectat problemes causats perquè s'envien coses a la pantalla abans que aquesta s'acabi d'inicialitzar. Si es detecta un mal funcionament de la pantalla, és recomanable posar un retard, per exemple d'aproximadament un segon, a l'inici del main.

La funció EnviaT ens permet enviar un text. El següent exemple combina les dues formes d'enviament.

#pragma config FOSC = INTRCIO, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP = OFF
#pragma config CPD = OFF, BOREN = OFF, IESO = OFF, FCMEN = OFF
#include <xc.h>					// Carrega el fitxer de funcions necessari per al compilador XC8
#define _XTAL_FREQ  4000000			// La freqüència del rellotge és 4 MHz
						// Definició de les funcions que farem servir 
void EnviaL(char Caracter);			// Envia un caràcter
void EnviaT(const char* text);			// Envia un text
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 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
	__delay_ms(2000);			// Esperem que arrenqui la pantalla
	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ó
	Esborra();				// Esborra la pantalla i posa el cursor a l'inici
	EnviaL('P');				// Lletra
	EnviaL('I');				// Lletra
	EnviaL('C');				// Lletra
	Cursor(2, 1);				// Posició
	EnviaT("kit");				// Envia un text
	while (1)				// Mentre el contingut del parèntesi sigui 1
		;				// repetirà aquesta línia (es bloqueja aquí)
}
void EnviaL(char Caracter) {
	TXREG = Caracter;			// Agafa el caràcter i l'envia
	__delay_ms(1);				// Donem temps
	while (PIR1bits.TXIF == 0)		// Esperem que s'acabi d'enviar
		;				// No fem res
}
void EnviaT(const char* text) {
	for (unsigned char i = 0; text[i] != '\0'; i++) {
		EnviaL(text[i]);		// Envia caràcter a caràcter
	}
}
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
}

Cal tenir present que el text no es pot modificar al llarg del programa.

En la següent versió de l'exemple hem afegit un caràcter especial (la lletra Ω) que l'hem guardat a la posició 0 de la taula de caràcters. Aquesta Ω la fem sortir a la posició 16 de la primera línia i també a la posició 15 de la segona.

#pragma config FOSC = INTRCIO, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP = OFF
#pragma config CPD = OFF, BOREN = OFF, IESO = OFF, FCMEN = OFF
#include <xc.h>					// Carrega el fitxer de funcions necessari per al compilador XC8
#define _XTAL_FREQ  4000000			// La freqüència del rellotge és 4 MHz
						// 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};
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
	__delay_ms(2000);			// Esperem que arrenqui la pantalla
	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ó
	DefCarac(0, Omega);			// Defineix caràcter
	Esborra();				// Esborra la pantalla i posa el cursor a l'inici
	EnviaL('P');				// Lletra
	EnviaL('I');				// Lletra
	EnviaL('C');				// Lletra
	Cursor(2, 1);				// Posició
	EnviaL('k');				// Lletra
	EnviaL('i');				// Lletra
	EnviaL('t');				// Lletra
	Cursor(1, 16);				// Posició
	EnviaL(0);				// Omega
	Cursor(2, 15);				// Posició
	EnviaL(0);				// Omega
	while (1)				// Mentre el contingut del parèntesi sigui 1
		;				// repetirà aquesta línia (es bloqueja aquí)
}
void EnviaL(char Caracter) {
	TXREG = Caracter;			// Agafa el caràcter i l'envia
	__delay_ms(1);				// Donem temps
	while (PIR1bits.TXIF == 0)		// Esperem 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 = Numero * 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 (signed char k = 0; k < 8; k++){
		EnviaL(Fileres[k]);		// Envia el caràcter
	}
}

El següent programa fa el mateix que el primer que hem vist però guardant els textos en vectors.

#pragma config FOSC = INTRCIO, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP = OFF
#pragma config CPD = OFF, BOREN = OFF, IESO = OFF, FCMEN = OFF
#include <xc.h>					// Carrega el fitxer de funcions necessari per al compilador XC8
#define _XTAL_FREQ  4000000			// La freqüència del rellotge és 4 MHz
						// 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)
char nom1[3] = {'P', 'I', 'C'};
char nom2[3] = {'k', 'i', 't'};
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
	__delay_ms(2000);			// Esperem que arrenqui la pantalla
	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ó
	Esborra();				// Esborra la pantalla i posa el cursor a l'inici
	for (signed char k = 0; k < 3; k++){
		EnviaL(nom1[k]);
	}
	Cursor(2, 1);				// Posició
	for (signed char k = 0; k < 3; k++){
		EnviaL(nom2[k]);
	}
	while (1)				// Mentre el contingut del parèntesi sigui 1
		;				// repetirà aquesta línia (es bloqueja aquí)
}
void EnviaL(char Caracter) {
	TXREG = Caracter;			// Agafa el caràcter i l'envia
	__delay_ms(1);				// Donem temps
	while (PIR1bits.TXIF == 0)		// Esperem 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
}

En aquest cas, sí és possible modificar els textos al llarg del programa.

 

 

Llicència de Creative Commons
Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.