Documentos de Académico
Documentos de Profesional
Documentos de Cultura
LCDMatricial PDF
LCDMatricial PDF
DSM
10/09/07
ndice
Introduccin..........................................................................................................................................1
Hardware..............................................................................................................................................2
LCD.................................................................................................................................................3
patillaje........................................................................................................................................4
tabla de instrucciones..................................................................................................................5
Timings.......................................................................................................................................6
Organizacin de la pantalla.........................................................................................................8
Circuito completo.................................................................................................................................9
Cdigo comentado..............................................................................................................................10
Bibliografa.........................................................................................................................................28
Introduccin:
El objetivo de este trabajo era aprender a controlar con un PIC un display LCD grfico mediante la
creacin de un pequeo juego rompebloques que lo utilice.
Hardware:
El montaje se realiz utilizando un PIC 16F84A de 18 patillas a 12 mhz que controla un LCD
grfico. El juego se maneja con 2 pulsadores que comparten las lneas de datos del LCD
aprovechndose del margen de niveles de la lgica TTL.
A continuacin se entrar en detalles sobre cada una de estas partes.
LCD:
El LCD utilizado es un LCD Grfico CFAG12864B-TMI-V de la casa Crystalfontz.
Caractersticas ms importantes
Ancho (pxeles/mm)
128 / 60
Alto (pxeles/mm)
64/ 32.6
Color
Inversor de tensin
Incluido
Chipset
2 x S6B0108 y 1 x S6B0107
El CFAG12864B-TMI-V est basado en los chips Samsung S6B0108 / S6B0107 (antes llamados
KS6B108 / KS0107B).
Cada S6B0108 solo admite 64 lneas as que el LCD est dividido en 2 mitades, cada una de ellas
controlada por uno de estos 2 chips tal y como ilustra el grfico.
Patillaje
1
Vdd (+5v)
Vss (0v)
13
14
15
16
17
18
19
20
Se recomienda una resistencia de al menos 25 Ohmios para el nodo del backlight. Una resistencia
de 10000 Ohmios para RESET suele ser tpica tambin en estos montajes.
4
Set Y
Address
Set X Page L
Set
L
Display
Start Line
B
U
S
Y
ON R
/
E
OFF S
E
T
Status
Read
Funcin
Y Address (0-63)
Establece la Direccin Y,
es decir, la columna activa.
X Page (0-7)
Establece la Pgina X, es
decir, la pgina vertical
activa.
Indica qu lnea debe ser
tomada como lnea de inicio
a la hora de mostrar la
imgen en el display.
Write
Display
Data
H L
Read
Display
Data
H H
Hay que hacer notar que cada mitad del LCD se controla independientemente. Cada mitad se activa
poniendo CS1 o CS2 a nivel bajo antes de cada instruccin, respectivamente.
La seal E (pin 17) acta como reloj. Las instrucciones se procesan en el flanco de subida. Si
estamos haciendo una lectura del estado (Status Read) ste es devuelto mientras E est alta.
Hay que esperar a que la BUSY Flag del LCD est desactivada antes de intentar cualquiera de las 6
primeras instrucciones (las 5 primeras se consideran escrituras de registros del LCD, y Status Read
una lectura de los mismos).
Las lecturas de RAM de pantalla son algo ms complejas que las dems instrucciones, pues
necesitan adems de una primera lectura en la que en realidad no lee nada, pues la lectura efectiva
se hace en el segundo intento.
Organizacin de la pantalla:
La pantalla est dividida en 2 mitades de 64x64 pxeles, cada una organizada en 64 columnas
individualmente sealables (Y Addresses) y en 8 pginas verticales (X Pages) que agrupan 8 pxeles
monocromticos cada una (1 byte cada X page).
Cada mitad individual del LCD se activa poniendo ~CS1 o ~CS2 a nivel bajo.
Circuito completo:
No se pintaron MCLR, VSS, VDD y OSC1 y OSC2 para ahorrar espacio. Estos pines estn
conectados como en cualquier circuito genrico de PICs.
Hay dos puntos que aclarar respecto a este circuito:
1) RA4/~CS1 tiene una resistencia Pull-up de 2K2 Ohmios porque este pin es Open Drain
Output en el PIC.
2) La lectura de los pulsadores (RB0 y RB1) utiliza los niveles lgicos TTL compatibles con el
PIC y se realiza de la siguiente forma:
1. Cuando el LCD esta usando ese puerto, al no haber resistencias entre el pin del PIC y el
del LCD siempre prevalece el valor puesto por el PIC/LCD.
2. Cuando el LCD esta desconectado (~CS1 y ~CS2 altos) se pueden leer los pulsadores. Si
stos estn sin pulsar, estarn puestos a 5V por las resistencias pull-up de 47K (TTL
input high mnimo 2V y -0.04mA) y detectar un 1 lgico.
Si estn pulsados, la corriente fluir desde los 5V por las resistencias pull-up de 47K y
las de 2K2 hasta GND, lo que significa que en dichos pines habr
5V/(47000+2200)=0.1mA y (0.0001*2200)=0.22V (TTL input low mximo 0.8V y
-1.6mA). En este caso la corriente no llega al mximo (-1.6mA) que podra exigir un
chip TTL, pero el PIC detectaba el 0 lgico sin problemas.
Cdigo comentado:
El juego consiste en romper todas los bloques sin que la pelota se caiga. Si se consigue se pasa a
otra fase en la que la velocidad de movimiento aumenta.
Al principio el LCD est apagado, para iniciar una fase hay que pulsar un botn.
LIST
__FUSES
include
P=16F84A, R=DEC
_HS_OSC & _WDT_OFF & _CP_OFF & _PWRTE_ON
"P16F84A.inc"
;------------------------------------------------------------------------; Constantes
;------------------------------------------------------------------------; Indican que pin corresponde a que seal de control
LCD_CS1
EQU 4
LCD_CS2
EQU 3
LCD_RW
EQU 2
LCD_DI
EQU 1
LCD_RS
EQU 1 ; (RS=DI)
LCD_E
EQU 0
;------------------------------------------------------------------------; Variables
;------------------------------------------------------------------------Ram
EQU
h'0C'
; Inicio de la RAM
Ram+5
Ram+6
Ram+6
Ram+7
Ram+7
Ram+8
10
Temp_Z
EQU
Ram+8
LCD)
; Direcciones de la pelota
;
; Posicion de la pelota
; Posicion de la barra
; Incremento de la barra
; Espera entre frame y frame
;
;
;
;
;------------------------------------------------------------------------; Programa
;------------------------------------------------------------------------Start
ORG
goto
0
Inicio
;
;
Direccion de inicio
Iniciar programa
;
; Aqui van todas las tablas del programa
Esta tabla es necesaria, porque querremos iluminar solo un pixel de toda la pgina vertical de 8
pxeles (la pelota).
; Tabla que devuelve el valor para una pagina
; del LCD segun el pixel que queramos poner
Pixel_Value
addwf PCL, F
retlw b'00000001'
retlw b'00000010'
retlw b'00000100'
retlw b'00001000'
retlw b'00010000'
retlw b'00100000'
retlw b'01000000'
retlw b'10000000'
;
11
; poner B a salida
; debemos poner E
;
;
; Apagamos el LCD
bcf
PORTA,
bsf
PORTA,
call LCD_Off
;
bsf
PORTA,
bcf
PORTA,
call LCD_Off
;
bsf
PORTA,
; desactivar las 2
mitades
bsf
PORTA, LCD_CS2 ; del lcd para leer
;
bsf
STATUS, RP0 ; puerto B a leer
movlw H'FF'
movwf
TRISB
bcf
STATUS, RP0
;
; esperamos unos ms
movlw 100
call
WaitNms
;
Esperar_Pulsacion_Inicial
movfw PORTB
; esperamos a que se pulse algo
andlw b'00000011'
addlw -3
btfsc STATUS, Z
goto Esperar_Pulsacion_Inicial
;
; volvemos a dejar el puerto B a salida
bsf
STATUS, RP0
clrf TRISB
bcf
STATUS, RP0
;
;
;
; inicialmente ponemos un cierto retardo (velocidad
12
juego)
movlw 30
movwf Espera
;
;
;
; aqui es donde se inicializan los elementos de
cada partida
Esta parte inicia una partida, independientemente de la velocidad. Se inicializan las posiciones de
la pelota, los bloques (matriz 2x16 en variable bloques), etc.
Iniciar_Partida
derribar
;
; inicializar los bloques
movlw
32
movwf
Bloques_Quedan
13
derribar)
Ini_bloques_L1
movwf Temp_X
movlw Bloques
movwf FSR
movlw
2
movwf INDF
incf FSR
decfsz
Temp_X
goto Ini_bloques_L1
; fin de inicializar los bloques
;
;
El loop principal consiste en pintar la pantalla, actualizar las posiciones de barra y pelota,
comprobar las colisiones con bloques y bordes, leer los controles, comprueba si se gana o se
pierde... Realiza una espera fija entre frame y frame. No hubo necesidad de usar el timer, puesto
que el nmero de instrucciones que se ejecuta es casi igual entre frames y es el lcd el que limita en
gran medida la velocidad (esperando al busy flag).
;Loop principal
Loop
;
; pintar los bloques
; apuntamos a la primera hilera de bloques
movlw Bloques
movwf FSR
;
bcf
PORTA, LCD_CS1 ; primera mitad LCD
bsf
PORTA, LCD_CS2
call Pintar_Bloques
; apuntamos a la segunda hilera bloques
movlw (Bloques+8)
movwf FSR
;
bsf
PORTA, LCD_CS1
bcf
PORTA, LCD_CS2 ; segunda mitad LCD
call Pintar_Bloques
; fin de pintar los bloques
;
;
;
; pintar la pelota
movfw Pelota_X
movwf LCD_Pixel_X
movfw Pelota_Y
movwf LCD_Pixel_Y
call LCD_Put_Pixel
;
;
14
;
; pintamos la barra
call Pintar_Barra
; fin de pintar la barra
;
;
; Leemos los controles y realizamos
; una espera entre frames
Mandos
unids. derecha
bsf
PORTA, LCD_CS1 ; desactivar
bsf
PORTA, LCD_CS2 ; las 2 mitades del lcd
;
; espera
movfw Espera
call
WaitNms
;
bsf
STATUS, RP0 ; puerto B a leer
movlw H'FF'
movwf
TRISB
bcf
STATUS, RP0
;
clrf Barra_Y_Inc ; movimiento neutro (cero)
; Si B.0 es 0 y no esta al tope de derecha, mover 2
btfsc
PORTB, 0
goto Mandos_L1
movfw Barra_Y
addlw 152
btfsc STATUS, C
goto Mandos_L1
movlw 2
movwf Barra_Y_Inc
Mandos_L1
2 unids. izquierda
Mandos_L2
15
Loop_Sig_1
Loop_Sig_2
Loop_Sig_3
Loop_Sig_4
;
; hacer rebotar la pelota en las paredes
; colision arriba
movfw Pelota_X
btfss STATUS, Z
goto Loop_Sig_1
movlw 1
movwf Inc_X
; colision izquierda
movfw Pelota_Y
btfss STATUS, Z
goto Loop_Sig_2
movlw 1
movwf Inc_Y
; colision abajo
movfw Pelota_X
xorlw 60
btfss STATUS, Z
goto Loop_Sig_3
call Wait1Second
goto Start
; colision derecha
movfw Pelota_Y
xorlw 127
btfss STATUS, Z
goto Loop_Sig_4
movlw 255
; -1
movwf Inc_Y
; final de rebotes en paredes
;
;
;
;
; hacer rebotar la pelota si choca con la barra
movlw 56
xorwf Pelota_X, W
btfss STATUS, Z
goto Rebotes_Barra_Salir
;
movfw Pelota_Y
;
addlw 1
subwf Barra_Y, W
btfsc STATUS, C ; Si Pelota_Y>=Barra_Y
goto Rebotes_Barra_Salir
;
movfw Barra_Y
;
addlw 25
subwf Pelota_Y, W
16
Rebotes_Barra_Salir
;
;
; Comprobar la colision con los bloques
Colision_Bloques
sale
pelota
pelota
movlw b'11110000'
andwf Pelota_X, W
btfss STATUS, Z ; comprobar si X es <=15, si no,
goto Fin_Colision_Bloques
; comprobar si hay bloques en la posicion de la
; extraemos la pos. del bloque a partir de la
movfw Pelota_Y
movwf Temp_1
rrf
Temp_1, F
rrf
Temp_1, F
rrf
Temp_1, F
movlw b'00001111'
17
; bloques 8x8
Colision_Bloques_L1
bloque
borrar)
siguiente nivel
andwf Temp_1, F
btfss Pelota_X, 3
; comprobar si fila 1 o 2
goto Colision_Bloques_L1
bsf
Temp_1, 4 ; sumar 16
; accedemos al byte de ese
movlw Bloques
addwf Temp_1, W
movwf FSR
movfw INDF
btfsc STATUS, Z ; comprobamos si 0 (bloque borrado)
goto Fin_Colision_Bloques
;
; no es un cero, efectuamos rebotes
decf INDF
; si no decrementamos (marcar para
decfsz
goto Colision_Bloques_L2
;
;
Partida_Ganada ; cuando se gana una partida
; restar 10 al retardo si no es ya 10
movlw -10
addwf Espera, W
btfsc STATUS, Z
goto Partida_Ganada_L1
movwf Espera
Partida_Ganada_L1
; Esperamos 1 segundo antes de pasar de fase
call
Wait1Second
; iniciamos una nueva partida con mas velocidad
goto Iniciar_Partida
;
;
Colision_Bloques_L2
; comprobamos si entro por la derecha, izquierda, o
medio
Colision_Bloques_Comp_Izquierda
movlw b'00000111'
andwf Pelota_Y, W
; nos interesan los 3 ultimos
bits
btfss STATUS, Z ; si desplazamiento dentro bloque es
cero
goto Colision_Bloques_Comp_Derecha
movlw 255
; -1
movwf Inc_Y
goto Colision_Bloques_Comp_Arriba
Colision_Bloques_Comp_Derecha
movfw Pelota_Y
movwf Temp_3
movlw b'00000111'
andwf Temp_3, F ; solo 3 ultimos bits
xorwf Temp_3, F
btfss STATUS, Z
goto Colision_Bloques_Comp_Arriba
18
movlw 1
movwf Inc_Y
Colision_Bloques_Comp_Arriba
movlw b'00000111'
andwf Pelota_X, W
btfss STATUS, Z ; si desplazamiento dentro bloque es
cero
goto Colision_Bloques_Comp_Abajo
movlw 255
; -1
movwf Inc_X
goto Fin_Colision_Bloques
Colision_Bloques_Comp_Abajo
movfw Pelota_X
movwf Temp_3
movlw b'00000111'
andwf Temp_3, F
xorwf Temp_3, F
btfss STATUS, Z
goto Fin_Colision_Bloques
movlw 1
movwf Inc_X
; fin de rebotes
;
Fin_Colision_Bloques
; Fin de comprobar la colision con los bloques
;
goto
Loop
sta es la parte de las subrutinas, se divide en dos. Las que solo sirven para el juego y las ms
generales que controlan el lcd.
;------------------------------------------------------------------------; Subrutinas
;------------------------------------------------------------------------;
; Borra la barra
;
Borrar_Barra
;
;
clrw
goto Pintar_Barra_C
;
; Pinta la barra
;
19
Pintar_Barra
Pintar_Barra_C
Pintar_Barra_CS1
movlw b'00111111'
movwf LCD_Data
movlw b'11000000'
andwf Barra_Y, W
btfsc STATUS, Z ; que mitad LCD empezamos a pintar
goto Pintar_Barra_CS1
bsf
PORTA, LCD_CS1
bcf
PORTA, LCD_CS2 ; segunda mitad LCD
goto Pintar_Barra_Mover
bcf
bsf
Pintar_Barra_Mover
cambiar de mitad
Pintar_Barra_L1
Pintar_Barra_L2
;
;
movlw 64
xorwf Temp_2, W
btfss STATUS, Z ; hay que cambiar de mitad LCD?
goto Pintar_Barra_L2
bsf
PORTA, LCD_CS1
bcf
PORTA, LCD_CS2 ; segunda mitad LCD
movlw 7
movwf LCD_Page
call LCD_Set_Page_X ; seguir en la misma X
clrf LCD_Address
call LCD_Set_Address_Y ; Y=0
call LCD_Write_Display_Data
incf Temp_2, F
decfsz
Temp_1, F
goto Pintar_Barra_L1
return
;
;
; Pinta la mitad de los bloques en la media pantalla activa
;
Pintar_Bloques
20
clrf LCD_Address
clrf LCD_Page
call LCD_Set_Address_Y
call LCD_Set_Page_X
movlw 2
movwf Temp_Y
Pintar_Bloques_LY
movlw 8
movwf Temp_X
movwf LCD_Address ;esta variable apunta a la
siguiente
saltarse bloques
Pintar_Bloques_LX
bloque
movfw INDF
;
; Pintar_Bloque en el LCD
btfsc STATUS, Z
goto LCD_Saltarse_Bloque ; si era 0, saltarse
addlw 255
; -1
btfsc STATUS, Z ; si era 1, pintarlo en blanco
goto LCD_Pintar_Bloque_Blanco
LCD_Pintar_Bloque_Normal
; si era otro , pintar normal
movlw b'11111111'
movwf LCD_Data
call LCD_Write_Display_Data
movlw b'11000011'
movwf LCD_Data
call LCD_Write_Display_Data
movlw b'10100101'
movwf LCD_Data
call LCD_Write_Display_Data
movlw b'10011001'
movwf LCD_Data
call LCD_Write_Display_Data
movlw b'10011001'
movwf LCD_Data
call LCD_Write_Display_Data
movlw b'10100101'
movwf LCD_Data
call LCD_Write_Display_Data
movlw b'11000011'
movwf LCD_Data
call LCD_Write_Display_Data
movlw b'11111111'
movwf LCD_Data
call LCD_Write_Display_Data
goto LCD_Pintar_Bloque_Salir
LCD_Pintar_Bloque_Blanco
clrf LCD_Data
; pintar 8 pages en blanco
movlw 8
movwf Temp_3
LCD_Pintar_Bloque_Blanco_L1
call LCD_Write_Display_Data
21
LCD_Saltarse_Bloque
decfsz
Temp_3
goto LCD_Pintar_Bloque_Blanco_L1
;
decf INDF ; no pintar ya mas
goto LCD_Pintar_Bloque_Salir
call LCD_Set_Address_Y
LCD_Pintar_Bloque_Salir
; Fin de pintar_Bloque en el LCD
;
movlw 8
; incrementar el puntero
al
addwf LCD_Address, F ; siguiente bloque
incf FSR
decfsz
Temp_X
goto Pintar_Bloques_LX
;
movlw 8
; siguiente hilera de bloques
addwf FSR, F
incf LCD_Page
call LCD_Set_Page_X
decfsz
Temp_Y
goto Pintar_Bloques_LY
return
;
;
;
; Borra la pagina entera donde se encuentre el pixel especificado
; en LCD_Pixel_X, LCD_Pixel_Y
;
LCD_Clear_Pixel
movlw 0
goto LCD_Put_Pixel_L1
;
;
;
; Pinta pixel especificado en LCD_Pixel_X, LCD_Pixel_Y
;
LCD_Put_Pixel
movfw LCD_Pixel_X
andlw b'00000111'
call Pixel_Value
LCD_Put_Pixel_L1
movwf LCD_Data
bcf
PORTA, LCD_CS1
bsf
PORTA, LCD_CS2 ; primera mitad LCD
movfw LCD_Pixel_Y
movwf LCD_Address
andlw b'11000000'
btfsc STATUS, Z ; comprobar de que mitad es
goto LCD_Put_Pixel_L2
bsf
PORTA, LCD_CS1
22
LCD_Put_Pixel_L2
;
;
bcf
call LCD_Set_Address_Y
movfw LCD_Pixel_X
movwf LCD_Page
rrf
LCD_Page, F
rrf
LCD_Page, F
rrf
LCD_Page, F
call LCD_Set_Page_X
call LCD_Write_Display_Data
return
;
; Borra la mitad del LCD seleccionada en ese momento
;
LCD_Clear
; Limpiar pantalla
clrf LCD_Data
clrf LCD_Address
clrf LCD_Page
call LCD_Set_Page_X
call LCD_Set_Address_Y
LCD_Clear_L1
movlw 64
movwf Temp_2
LCD_Clear_L2
call LCD_Write_Display_Data
decfsz
Temp_2, F
goto LCD_Clear_L2
;
incf LCD_Page, F
call LCD_Set_Page_X
btfss LCD_Page, 3
goto LCD_Clear_L1
;
return
;
;
;
; Aqui empiezan las rutinas de mas bajo nivel del manejo del LCD
;
;
; Situa la Pagina activa de la mitad del LCD seleccionada en ese momento
; a LCD_Page
;
LCD_Set_Page_X
call Wait_For_Busy_Flag
bcf
PORTA, LCD_RW
bcf
PORTA, LCD_RS
23
;
;
movfw LCD_Page
iorlw b'11111000'
xorlw b'01000000'
movwf PORTB
call Wait
bsf
PORTA, LCD_E
call Wait
bcf
PORTA, LCD_E
return
;
; Situa la Y Address activa de la mitad del LCD seleccionada
; en ese momento a LCD_Address
;
LCD_Set_Address_Y
call Wait_For_Busy_Flag
bcf
PORTA, LCD_RW
bcf
PORTA, LCD_RS
movfw LCD_Address
iorlw b'11000000'
xorlw b'10000000'
movwf PORTB
call Wait
bsf
PORTA, LCD_E
call Wait
bcf
PORTA, LCD_E
return
;
;
;
; Escribe el dato en LCD_Data en la Pagina X y Direccion Y
; activas en la mitad seleccionada del LCD en ese momento
;
LCD_Write_Display_Data
call Wait_For_Busy_Flag
bcf
PORTA, LCD_RW
bsf
PORTA, LCD_RS
movfw LCD_Data
movwf PORTB
call Wait
bsf
PORTA, LCD_E
call Wait
bcf
PORTA, LCD_E
return
;
;
;
; Apaga la mitad seleccionada del LCD en ese momento
;
24
LCD_Off
;
;
call Wait_For_Busy_Flag
bcf
PORTA, LCD_RW
bcf
PORTA, LCD_RS
movlw b'00111110'
movwf PORTB
call Wait
bsf
PORTA, LCD_E
call Wait
bcf
PORTA, LCD_E
return
;
; Enciende la mitad seleccionada del LCD en ese momento
; y situa su Display Start Line a 0
;
LCD_On
call Wait_For_Busy_Flag
bcf
PORTA, LCD_RW
bcf
PORTA, LCD_RS
movlw b'00111111'
movwf PORTB
call Wait
bsf
PORTA, LCD_E
call Wait
bcf
PORTA, LCD_E
;
; Display Start Line = 0
;
call Wait_For_Busy_Flag
bcf
PORTA, LCD_RW
bcf
PORTA, LCD_RS
movlw b'11000000'
movwf PORTB
call Wait
bsf
PORTA, LCD_E
call Wait
bcf
PORTA, LCD_E
;
return
;
;
;
; Espera por la Busy Flag de la mitad del LCD seleccionada en ese momento
;
Wait_For_Busy_Flag
;
bsf
STATUS, RP0
; poner puerto B a leer
movlw H'FF'
movwf
TRISB
;
bcf
STATUS, RP0
;
;
25
bcf
PORTA, LCD_RS
bsf
PORTA, LCD_RW
;
call Wait
bsf
PORTA, LCD_E
call Wait
L1
estaba
;
;
btfsc
PORTB, 7
; BUSY=bit 7
goto L1
bcf
PORTA, LCD_E
;
bsf
STATUS, RP0
; dejar el puerto B como
clrf TRISB
bcf
STATUS, RP0
;
return
;
;
;
; Rutinas de espera
;
Optamos por usar una nica rutina Wait para todas las esperas al mandar instrucciones al LCD
(Tiempo que tiene que estar E alto/bajo, tiempo antes de poder leer, etc, todas siempre menos de 1
us). De esta forma podremos adaptar a otras velocidades de reloj si hace falta.
;
; Esperar 1 us a 12 mhz (sobra 1 ciclo contando el call y el return)
;
Wait
return
;
;
;
; Espera aproximadamente 1 milisegundo a 12 mhz
;
; [(8+1+1+2)*248]+(8+1+2)+8=2995 (sin contar el call)
Esperar_2995_Ciclos
movlw 249
nop
goto $+1
goto $+1
Esperar_2995_Ciclos_L1
goto $+1
goto $+1
goto $+1
goto $+1
addlw -1
btfss STATUS, Z
26
goto Esperar_2995_Ciclos_L1
return
;
; Espera el numero de ms especificados en W
;
WaitNms
movwf Temp_Count
WaitNms_L1
call Esperar_2995_Ciclos
decfsz
Temp_Count
goto WaitNms_L1
return
;
;
;
; Espera 1 Segundo
;
Wait1Second
movlw
call
movlw
call
movlw
call
movlw
goto
250
WaitNms
250
WaitNms
250
WaitNms
250
WaitNms
END
27
Bibliografa:
1. Manual LCD grfico CFAG12864BTMIV (http://www.crystalfontz.com/)
2. Manual PIC16F84A (http://microchip.com/)
3. Standard TTL logic levels (http://www.twysted-pair.com/74xx.htm)
28