22
UNIVERSIDAD AUTÓNOMA DE YUCATÁN Facultad de Ingeniería Dispositivos de Control Practica 1: “Programación Básica con el LCD” Equipo: FENDER Integrantes: Colín Amador, Diana Monserrat. May Tzuc, Oscar de Jesús. Góngora Niño, Sergio.

Practica1 FENDER

Embed Size (px)

Citation preview

Page 1: Practica1 FENDER

UNIVERSIDAD AUTÓNOMA DE YUCATÁN

Facultad de Ingeniería

Dispositivos de Control

Practica 1: “Programación Básica con el LCD”

Equipo: FENDER

Integrantes:

Colín Amador, Diana Monserrat.May Tzuc, Oscar de Jesús.Góngora Niño, Sergio.

Profesor: M en C. Mauricio Romero.

OBJETIVO:

Page 2: Practica1 FENDER

Usar una pantalla LCD para visualizar información y como medio de depuración de aplicaciones, tanto en C como en Ensamblador.

INTRODUCCIÓN.

El LCD es una herramienta muy útil y económica, no solo para el despliegue de información, sino también para el proceso de depuración durante el desarrollo, ya que nos permite desplegar resultados parciales o usarlo para monitorear los procesos y variables dentro de nuestra aplicación.

Actualmente los displays de LCD más usados se basan en el protocolo estándar del manejador de LCD Hitachi HD44780. Este driver puede manejar displays de hasta 8 líneas y 40 caracteres. Este manejador puede ser usado con dos interfaces diferentes de 4 y 8 bits, siendo la ultima más rápida a costa de usar más terminales de E/S. El PSoC Designer nos proporciona una API estándar para el manejo de LCDs basados en este chip, de 2 líneas y 16 caracteres; Sin embargo, es posible usarla con otros displays más grandes, con la única restricción de que no podremos usar directamente las barras graficas. Para Conectar el LCD, el PSoC utiliza 7 bits de un puerto, ya que utiliza la interfaz de 4 bits del controlador para ahorrar pines. El octavo bit del puerto podemos usarlo para controlar el LED del panel trasero de nuestra pantalla en caso de tenerlo, usando máscaras en el bit 7 del puerto, o usando un módulo de LED dentro del PSoC Designer.

Conexiones.

Para nuestra primera práctica conectaremos la pantalla al puerto 2 del PSoC de acuerdo al siguiente diagrama:

El Potenciómetro o Preset puede tener cualquier valor en el rango de 10KOhms a 100KOhms. Este valor no es crítico ya que su única función es establecer el nivel de contraste deseado para la pantalla. Si no deseamos variarlo, podemos fijar su valor usando 2 resistencias fijas. En caso de que nuestro LCD tenga luz trasera, la conectaremos a la terminal 7 del puerto 2.

EL PSoC se conecta al programador por medio de 5 terminales: Alimentación (Vdd), Tierra (GND), Reset (XRES), SCLK (P1.0) y SDATA (P1.1). De estas 5 terminales el reset es opcional, y se suele utilizar cuando queremos programar un micro que tiene alimentación aplicada. El Programador del PSoC puede proporcionarnos alimentación de 5 volts para nuestro circuito, sin embargo se debe tener cuidado de que la corriente del circuito no exceda los 120mA, y desconectar las terminales de programación SCLK y SDATA durante la operación del circuito si las usamos dentro de nuestra aplicación para alguna función, ya que de lo contrario podríamos dañar el programador.

DESARROLLO

Page 3: Practica1 FENDER

Se sigue el procedimiento descrito en el protocolo de práctica para la creación de un primer programa usando la LCD, y se desarrollan los siguientes ejemplos para el lenguaje C:

1.a.- Escribe el código que se muestra a continuación, compílalo, prográmalo en la tarjeta y contesta las preguntas:

#include <m8c.h> // part specific constants and macros

Page 4: Practica1 FENDER

#include "PSoCAPI.h" // PSoC API definitions for all User Modules

const char Cadena1[]="Cadena en ROM";char Cadena2[]= "Cadena en RAM";

void main(void){

LCD_Start();LED_Start();LCD_Position(0,0);LCD_PrCString(Cadena1);LCD_Position(1,0);LCD_PrString(Cadena2);

}

1.- Explica Que hace este programa.

Este programa imprime en una pantalla LCD dos cadenas de textos, una guardada en la memoria RAM y la otra en la memoria ROM del microcontrolador.

2.- ¿Que diferencia hay entre las líneas 16 y 18, y como se relacionan estas con las líneas 8 y 9? ¿Funcionarían si se cambia la forma de declarar las cadenas? Explica tus Respuestas.

Las instrucciones en las líneas 8 y 9 se utilizan para generar cadenas de textos. Las instrucciones en las líneas 16 y 18 se emplean para imprimir el texto en una pantalla LCD.

La diferencia entre las líneas de impresión de texto (16 y 18), es que la primera se utiliza para imprimir datos provenientes de la memoria RAM (línea 9), y la segunda imprime datos que se encuentran guardados en la memoria ROM (línea 8). Si se llegara a cambiar el orden marcaría un error de compilación.

3.- ¿En el Caso de que la Pantalla lleve un LED, Que tendría que poner para que se encendiera?

Eso depende la configuración que se le de al LED:

Si en los parámetros el Drive del LED está en modo High, es necesario escribir LED_On.

Si en los parámetros el Drive del LED está en modo Low, no es necesario escribir algún otro comando.

2.a.- Cambia el código del programa al siguiente.

Page 5: Practica1 FENDER

El programa tiene un error, detéctalo y corrígelo.

#include <m8c.h> // part specific constants and macros#include "PSoCAPI.h" // PSoC API definitions for all User Modules

char caracter= -64;unsigned char Ucaracter= 65;int entero= 1625;

void main(void){

LCD_Start();LED_Start();LCD_Position(0,0); LCD_PrHexByte(caracter);LCD_WriteData(' ');LCD_PrHexByte(Ucaracter);LCD_WriteData(' ');LCD_PrHexInt(entero);

}

4.- Escribe y Explica la salida del Programa.

Page 6: Practica1 FENDER

El programa visualiza por medio de una LCD valores en hexadecimal de tres tipos diversos de datos: una cadena de byte, una cadena de byte sin signo y un número entero. Tal y como se aprecia en la siguiente tabla:

Entrada

Salida

-64 FFFFFFC0

65 411625 0659

5.- Explica con tus palabras para que sirven las funciones LCD_PrHexByte, LCD_PrHexInt y LCD_WriteData.

LCD_PrHexByte: Imprime bytes (números), en cadenas de texto en código hexadecimal.

LCD_PrHexInt: Imprime números enteros en una pantalla LCD, en código hexadecimal.

LCD_WriteData: Imprime los caracteres guardados en la memoria ROM del LCD, generalmente valores en ASCII.

Hay que tomar en cuenta que LCD_PrHexByte, imprime únicamente dos caracteres, lo cual se puede corroborar observando que el valor de -64 imprimió únicamente los 2 digitos menos significativos.

De la misma forma para la instrucción LCD_PrHexInt, esta imprime cuatro caracteres, por lo cual en nuestra pantalla se llena el cuarto carácter con un cero.

3.a.- Escribe este Programa y córrelo en la tarjeta.

Page 7: Practica1 FENDER

#include <m8c.h> // part specific constants and macros#include "PSoCAPI.h" // PSoC API definitions for all User Modules#include "stdlib.h"

char cadena[10]; int entero= -1625;long enterolargo=0x8DEEFFFF;

void main(void) {

LCD_Start(); LED_Start(); LCD_Position(0,0);LCD_PrString(itoa(cadena,entero,10));LCD_WriteData(' ');LCD_PrString(ltoa(cadena,enterolargo,10));LCD_Position(1,0);LCD_PrString(utoa(cadena,entero,10));LCD_WriteData(' ');LCD_PrString(ultoa(cadena,enterolargo,10));

}

6.- Escribe y Explica la salida del Programa, y para que sirven las funciones itoa, ltoa, utoa y ultoa.

Page 8: Practica1 FENDER

Este código nos muestra el procedimiento para convertir cierto de tipo de valores numéricos a cadenas de datos, visualizándolos en LCD.

1.- itoa: convierte valores de tipo entero a string.

char *itoa (char *string, int value, int base);

int value: valor que queremos convertir.

*string: puntero que guarda el dato convertido

base: generalmente es 10.

2.- ltoa: convierte valores de tipo long a string.

char *ltoa (char *string, long value, int base);

long value: valor que queremos convertir.

*string: puntero que guarda el dato convertido

base: generalmente es 10.

3.- uitoa: convierte valores de tipo entero sin signo a string.

char *uitoa (char *string, uint value, int base);

uint value: valor que queremos convertir.

*string: puntero que guarda el dato convertido

base: generalmente es 10.

4.- ultoa: convierte valores de tipo long sin signo a string.

char *ultoa (char *string, ulong value, int base);

ulong value: valor que queremos convertir.

*string: puntero que guarda el dato convertido

base: generalmente es 10.

7.- Investiga en la documentación en el archive “C Language Compiler User Guide” más acerca de estas funciones, investiga cual es la función que me permite imprimir

Page 9: Practica1 FENDER

números con punto decimal, y haz un programa ejemplo que me imprima una variable flotante llamada MyPI con valor 3.141592. Escribe el código del Programa.

#include <m8c.h> // part specific constants and macros#include "PSoCAPI.h" // PSoC API definitions for all User Modules#include "stdlib.h"#include "string.h"#define _FTOA_TOO_LARGE -2#define _FTOA_TOO_SMALL -1

char valor[]="MyPI = ";

void main(void) { float MyPI; int estado; char*nuevo; MyPI= 3.141592; LCD_Start(); LED_Start(); nuevo= ftoa(MyPI,&estado); LCD_Position(0,0); LCD_PrString(valor); LCD_WriteData(' '); LCD_PrString(nuevo);

}

Page 10: Practica1 FENDER

Se procede a crear un nuevo proyecto llamada Practica1b, y seleccionamos la opción de compilación en ensamblador. Y se realizan los siguientes ejemplos:

1.b.- Escribe el código que se muestra a continuación, compílalo, prográmalo en la tarjeta y contesta las preguntas:

include "m8c.inc" ; part specific constants and macrosinclude "memory.inc" ; Constants & macros for SMM/LMM and Compilerinclude "PSoCAPI.inc" ; PSoC API definitions for all User Modules

export _mainarea bss(RAM) ;directiva usada cuando la variable tiene que ser declara en RAM VarStr: blk 17 ;separo 17 bytes para una cadena en RAM de 16 caracteres+el nullarea text(ROM,REL);es la directiva usada cuando el código está escrito. Después de ;usar el "área bss (RAM)" y declaración de variables " área

;txt(rom)" tiene que ser utilizado antes de entrar en el código.

_main:call LCD_Start ;iniciamos la

LCDcall LED_Start

;iniciamos el LEDcall LED_Onmov[VarStr],'H'

;iniciamos la cadena.mov[VarStr+1],'o'

mov[VarStr+2],'l' mov[VarStr+3],'a' mov[VarStr+4],' ' mov[VarStr+5],'M' mov[VarStr+6],'u'

mov[VarStr+7],'n' mov[VarStr+8],'d' mov[VarStr+9],'o' mov[VarStr+10],0x00 mov A,00h mov X,00h call LCD_Position mov A,>VarStr mov X,<VarStr call LCD_PrString

;imprimimos la cadena RAMmov A,01h

;indicamos fila 1 para la LCDmov X,00h ;indicamos col 0 para la LCDcall LCD_Position ; indicamos que son las coordenanadas en la LCDmov A,>TablaRom ; Parte alta de la dirección de la tabla en ROMmov X,<TablaRom ; Parte baja de la dirección de la tabla en ROMcall LCD_PrCString ; Imprime la cadena constante en ROM

.terminate: jmp .terminate.literalTablaRom:

asciz "Cadena ROM" ;defino una cadena en ROM con terminacion nula .endliteral

Page 11: Practica1 FENDER

8.- ¿Que Hace este Código? ¿Cuál es la diferencia entre LCD_PrString y LCD_PrCString?

Imprime en la parte superior una cadena de caracteres guardados en la memoria RAM, mientras que en la parte inferior imprime texto ubicado en la memoria ROM del microcontrolador.

La diferencia entre ambas instrucciones es la misma que en el lenguaje C, la primera se utiliza para datos en la memoria RAM, mientras que la segundo para los datos en la ROM.

9.- Porque es necesaria la línea “mov A,>VarStr” y ¿Cómo Afecta la función LCD_PrString a mi programa, en cuanto a posibles conflictos que puede generar?

Es el método que utiliza el compilador en lenguaje ensamblador para imprimir cadenas de caracteres, ya que es necesario dividir la parte alta y parte baja de lo contrario existiría un error en la compilación.

El registro X y el acumulador pueden ser modificados debido a implementaciones actuales o implementaciones futuras de la función LCD_PrString. Lo mismo pasa para todas las variables o punteros en RAM registrados en el modelo de memoria larga. Cuando sea necesario, la función puede preservar los valores de los registros o variables en RAM a través de llamadas a funciones fastcall16.

2.b.-Ahora crea el código:

include "m8c.inc" ; part specific constants and macrosinclude "memory.inc" ; Constants & macros for SMM/LMM and Compilerinclude "PSoCAPI.inc" ; PSoC API definitions for all User Modules

export _mainarea bss(RAM) MyVar: blk 1 area text(ROM,REL)

_main:

call LCD_Start call LED_Start call LED_On mov [MyVar],52 mov A,00h mov X,00h call LCD_Position mov A,>Tablarom mov X,<Tablarom call LCD_PrCString mov A,0 mov X,6 call LCD_Position mov A,[MyVar] call LCD_WriteData mov A,0 mov X,13 call LCD_Position mov A,[MyVar] call LCD_PrHexByte

.terminate:jmp .terminate.literal

Page 12: Practica1 FENDER

Tablarom:asciz "Ascii: Hex:"

.endliteral

10.- ¿Es posible imprimir números en formato decimal haciendo uso de LCD_PrHexByte? Explica tu respuesta.

No, ya que este únicamente imprime los dos números menos significativos en lenguaje hexadecimal.

11.- ¿Que ventajas nos proporciona imprimir usando LCD_WriteData a usar LCD_PrString?

La ventaja del LCD_WriteData es que nos permite imprimir un solo carácter proveniente de Ascii y asi poder ocupar menos espacio en la memoria.

3.b Ahora vamos a crear un pequeño programa que haga uso de los comandos internos del LCD. Consulta la Hoja de Datos del LCD para poder seguir el programa.

include "m8c.inc" ; part specific constants and macrosinclude "memory.inc" ; Constants & macros for SMM/LMM and Compilerinclude "PSoCAPI.inc" ; PSoC API definitions for all User ModulesBorrarLCD: equ 0b00000001GoHome: equ 0b00000010SetDDRAM_Addr: equ 0b10000000 ; Seleccionar dirección de la memoria de despliegue del LCDexport _mainarea bss(RAM)MyVar: blk 1 ; Separo 1 byte para una Variable en ramarea text(ROM, REL)_main:call LCD_Startcall LED_Startcall LED_Onmov A, BorrarLCDcall LCD_Control ; Borra el LCDmov A, SetDDRAM_Addrcall LCD_Control ; Me pongo en la primera Posición del LCD (Direccion 0x00)mov A,>TablaRom1 ; Parte alta de la dirección de la tabla en ROMmov X,<TablaRom1 ; Parte baja de la dirección de la tabla en ROMcall LCD_PrCString ; Imprime la cadena constante en ROMmov A, SetDDRAM_Addr | 0x40call LCD_Control ; Me pongo en la primera Posición de la segunda linea del LCD (Direccion 0x40)mov A,>TablaRom2 ; Parte alta de la dirección de la tabla en ROMmov X,<TablaRom2 ; Parte baja de la dirección de la tabla en ROMcall LCD_PrCString ; Imprime la cadena constante en ROMmov A, 0b00001111call LCD_Controlmov [MyVar],100Ciclo:mov A,200call LCD_Delay50uTimesdec [MyVar]jnz Ciclomov A, GoHomecall LCD_Control ; Mueve el Cursor a Home.terminate:jmp .terminate.literalTablaRom1:

Page 13: Practica1 FENDER

asciz "Linea1" ; Defino una cadena en rom con terminación nulaTablaRom2:asciz "Linea2" ; Defino una cadena en rom con terminación nula.endliteral

12.- A que código en nuestros programas anteriores sustituyen las líneas: mov A, SetDDRAM_Addr | 0x40 y call LCD_Control?

Sustituye a:

Mov A,xxhMov X,yyhCall LCD_Position

13.- ¿A que estructura de alto nivel equivale el siguiente código, y para que se utiliza en el programa?mov [MyVar],100Ciclo:mov A,200call LCD_Delay50uTimesdec [MyVar]jnz Ciclo

es equivalente a un ciclo do-while.

14.- ¿ función realizan las instrucciones: mov A, 0b00001111 y call LCD_Control?

Se encarga de posicionar el cursor, encender el parpadeo y encender la LCD. (DISPLAY ON/OFF Control).

15.- ¿Que desventajas y ventajas encuentras en el uso de ensamblador para el Manejo del LCD, con respecto a C?

En C es mucho mas fácil y rápido realizar la programación de la LCD, ya que no es necesario escribir tantos códigos. Aun así en ensamblador se puede configurar ciertas cosas que están predefinidas en C ,además de ocupar menos espacio de memoria.

Page 14: Practica1 FENDER

4b. Crea un nuevo proyecto en Ensamblador, y llámalo “Práctica1c”. Haz un programa

que genere y despliegue 8 caracteres propios en el LCD (como por ejmplo: etc.) Cada uno debe de ir apareciendo uno a uno con intervalos de un segundo entre cada despliegue. Para generar este tiempo de espera entre el despliegue de cada símbolo, crea una subrutina llamada Pausa1s haciendo uso de la función LCD_Delay50uTimes del LCD. De tal manera que cada vez que desees hacer una espera de 1 seg uses la instrucción “call Pausa1s”. Incluye en el reporte de la práctica el código del programa.

;-----------------------------------------------------------------------------; Assembly main line;-----------------------------------------------------------------------------

include "m8c.inc" ; part specific constants and macrosinclude "memory.inc" ; Constants & macros for SMM/LMM and Compilerinclude "PSoCAPI.inc" ; PSoC API definitions for all User Modules

CLEARLCD: equ 0b00000001 ;borrar la lcdCGRAM: equ 0b01000000 ;indicamos la direccion del a cgramDDRAM: equ 0b10000000 ;indicamos la direccion de la ddram

export _mainarea bss(RAM)var: blk 1var1: blk 1tiempo: blk 1area text(ROM,REL)

_main:

call LCD_Start ;iniciamos la LCDcall LED_Start ;iniciamos el LEDcall LED_On ;encendemos el LEDmov A,CLEARLCD call LCD_Control ;limpiamos el LCDmov A,CGRAMcall LCD_Control ;indicamos que las transferencias

de datos se realizaran en la CGRAMmov [var],65mov [var1],0

loop: mov A,[var1]

index Tabla1 call LCD_WriteData inc[var1] dec[var] jnz loop

mov A, DDRAMcall LCD_Control

Page 15: Practica1 FENDER

mov A,00hcall LCD_WriteDatamov [tiempo],100call pausa

mov A,01hcall LCD_WriteDatamov [tiempo],100call pausa

mov A,02hcall LCD_WriteDatamov [tiempo],100call pausa

mov A,03hcall LCD_WriteDatamov [tiempo],100call pausa

mov A,04hcall LCD_WriteDatamov [tiempo],100call pausa

mov A,05hcall LCD_WriteDatamov [tiempo],100call pausa

mov A,06hcall LCD_WriteDatamov [tiempo],100call pausa

mov A,07hcall LCD_WriteDatamov [tiempo],100call pausa

pausa:

mov A,200call LCD_Delay50uTimesdec[tiempo]jnz pausaret

; mov A,3; index Tabla1; lcall LCD_WriteData;

.terminate: jmp .terminate

.literalTabla1:

Page 16: Practica1 FENDER

;primeradb 0b00100db 0b01110db 0b11111db 0b01110db 0b00100db 0b01110db 0b01110db 0b01110;segundadb 0b00010db 0b00110db 0b01010db 0b01010db 0b01010db 0b00110db 0b00010db 0b00000;terceradb 0b10001db 0b00100db 0b01010db 0b01010db 0b00100db 0b00100db 0b00100db 0b10101;cuartadb 0b00000db 0b00100db 0b01010db 0b11111db 0b10001db 0b10001db 0b11111db 0b00000;quintadb 0b00000db 0b00110db 0b01111db 0b11110db 0b01111db 0b00110db 0b00000db 0b00000;quintadb 0b01110db 0b01110db 0b01110db 0b00100db 0b11111db 0b00100db 0b01010db 0b10001;sextadb 0b00000db 0b01110

Page 17: Practica1 FENDER

db 0b10001db 0b00100db 0b01010db 0b00000db 0b00100db 0b00000;septimadb 0b00100db 0b00110db 0b10101db 0b01110db 0b01101db 0b10110db 0b00100db 0b00000

.endliteral

Page 18: Practica1 FENDER

BIBLIOGRAFÍA.

Mauricio Romero. Guía de Practicas de Dispositivos de Control. “Practica 1.- Programación Básica del LCD”.

Visualización de Números en Punto Flotante. Recuperado de: http://www.cypress.com/?id=4&rID=31078

Alexander Sáenz. Introducción a la Programación de los PsoC’s. Recuperado de: http://es.scribd.com/doc/91635812/Introduccion-Programacion-de-Psoc-Cap1

Cypress. C lenguaje compiler user guide. Recuperado de la documentación de PsoC.

Cypress. Assembly lenguaje user guide. Recuperado de la documentación de PsoC.

Assembler Directives to Specify RAM Area and Code Area. Recuperado de: http://www.cypress.com/?id=4&rID=28629

Cypress. LCD. Recuperado de la documentación de PsoC.