PIC32_09_LCD_GRAFICO.pdf

16
8 - Display Gráfico Ing. Juan Ramon Terven Salinas 137 8 DISPLAY LCD GRÁFICO En el capítulo 4 se utilizó un display LCD alfanumérico para mostrar información en forma de texto. En este capítulo aprenderemos a usar un display LCD gráfico monocromático en el cual es posible dibujar cualquier cosa modificando los pixeles individuales. El display que usaremos es el display gráfico que posee el teléfono celular Nokia 1100 mostrado en la Figura 8-1. Figura 8-1. Nokia 1100 Se trata de un display LCD gráfico de 96 pixeles de ancho por 65 pixeles de alto. La Figura 8-2 muestra la apariencia física de la pantalla y la manera de identificar los pines. La Figura 8-3 muestra el nombre y número de los pines del display visto de frente.

Transcript of PIC32_09_LCD_GRAFICO.pdf

8 - Display Gráfico

Ing. Juan Ramon Terven Salinas 137

8 DISPLAY LCD GRÁFICO

En el capítulo 4 se utilizó un display LCD alfanumérico para mostrar información

en forma de texto. En este capítulo aprenderemos a usar un display LCD gráfico

monocromático en el cual es posible dibujar cualquier cosa modificando los pixeles

individuales.

El display que usaremos es el display gráfico que posee el teléfono celular Nokia

1100 mostrado en la Figura 8-1.

Figura 8-1. Nokia 1100

Se trata de un display LCD gráfico de 96 pixeles de ancho por 65 pixeles de alto. La

Figura 8-2 muestra la apariencia física de la pantalla y la manera de identificar los pines.

La Figura 8-3 muestra el nombre y número de los pines del display visto de frente.

8 - Display Gráfico

Ing. Juan Ramon Terven Salinas 138

Figura 8-2. Display LCD gráfico

Figura 8-3. Pines del LCD1100

8 - Display Gráfico

Ing. Juan Ramon Terven Salinas 139

La Figura 8-4 muestra la conexión que usaremos con el PIC32. Como se puede observar

en esta figura, solamente se necesitan 3 pines del PIC para controlar el display LCD, ya

que la comunicación se realiza de manera serial usando los pines CLK y DATA. El

tercer pin RESET se usa para la configuración del display.

Figura 8-4. Conexión de display LCD gráfico con PIC32

8 - Display Gráfico

Ing. Juan Ramon Terven Salinas 140

Comunicación con el Display Gráfico

La comunicación con el display se realiza de manera serial usando los pines CLK

(SCLK) y DATA (SDA). La Figura 8-5 muestra el diagrama de tiempos de cómo se

debe de transmitir la información entre el microcontrolador y el display.

Como se observa en esta figura, primero se debeenviar un bit llamado D/C que

indica al LCD si el byte siguiente es un dato (D=1) o es un comando (C=0). Luego se

envía bit a bit el byte que representa el dato o el comando. Observe que el

microcontrolador debe generar las señales SCLK y SDA, generando los cambios en

SDA cuando SCLK se encuentra en nivel bajo para que el LCD muestrie el bit en cada

flanco ascendente.

Figura 8-5. Transmisión de datos [22]

La función writeLCD1100 que se muestra a continuación realiza la transmisión de un

dato o comando respetando los tiempos mostrados en la Figura 8-5.

Por ejemplo si se desea enviar el comando 5, se usaría la función de la siguiente

manera:

writeLCD1100(0,5); //el primer parámetro indica si es comando o dato

//el segundo parámetro es el comando o dato

8 - Display Gráfico

Ing. Juan Ramon Terven Salinas 141

Programa 8-1. Función writeLCD1100 //////////////////////////////////////////////////////////////////// // Funcion: writeLCD1100 // // Escribe un dato de bajo nivel // Entrada: // cd: bit de control, indica si es un comando o un dato // c: byte de dato a enviar // // Salida: Nada //////////////////////////////////////////////////////////////////// void writeLCD1100(int8_t dc,uint8_t c) { int8_t i; //Envia D/C pin_clk = 0; //clk en 0 pin_data = dc; //coloca bit DC en DATA pin_clk = 1; //clk en 1 delayusLCD1100(); //retardo //clk en 0 pin_clk = 0; // enviar byte de control/dato for(i=0;i<8;i++) { //coloca bit en DATA if(c & 0x80) pin_data = 1; else pin_data = 0; pin_clk = 1; //sube clk delayusLCD1100(); //retardo pin_clk = 0; //clk en 0 //cambia el bit c <<= 1; } } //writeLCD1100

8 - Display Gráfico

Ing. Juan Ramon Terven Salinas 142

Display Data RAM (DDRAM)

El display LCD posee una memoria RAM interna llamada DDRAM la cual almacena

los pixeles que se desean mostrar. Existe una correspondencia directa entre la DDRAM

y el display como se muestra en la Figura 8-6. En donde cada bit de la memoria

DDRAM se corresponde con un pixel en el display.

Figura 8-6. Correspondencia entre DDRAM y Display [22]

La memoria DDRAM está dividida en 96 columnas (de la 0 a la 95) y 9 páginas (de la 0

a la 8) donde cada página equivale a los 8 bits (8 pixeles) del byte enviado. La Figura

8-7 muestra el arreglo de columnas y páginas de la DDRAM.

Figura 8-7. Descripción de la DDRAM

8 - Display Gráfico

Ing. Juan Ramon Terven Salinas 143

Funcionamiento del Display Gráfico

Si queremos dibujar algo en el display (prender pixeles) debemos enviar los bytes a

la columna y a la página deseada, donde los ‘1’s de los bytes enviados indican pixeles

oscuros y los ‘0’s indican pixeles claros.

Por ejemplo, suponga que la cuadrícula que se muestra en la la Figura 8-8 es el

display gráfico, donde cada cuadrito es un pixel; se desean activar los 3 pixeles que se

muestran. Primero debemos identificar en que columna y en que página se encuentran,

en este caso la columna 4 y la página 0.

Luego debemos identificar que dato debo enviar para activar esos 3 pixeles. De la

columna 4, página 0 vemos que los bits con valor de 2,4 y 8 deben ser ‘1’ por lo tanto,

el dato a enviar es 2+4+8 = 14

Finalmente debemos escribir un 14 en la columna y página seleccionadas.

Figura 8-8. Ejemplo

8 - Display Gráfico

Ing. Juan Ramon Terven Salinas 144

Para seleccionar la columna se usa el comando Column Addres Set mostrado en la Tabla 8-1.

Tabla 8-1. Comando Column Address Set [22]

Por ejemplo para seleccionar la columna 4 usaríamos la función anterior de la siguiente

manera:

writeLCD1100(0,0x10); //comando Column Address Set

writeLCD1100(0,0x4); //columna 4

El comando PageAddres Set se usa para seleccionar la página. Se muestra en la Tabla

8-2.

Tabla 8-2. Comando Page Address Set [22]

Por ejemplo para seleccionar la página 0:

writeLCD1100(0,0xB0); //página 0

Finalmente para escribir el 14 en la DDRAM se usa el comando Display Data Write

mostrado en la Tabla 8-3.

Tabla 8-3. Display Data Write [22]

Para escribir el dato en la DDRAM simplemente usamos la función de la siguiente

manera:

writeLCD1100(1,14); //Escribe un 14 en la DDRAM

8 - Display Gráfico

Ing. Juan Ramon Terven Salinas 145

Cada vez que se escribe un dato en la DDRAM, el número de columna aumenta

automáticamente y al llegar a la última aumenta la página. Por lo tanto podemos escribir

datos de manera consecutiva.

Por ejemplo si queremos borrar todo el contenido de la pantalla (y por lo tanto de la

DDRAM) podemos hacerlo de la siguiente manera:

// Columna 0 writeLCD1100(0,0x10); writeLCD1100(0,0); // Fila 0 writeLCD1100(0,0xB0); //cicla borrando todo el contenido de la DDRAM for(pag=0; pag<9; pag++) for(col=0; col<65; col++) writeLCD1100(1,0);

8 - Display Gráfico

Ing. Juan Ramon Terven Salinas 146

Librería LCD_1100

Se desarrolló una librería llamada lcd_1100.h la cual posee un conjunto de

funciones útiles que nos servirán para utilizar el display LCD. La Tabla 8-4 muestra una

lista con las funciones contenidas en esta librería y una breve descripción.

Tabla 8-4. Funciones de libreria LCD_1100

Nombre de función Descripción

openLCD1100 Inicializa el LCD gráfico.

writeLCD1100 Escribe un dato o comando en el display.

putcLCD1100 Escribe un caracter en el buffer de la pantalla en las

coordenadas x,y.

putsLCD1100 Escribe una cadena en el buffer de la pantalla a partir

de las coordenadas x,y.

paintLCD1100 Pinta el contenido del buffer en display.

clearBufferLCD1100 Limpia el contenido del buffer del display.

putPixelLCD1100 Dibuja un pixel en las coordenadas x,y.

lineLCD1100 Dibuja una linea usando el algoritmo de Bresenham.

writeRawBufferLCD1100 Escribe un dato de 8 bits en la pagina y columna

especificada del buffer del LCD.

paintPictureLCD1100 Dibuja una imagen en el buffer del LCD.

recorreUpLCD1100 Recorre LCD hacia arriba la cantidad de pixeles

especificada.

getAnchoFuenteLCD1100 Regresa el ancho en pixeles de la fuente seleccionada.

getAltoFuenteLCD1100 Regresa el alto en pixeles de la fuente seleccionada.

getSizeFuenteLCD1100 Regresa el tamaño de la fuente que puede ser:

TAM_CHICA, TAM_MEDIANA o TAM_GRANDE

setSizeFuenteLCD1100 Ajusta el tamaño de la fuente que puede ser:

TAM_CHICA, TAM_MEDIANA o TAM_GRANDE

powerSaveOnLCD1100 Coloca el display en modo de bajo consumo.

powerSaveOffLCD1100 Coloca el display en modo normal.

8 - Display Gráfico

Ing. Juan Ramon Terven Salinas 147

Ejemplo 1. Uso de Display LCD Gráfico

El siguiente ejemplo muestra el uso del display gráfico para mostrar texto y líneas. La

siguiente figura muestra la conexión del display con el PIC32.

Figura 8-9. Conexión de display LCD con PIC32

Programa 8-2. Ejemplo 1 /* USO DE DISPLAY LCD GRAFICO DE 96 x 65 NOKIA 1100 */ #include <p32xxxx.h> #include "../librerias/LCD_1100/lcd_1100.h" //Bits de configuracion #pragma config POSCMOD = HS, FNOSC = PRIPLL, FPLLMUL = MUL_20 #pragma config FPLLIDIV = DIV_2, FPLLODIV = DIV_1 #pragma config FPBDIV = DIV_1, FWDTEN = OFF, UPLLEN = ON #pragma config UPLLIDIV = DIV_2, FVBUSONIO = ON, FUSBIDIO = ON #pragma config FSOSCEN = OFF, CP = OFF, FCKSM = CSECMD int main(void) { short i; AD1PCFG = 0xFFFF; // configura pines AN como digitales // Inicializa el display LCD gráfico openLCD1100(); //Ajusta el tamaño de la letra setSizeFuenteLCD1100(TAM_MEDIANA); //Limpia el buffer del LCD clearBufferLCD1100(); //Escribe en el buffer del LCD putsLCD1100(1,0," DISPLAY LCD "); //Ajusta fuente chica setSizeFuenteLCD1100(TAM_CHICA); putsLCD1100(1,20,"PROBANDO FUENTE CHICA"); //Ajusta fuente mediana setSizeFuenteLCD1100(TAM_MEDIANA);

8 - Display Gráfico

Ing. Juan Ramon Terven Salinas 148

putsLCD1100(1,30,"FUENTE MEDIANA"); //Ajusta fuente grande setSizeFuenteLCD1100(TAM_GRANDE); putsLCD1100(1,45,"GRANDE"); //Refresca el LCD paintLCD1100(); retardoms(2000); //Dibuja líneas lineLCD1100(0,0,95,64); paintLCD1100(); retardoms(500); lineLCD1100(0,64,95,0); paintLCD1100(); //Recorre display hacia arriba for(i=0; i<64; i++) { recorreUpLCD1100(1); paintLCD1100(); retardoms(50); } //Limpia el buffer del LCD clearBufferLCD1100(); //Escribe texto setSizeFuenteLCD1100(TAM_GRANDE); putsLCD1100(20,20,"DISPLAY"); putsLCD1100(10,40,"NOKIA 1100"); paintLCD1100(); while(1) { } return 0; }

8 - Display Gráfico

Ing. Juan Ramon Terven Salinas 149

Ejemplo 2. The Matrix

El siguiente ejemplo muestra el uso del display gráfico para mostrar texto aleatorio

desplazandose en columnas aleatorias dando un efecto similar a la Matrix.

Para generar números aleatorios se usó la función rand de la librería stdlib.h, la

cual regresa un número aleatorio entre 0 y 232-1.

/* THE MATRIX */ #include <p32xxxx.h> #include <stdlib.h> #include "../librerias/LCD_1100/lcd_1100.h" //Bits de configuracion #pragma config POSCMOD = HS, FNOSC = PRIPLL, FPLLMUL = MUL_20 #pragma config FPLLIDIV = DIV_2, FPLLODIV = DIV_1 #pragma config FPBDIV = DIV_1, FWDTEN = OFF, UPLLEN = ON #pragma config UPLLIDIV = DIV_2, FVBUSONIO = ON, FUSBIDIO = ON #pragma config FSOSCEN = OFF, CP = OFF, FCKSM = CSECMD char aleatorio(char inicio, char fin); int main(void) { char col, car, i; char renglones[25] = {0}; // 1 renglon por cada columna que cabe en el display AD1PCFG = 0xFFFF; // configura pines AN como digitales //Ajusta la semilla para la generación de numeros aleatorios srand(5); //Inicializa el display gráfico openLCD1100(); // Inicializa el display LCD gráfico setSizeFuenteLCD1100(TAM_CHICA); //Ajusta el tamaño de la letra clearBufferLCD1100(); //Limpia el buffer del LCD while(1) { //selecciona un caracter aleatoriamente car = aleatorio(33,120); //selecciona una columna aleatoriamente col = aleatorio(0,24); //Borra 10 renglones de la columna seleccionada for(i=0; i<10; i++) putcLCD1100(col*4,(renglones[col]+i)*(getAltoFuenteLCD1100()+1), ' '); //Dibuja el caracter aleatorio en la columna aleatoria //en el renglon que se quedó esa columna putcLCD1100(col*4,renglones[col]*(getAltoFuenteLCD1100()+1), car); paintLCD1100(); //Incrementa el renglon de la columna escogida aleatoriamente renglones[col]++; //Reinicia el renglon en caso de llegar al final if(renglones[col] > 10) //9 renglones con letra chica renglones[col] = 0; retardoms(20); } return 0; }

8 - Display Gráfico

Ing. Juan Ramon Terven Salinas 150

// Genera un número aleatorio en el rango [inicio , fin] char aleatorio(char inicio, char fin) { int salida8, salida32; float salidaf; salida32 = rand(); salidaf = (float)salida32/RAND_MAX; salida8 = (char)(salidaf*(fin-inicio) + inicio); }

Dibujar Imágenes en Display LDC Gráfico

La librería lcd_1100.h incluye una función llamada

paintPictureLCD1100, la cual puede ser usada para dibujar una imagen de 96x65

pixeles. Dicha imagen es un arreglo tipo unsigned char de 864 valores (96 columnas x 9

páginas), donde cada valor es una columna del display.

Para generar este arreglo de valores a partir de una imagen podemos usar un

programa como el LCD.EXE que se muestra en la Figura 8-10. Este programa permite

abrir una imagen en formato BMP (comando Abrir BMP) y generar los valores de cada

columna del display (Guardar H).

Figura 8-10. LCD.exe

8 - Display Gráfico

Ing. Juan Ramon Terven Salinas 151

Ejemplo 3. Dibujar Imagen en LCD

El siguiente ejemplo dibuja la imagen mostrada a continuación usando la función

paintPictureLCD1100. Para generar el arreglo de valores se usó el programa

LCD.EXE mencionado anteriormente.

Programa 8-3. Dibuja Imagen en LCD /* DIBUJA IMAGENES EN DISPLAY LCD GRÁFICO NOKIA 1100 */ #include <p32xxxx.h> #include "../librerias/LCD_1100/lcd_1100.h" //Bits de configuracion #pragma config POSCMOD = HS, FNOSC = PRIPLL, FPLLMUL = MUL_20 #pragma config FPLLIDIV = DIV_2, FPLLODIV = DIV_1 #pragma config FPBDIV = DIV_1, FWDTEN = OFF, UPLLEN = ON #pragma config UPLLIDIV = DIV_2, FVBUSONIO = ON, FUSBIDIO = ON #pragma config FSOSCEN = OFF, CP = OFF, FCKSM = CSECMD unsigned char imagen1[864]={ 255,117,63,17,97,49,145,31,43,117,43,21,127,49,145,33,97,191,27,21,235,181,31,17,113,33,17,31,43,245,107,53,31,145,33,97,161,95,43,149,155,21,63,97,161,97,29,131,93,33,33,81,159,21,27,53,155,159,33,97,161,225,95,53,43,53,107,223,97,33,17,17,63,53,107,181,107,63,17,145,17,33,95,181,59,21,235,223,161,97,33,145,31,53,235,255,255,255,0,0,254,135,255,127,0,255,0,0,254,69,63,159,192,255,0,0,255,255,0,0,254,255,254,0,0,255,0,0,255,197,255,158,1,0,159,213,223,159,214,51,209,216,55,231,0,0,231,238,255,0,0,207,157,159,207,224,63,1,0,62,175,54,172,254,255,0,0,63,63,158,192,255,224,128,15,55,79,132,254,255,0,0,255,113,136,68,62,63,0,0,255,255,255,255,0,0,249,25,28,236,255,255,0,0,254,120,227,141,63,127,0,0,127,63,0,128,191,255,191,128,128,159,184,224,207,153,191,159,208,224,207,222,95,75,35,114,125,125,62,31,128,192,255,191,143,128,128,159,190,188,252,255,255,224,192,159,187,149,71,103,63,0,0,63,124,240,195,12,115,1,50,124,56,0,131,127,0,0,255,1,0,252,254,254,0,0,255,255,255,103,96,48,49,26,26,143,205,228,244,254,142,47,239,239,175,143,239,47,15,191,191,191,63,63,191,191,63,63,191,191,63,191,191,63,191,63,127,255,255,255,143,47,239,239,47,47,207,31,15,175,239,15,191,63,191,191,63,63,191,191,63,191,191,15,47,239,143,63,191,63,191,63,63,191,190,62,62,190,190,63,62,190,188,52,231,206,156,24,25,61,48,96,231,255,255,0,128,240,252,254,255,255,255,255,255,255,241,244,247,247,180,16,183,244,240,246,246,247,240,247,240,254,56,19,181,245,208,87,80,87,208,247,240,223,255,255,241,244,247,119,113,49,215,176,119,116,243,240,243,244,19,24,88,243,245,149,16,87,112,151,240,243,244,244,243,244,247,240,247,240,248,248,115,245,245,240,245,244,246,240,255,255,127,255,254,252,240,128,0,255,255,0,63,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,127,191,247,17,17,85,247,255,0,0,85,255,119,111,159,255,227,157,186,240,176,240,184,252,191,255,191,254,190,157,227,188,0,85,255,127,255,1,1,85,255,223,191,191,127,127,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,63,0,255,255,192,128,1,7,31,63,127,255,255,255,255,255,255,255,127,255,191,191,191,63,255,255,255,252,203,203,255,192,192,253,199,215,196,212,197,247,213,245,213,255,208,242,208,242,208,242,192,194,224,82,96,194,192,226,224,255,229,231,101,103,101,231,101,103,229,231,229,255,255,223,206,241,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,127,63,31,7,1,128,192,255,255,10,13,247,94,188,88,248,0,0,1,1,255,225,222,191,97,94,94,109,191,222,225,191,1,81,85,16,30,203,197,213,193,195,223,193,193,253,193,193,253,193,193,255,227,193,213,209,235,255,192,192,255,227,193,221,193,227,253,192,192,253,253,192,192,221,255,255,205,214,217,255,225,222,225,255,225,222,225,255,205,214,217,255,1,1,0,0,248,168,220,170,247,13,10,255,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1

}; int main(void) { short i; AD1PCFG = 0xFFFF; // configura pines AN como digitales // Inicializa el display LCD gráfico openLCD1100(); // Limpia el buffer del LCD clearBufferLCD1100(); //Dibuja la imagen en buffer paintPictureLCD1100(imagen1); //Dibuja el buffer en display LCD paintLCD1100(); while(1) { } return 0; }

8 - Display Gráfico

Ing. Juan Ramon Terven Salinas 152

PRÁCTICA 8. Mini Osciloscopio Digital

Diseñe un osciloscopio digital de 1 canal usando el display LCD gráfico.

El osciloscopio debe ser capaz de funcionar en un rango mínimo de -20V a 20V.

Debe diseñar un circuito acondicionar similar a la práctica anterior para convertir el

rango amplio bipolar (-20 a 20) en un rango adecuado para el ADC (0 a 3.3V).

Figura 8-11. Osciloscopio Digital

Requisitos a calificar:

1.- Osciloscopio funcionando (grafica la señal en el display): 8 puntos.

2.- Cursores en Y para medir diferencias de voltaje: 2 puntos.