Vous êtes sur la page 1sur 13

Manejo de display LCD con microcontrolador HC08

En este ejemplo, usaremos un display LCD alfanumrico de 2 lneas con 16


caracteres cada una. Trabajaremos con envo de datos de 8 bits (paralelo), ya que
es ms simple para comprender el manejo del display al principio.
El objetivo es, entonces, escribir algunos caracteres en ambas lneas del
display, para comprender el funcionamiento y constatar la correcta
comunicacin entre el micro y el LCD. Con esta base, luego se podrn hacer
programas de mayor complejidad.
Tendremos entonces, los siguientes pines para manejo del display :
-Datos (D0 a D7)
-Pin E (habilita el display)
-Pin RS (le dice al display si le estamos enviando un dato o una instruccin de
control.
El pin R/W no ser utilizado ahora, y debemos conectarlo a masa.
El ejemplo servir para usar un microcontrolador de Freescale de cualquier tipo
de la familia HC08, siempre que tenga al menos un puerto entero (con sus 8 bits
disponibles). En este caso usamos el siguiente micro:
- MC68HLC908QY4A, de 16 pines, 4K de Flash, 128 bytes de RAM
En este caso tenemos todo el puerto PTB disponible.
Es importante tener a mano la hoja de datos del micro que utilicemos,
antes de iniciar cualquier tarea, y estudiarla atentamente.
En este caso usaremos un display GM1602 A, primero daremos los datos de los
pines del micro y del display:
Microcontrolador
1 VDD
2 PTB7
3 PTB6
4 PTA5/OSC1/AD3/KBI5
5 PTA4/OSC2/KBI4
6 PTB5
7 PTB4
8 PTA3/RST*/KBI3
Display

9 PTA2/IRQ*/KBI2/TCLK
10 PTB3
11 PTB2
12 PTA1/AD1/TCH1/KBI1
13 PTA0/AD0/TCH0/KBI0
14 PTB1
15 PTB0
16 VSS

1 VSS
2 VDD
3 V0
4 RS
5 R/W
6E
7 DB0
8 DB1

9 DB2
10 DB3
11 DB4
12 DB5
13 DB6
14 DB7
15 BCKL +
16 BCKL

Ahora, a continuacin damos el circuito:

Vemos que el PTB se usa completo para el envo de datos al display, y se ha


elegido PTA0 para el pin E y PTA1 para el pin RS.
R/W se deja a masa, ya que solo enviaremos datos a la RAM del display, pero
no leeremos de la misma.
Los pines blacklite no estn conectados, pues eso depender del tipo de display
a usar. Para una prueba bsica se puede conectar el blacklite a + 5V a travs de
una resistencia de 10 ohm (pin BCKL +) y a masa (BCKL -), si es que el display
tiene blacklite (iluminacin posterior).
Por ltimo, el pin V0 (contraste) est conectado a un potencimetro para dar a
ese pin la tensin ms conveniente, segn el tipo de display, que nos proporcione
la mejor definicin visual en los caracteres.
Procedimiento
En este programa, debemos realizar los siguientes pasos:
1) Inicializar el microcontrolador y sus variables.
2) Inicializar el display LCD.
3) Enviar cuatro caracteres a escribirse en la lnea superior del display, y cuatro
caracteres en la lnea inferior.
Inicializacin del microcontrolador
Debemos tener en cuenta qu tipo de entorno de programacin usamos (puede
ser P&E, Code Warrior, Winide, etc). Aqu no entraremos en detalles con respecto
a esos entornos. El programador sabr adaptar estas rutinas al entorno de
desarrollo que conoce.
Tenemos a continuacin un listado bsico de inicio de QY4:
*********************************************************************************************
* Prueba display LCD 1602
*
*********************************************************************************************
* Definicin del mapa de Memoria del 68HC908QY4 (68HC908QT1-2/QY1-2) *
*
*
*********************************************************************************************
RAM_START
ROM_START
VECTORES

EQU
EQU
EQU

$0080
$EE00
$FFDE

; Direccin del inicio de RAM


; Direccin del inicio de ROM
; Dir. Inicio rea de Vectores

**********************************************************************************************
* rea de variables de RAM (en esta prueba no se usa ninguna variable RAM) *
**********************************************************************************************
ORG RAM_START
*Registro temporario del acumulador
TEMPA RMB 1
*Registro temporario de ndice
TEMPX RMB 1
*********************************************************************************
* Asignacin de puertos
*
*********************************************************************************
ED equ 0; para el PTA0
RS equ 1; para el PTA1
*****************************************************************************************
* PROGRAMA PRINCIPAL - En este punto arranca el micro luego del Reset *
*
*
*****************************************************************************************
$Include
org

'qtqy_registers.inc'
ROM_START

; Definiciones de Reg para QT, QY


;Define y va al inicio de la ROM (flash)

start:
RSP
; Resetea el Stack Pointer
SEI
; Habilita la mscara de interrupciones
CLR PTB
; Limpia el puerto B
CLR PTA
; Limpia el puerto A
MOV #$03,DDRA
;Programo los puertos PortA(0-1) como salida
MOV #$FF,DDRB
;Programa todos los puertos B como salida
*********************************************************************************
* Inicializacin de timmer
*
*********************************************************************************
MOV
#$30,TSC
;Stop y reset Timmer. Prescaler = 1
MOV
#$00,TSC
;Libera Timmer. Prescaler = 1

Inicializacin del display


Es importante tener las hojas de datos del display que vayamos a utilizar. En ella
encontraremos informacin de los pines, estructura de la memoria DDRAM,
instrucciones de comandos, etc.
La mayora de los LCD trabajan de la misma manera, inclusive aunque sean de
distintos fabricantes, pero no debemos descartar que haya diferencias, sobre todo
en la plantilla de caracteres que cada display tiene disponible.
Hay dos cosas que comunicar al display:
1) Instrucciones de control, lo cual haremos mediante una rutina llamada WCTRL
(escribe control). Las instrucciones se escriben generalmente en hexadecimal, ya
que son configuraciones de bits especficos en el byte de control enviado.
2) Datos, que se envan mediante la rutina WDAT (escribe dato). La manera ms
sencilla de hacerlo es usando el cdigo ASCII del carcter que estamos queriendo
mostrar un display.
Sin embargo, nada podemos hacer antes de inicializar el display, lo cual significa
que le enviemos una serie de instrucciones que le dirn cmo queremos que
trabaje. Estas instrucciones deben enviarse respetando una temporizacin mnima
que depende de cada display en particular, es decir que no podemos mandar toda
la serie de comandos seguidos, ya que el display no tendr tiempo de procesar la
informacin, y se inicializar errneamente. Resultado: nunca mostrar nada de lo
que pretendemos.
Veamos un ejemplo de inicializacin de display, que no servir para nuestro
objetivo:
*********************************************************************************
* Inicializacin del display
*
*********************************************************************************
JSR
DELAY150
LDA
#$38
; %00111000
JSR
WCTRL
; Function Set 8 bits, 2 lineas, 5x7
JSR
DELAY150
LDA
#$38
JSR
WCTRL
JSR
DELAY150
LDA
#$38
JSR
WCTRL
JSR
DELAY150
LDA
#$0C
JSR
WCTRL
;Enciende el display y apaga el cursor

LDA
JSR
LDA
JSR

#$06
WCTRL
#$01
WCTRL

;Incrementa la direccin de muestra


;Limpia display

Como se ve, el primer comando se enva tres veces (ver hoja de datos para ms
detalles) y luego de cada envo se llama a una rutina de demora de 150 mseg.
Este tiempo supera ampliamente el especificado por cualquier fabricante, y lo
haremos de esta manera para seguridad de la prueba.
Tambin se llama a DELAY150 antes de mandar la primera instruccin, para
permitir que se estabilice todo el hardware antes de comenzar este proceso.
Segn los comentarios, con la primera instruccin (repetida tres veces), le
estamos diciendo al display que trabajemos con palabra de 8 bits, en display de
dos lneas, y con tamao de carcter de 5x7 puntos.
La siguiente instruccin enviada ($0C) enciende el display e inhabilita la muestra
del cursor, que no usaremos ahora.
La instruccin siguiente ($06) ordena al display que incremente la direccin de
muestra. Esto es, luego de escribir el carcter, el display automticamente
apuntar a la direccin siguiente para que escribamos en el que sigue. Por lo
tanto, los caracteres de datos que enviemos se irn escribiendo uno tras de otro,
de izquierda a derecha.
Por ltimo, enviamos el comando de borrado ($01) que limpia la DDRAM y por lo
tanto toda muestra que hubiere en la pantalla.
Rutinas WCTRL y WDAT
Antes de seguir con nuestro objetivo, veremos cmo trabajan estas rutinas
fundamentales de la comunicacin con el LCD.
WCTRL:
STA
BSET
NOP
BCLR
RTS

PTB
ED,PTA

;E=1

ED,PTA

;E=0

WCRTL toma lo que viene en el acumulador y lo saca por el puerto PTB.


Luego habilita el display haciendo ED = 1, espera sin hacer nada y vuelve a
inhabilitar el display con ED = 0. El paso siguiente (RTS) es el retorno de esta
rutina. La demora NOP depender del cristal utilizado.

Veamos ahora la WDAT


WDAT:
STB
PTB
BSET RS,PTA
BSET ED,PTA
NOP
BCLR ED,PTA
BCLR RS,PTA
RTS

; RS = 1
; ED = 1
; ED = 0
; RS = 0

WDAT es muy similar a WCTRL. La diferencia radica en que avisamos al display


que el carcter enviado ser un dato y no una instruccin, haciendo RS = 1 antes
de habilitar, y RS = 0 luego de inhabilitar.
Envo de datos al display
La memoria de ste display est organizada de la siguiente forma:

00$

01$

02$

03$

04$

05$

06$

07$

08$

09$

40$

41$

42$

43$

44$

45$

46$

47$

48$

49$

0A
$
4A
$

0B
$
4B
$

0C
$
4C
$

0D
$
4D
$

0E
$
4E
$

0F$
4F$

Tenemos entonces que la primera lnea se inicia en la direccin $00, y la segunda


en la direccin $40.
Si queremos escribir un dato en la primera lnea, tercer carcter, debemos antes
decirle al display que coloque su direccin de escritura all. Eso lo hacemos de la
siguiente forma:
LDA
ORA
JSR

#$03
#$80
WCTRL

; Toma la direccin deseada


; ACC = 10000011 (aade bit7 = 1)
; Enva la instruccin (direccin de DDRAM a escribir)

Luego enviamos el dato mediante la rutina WDAT, y se escribir en el lugar


propuesto: Supongamos que deseamos escribir la letra M:
LDA
JSR

#M
WDAT

; Esto indica M en ASCII


; Enva el dato

Tendremos as mostrndose en el tercer carcter de la L1.


Como en la inicializacin del display le ordenamos auto incrementar la direccin
de la DDRAM, si queremos escribir varios caracteres seguidos solo tenemos que
enviar una sola vez la direccin de inicio de esa cadena de caracteres. As, si
queremos escribir HOLA podemos listar la rutina como sigue:
CARTEL1:
LDA
ORA
JSR
LDA
JSR
LDA
JSR
LDA
JSR
LDA

#$00
; Direccin primer cartel lnea 1
#$80
WCTRL
#'H'
;Enva letra H
WDAT
#'O'
;Enva letra O
WDAT
#'L'
;Enva letra L
WDAT
#'A'
;Enva letra A

RTS
Listado completo del programa:
Para mayor claridad, listaremos el programa completo, incluyendo tambin el
rea de vectores:

*********************************************************************************************
* Prueba display LCD 1602
*
*********************************************************************************************
* Definicin del mapa de Memoria del 68HC908QY4 (68HC908QT1-2/QY1-2) *
*
*
*********************************************************************************************
RAM_START
ROM_START
VECTORES

EQU
EQU
EQU

$0080
$EE00
$FFDE

; Direccin del inicio de RAM


; Direccin del inicio de ROM
; Dir. Inicio rea de Vectores

**********************************************************************************************
* rea de variables de RAM (en esta prueba no se usa ninguna variable RAM) *
**********************************************************************************************
ORG RAM_START
*Registro temporario del acumulador
TEMPA RMB 1
*Registro temporario de ndice
TEMPX RMB 1
*********************************************************************************
* Asignacin de puertos
*
*********************************************************************************
ED equ 0; para el PTA0
RS equ 1; para el PTA1
*****************************************************************************************
* PROGRAMA PRINCIPAL - En este punto arranca el micro luego del Reset *
*
*
*****************************************************************************************
$Include
org

'qtqy_registers.inc'
ROM_START

; Definiciones de Reg para QT, QY


;Define y va al inicio de la ROM (flash)

start:
RSP
; Resetea el Stack Pointer
SEI
; Habilita la mscara de interrupciones
CLR PTB
; Limpia el puerto B
CLR PTA
; Limpia el puerto A
MOV #$03,DDRA
;Programo los puertos PortA(0-1) como salida
MOV #$FF,DDRB
;Programa todos los puertos B como salida
*********************************************************************************
* Inicializacin de timmer
*
*********************************************************************************
MOV
#$30,TSC
;Stop y reset Timmer. Prescaler = 1
MOV
#$00,TSC
; Libera Timmer. Prescaler = 1

*********************************************************************************
* Inicializacin del display
*
*********************************************************************************
JSR
DELAY150
LDA
#$38
; %00111000
JSR
WCTRL
; Function Set 8 bits, 2 lneas, 5x7
JSR
DELAY150
LDA
#$38
JSR
WCTRL
JSR
DELAY150
LDA
#$38
JSR
WCTRL
JSR
DELAY150
LDA
#$0C
JSR
WCTRL
;Enciende el display y apaga el cursor
LDA
#$06
JSR
WCTRL
;Incrementa la direccin de muestra
LDA
#$01
;Limpia display
JSR
WCTRL
***********************************************************************************
JSR
CARTEL1
LOOP1:
STA COPCTL

;Resetea el COP

BRA LOOP1
************************************************************************************
* Rutina que escribe un caracter de control en el display. La instruccin *
* viene en el acumulador
*
************************************************************************************
WCTRL:
STA
BSET
NOP
BCLR
RTS

PTB
ED,PTD

;E=1

ED,PTD

;E=0

*************************************************************************************
* Rutina que escribe un caracter de control en el display. La instruccin *
* viene en el acumulador
*
**************************************************************************************
WCTRL:
STA
BSET
NOP
BCLR
RTS

PTB
ED,PTD

;E=1

ED,PTD

;E=0

*********************************************************************************
* DELAY150 - Subrutina de demora de 150 mseg
*
*********************************************************************************
DELAY150:
LDX #$FF
;[2]
delay02:
LDA #$FF
;[2]
delay01:
DECA
;[1]
CMP #$00
;[2]
BNE delay01
;[3] ((3x2xff)+1+2+3+2)xff+6=392196d
DECX
;[1]
CPX #$00
;[2]
BNE delay02
;[3]
RTS
;[4]
*********************************************************************************
* Rutina CARTEL1
*
*********************************************************************************
CARTEL1:
LDA
#$00
; Direccin primer cartel lnea 1
ORA
#$80
JSR
WCTRL
LDA
#'H'
;Enva letra H
JSR
WDAT
LDA
#'O'
;Enva letra O
JSR
WDAT
LDA
#'L'
;Enva letra L
JSR
WDAT

LDA

#'A'

;Enva letra A

RTS
*********************************************************************************
* VECTORES - Definicin de Vectores del Sistema

*********************************************************************************
org

VECTORES

dw

adc_isr

; ADC Conv.Complete Vector

dw

keyb_isr

; Keyboard Vector

dw

dummy_isr

; (No Vector Assigned)

($FFE2-$FFE3)

dw

dummy_isr

; (No Vector Assigned)

($FFE4-$FFE5)

dw

dummy_isr

; (No Vector Assigned)

($FFE6-$FFE7)

dw

dummy_isr

; (No Vector Assigned)

($FFE8-$FFE9)

dw

dummy_isr

; (No Vector Assigned)

($FFEA-$FFEB)

dw

dummy_isr

; (No Vector Assigned)

($FFEC-$FFED)

dw

dummy_isr

; (No Vector Assigned)

($FFEE-$FFEF)

dw

dummy_isr

; (No Vector Assigned)

($FFF0-$FFF1)

dw

tim_ov_isr

; TIM1 Overflow Vector

($FFF2-$FFF3)

dw

tim_1_isr

; TIM1 Channel 1 Vector

($FFF4-$FFF5)

dw

tim_0_isr

; TIM1 Channel 0 Vector

($FFF6-$FFF7)

dw

dummy_isr

; (No Vector Assigned)

($FFF8-$FFF9)

dw

irq_isr

dw

dummy_isr

dw

start

; ~IRQ1
; SWI Vector
; Reset Vector

($FFDE-$FFDF)

($FFE0-$FFE1)

($FFFA-$FFFB)
($FFFC-$FFFD)
($FFFE-$FFFF

*********************************************************************************
end