List p=16F877 ;Tipo de procesador
include "P16F877.inc"
#define Fosc 20000000 ;Velocidad de trabajo
__config _CP_OFF&_CPD_OFF&_WDT_OFF&_HS_OSC&_BODEN_OFF&_LVP_OFF
N_FILAS equ .128 ;Resolución vertical del LCD
N_COLUMNAS equ .240 ;Resolución horizontal del LCD
TEXT_HOME equ 0x0000 ;Dirección de inicio de la RAM para visualizar texto
GRAPH_HOME equ 0x0200 ;Dirección de inicio de la RAM para visualizar gráficos
TEXT_AREA equ N_COLUMNAS/8 ;Máxima área para visualizar texto
GRAPH_AREA equ N_COLUMNAS/8 ;Máxima área para visualizar gráficos
Contador equ 0x20
Secuencia equ 0x21 ;Contador de secuencias
Random_H equ 0x22 ;
Random_L equ 0x23 ;Variables para el nº aleatorio
org 0x00
goto Reset ;Vector de Reset
org 0x05
;******************************************************************************************
;Según el valor contenido en el registro W, se devuelve el carácter a visualizar
Tabla_Mensajes movwf PCL ;Calcula el desplazamiento sobre la tabla
;***********************************************************************************
;La directiva dt genera tantas intsrucciones retlw como bytes o caracteres contenga
Mens_0 equ $ ;Mens_0 apunta al primer carácter del mensaje 0
dt "Hello Word !",0x00
Mens_1 equ $ ;Mens_1 apunta al primer carácter del mensaje 1
dt "Microsystems",0x00
Mens_2 equ $ ;Mens_2 apunta al primer carácter del mensaje 2
dt "Engineering",0x00
Mens_3 equ $ ;Mens_3 apunta al primer carácter del mensaje 3
dt "PIC16F.",0x00
include "T6963C_PIC16F.INC" ;Incluir rutinas básicas de manejo de LCD gráfico
include "MSE_Delay.inc" ;Incluir rutinas de temporización
;******************************************************************************************
;Mensaje: Esta rutina visualiza en el LCD el mensaje cuyo inicio está indicado en
;el acumulador. El fin de un mensaje se determina mediante el código 0x00 y se supone que se
;estableció la dirección inicial de la RAM de texto.
Mensaje movwf Temporal_1 ;Salva posición de la tabla
Mensaje_1 movf Temporal_1,W ;Recupera posición de la tabla
call Tabla_Mensajes ;Busca caracter de salida
movwf DATABUFA ;Guarda el caracter
movf DATABUFA,F
btfss STATUS,Z ;Mira si es el último
goto No_es_ultimo
return
No_es_ultimo movlw 0x20
subwf DATABUFA,F ;Ajusta carácter ASCII al juego de caracteres del T6963C
movlw 0xc0
movwf COMMANDBUF
call SEND_1DATA_CMD ;Escribe el carácter sobre el LCD
incf Temporal_1,F ;Siguiente caracter
goto Mensaje_1
;********************************************************************************************************
;Random - Esta rutina genera un nº aleatorio de 16 bits que se deposita en Random_H y Random_L. Estas
;variables se pueden cargar un un nº inicial o "semilla" o bien se dejan con el valor alatorio tras el
;power-up.
Random clrf Temporal_1
clrf Temporal_2
btfsc Random_L,3
bsf Temporal_1,0
btfsc Random_H,6
bsf Temporal_1,1
btfsc Random_H,4
bsf Temporal_2,0
btfsc Random_H,7
bsf Temporal_2,1
movf Temporal_2,W
xorwf Temporal_1,F ;Función XOR entre los bits 3-12 y 14-15 (a=3^12 y b= 14^15)
clrf Temporal_2
btfsc Temporal_1,1
bsf Temporal_2,0
movf Temporal_2,W
xorwf Temporal_1,F ;Función XOR entre a y b (c=a^b)
bcf STATUS,C
btfsc Temporal_1,0
bsf STATUS,C ;El resultado de la XOR pasa al Carry
rlf Random_L,F
rlf Random_H,F ;Rotación a la izda. del Nº aleatorio.
return
;***************************** INICIO DEL PROGRAMA PRINCIPAL *************************************
Reset bsf STATUS,RP0 ;Selecciona el banco 1
btfsc PCON,NOT_POR ;Ha sido Power UP ??
goto No_power_up ;No
bsf PCON,NOT_POR ;Si, desactiva flag de Power UP
bcf STATUS,RP0 ;Selecciona el banco 0
movlw b'00000001'
movwf Secuencia ;Inicia contador de secuencias
goto Inicio
No_power_up bcf STATUS,RP0 ;Selecciona el banco 0
bcf STATUS,C
rlf Secuencia,F ;Ajusta el contador de tareas
btfss Secuencia,3 ;Se han hecho todas ??
goto Inicio ;No
movlw b'00000001'
movwf Secuencia ;Si, ajusta contador de tareas
Inicio Delay 60 Milis ;Temporiza 60mS para el Power-Up del LCD
bsf STATUS,RP0 ;Selecciona banco 1
movlw 0x06
movwf ADCON1 ;Puerta A digital
bcf STATUS,RP0 ;Selecciona banco 0
call LCD_CONFIG ;Configura puertos de E/S para interface con el LCD
;*************************************** BUCLE PRINCIPAL ***************************************
btfsc Secuencia,0 ;hay que hacer la secuencia 0 ??
goto Sec_0_0 ;Si
btfsc Secuencia,1 ;Hay que hacer la secuencia 1 ??
goto Sec_1 ;Si
goto Sec_2 ;No, hacer la secuencia 2
;**************************** Secuencia 0: Presentación de MSE *********************************
Sec_0_0 call LCD_GRAPH_INI ;Inicia la pantalla en modo gráfico y borra pantalla
call LCD_TEXT_INI ;Inicia la pantalla en modo texto y borra la pantalla
MOVLW TEXT_ON_GRAPH_ON
movwf COMMANDBUF
CALL SEND_CMD ; Display gráfico ON, texto en ON
movlw XOR_MODE
movwf COMMANDBUF
call SEND_CMD ;Función XOR entre el modo texto y el modo gráfico
;********************************************************************************************************
;Dibuja una barra gráfica horizontal de 13 pixels de grosor a partir de la fila 6ª y de un extremo al otro
movlw high (GRAPH_HOME+(GRAPH_AREA*(6-1)))
movwf DATABUFA
movlw low (GRAPH_HOME+(GRAPH_AREA*(6-1)))
movwf DATABUFB ;Calcula la dirección inicial en función de la fila deseadea
movlw SET_ADDR_PTR
movwf COMMANDBUF
call SEND_2DATA_CMD ;Ajusta dirección de inicio en RAM gráfica para la barra horizontal
movlw high (GRAPH_AREA*13)+1
movwf H_byte
movlw low (GRAPH_AREA*13)
movwf L_byte ;Nº de bytes a escribir en modo gráfico
Sec_0_1 movlw 0xff ;Byte a escribir (0xFF=11111111). Se escriben 8 pixels
movwf DATABUFA ;horizontales por cada byte
movlw 0xc0
movwf COMMANDBUF ;Comando de escritura
call SEND_1DATA_CMD
decfsz L_byte,F ;Repetir la escritura
goto Sec_0_1
decfsz H_byte,F ;Fin ??
goto Sec_0_1 ;No
;********************************************************************************************
;Imprime el mensaje de texto "Hello Word !" en la fila 2ª, 2ª columna
movlw .2
movwf Y
movlw .2
movwf X
call SET_TEXT_XY ;Calcula la dirección de la fila 2ª, 2ª columna
movlw Mens_0
call Mensaje ;Visualiza el mensaje
;*********************************************************************************************
;Inicia una intermitencia del texto mediante la conexión/desconexión de la RAM de texto
movlw .5
movwf Contador ;Se realizan 5 intermitencias
Sec_0_2 movlw TEXT_OFF_GRAPH_ON
movwf COMMANDBUF
call SEND_1DATA_CMD ;Desconecta la RAM de texto
Delay 500 Milis ;Temporiza 0,5 seg.
movlw TEXT_ON_GRAPH_ON
movwf COMMANDBUF
call SEND_1DATA_CMD ;Conecta la RAM de texto
Delay 500 Milis ;Temporiza 0,5 seg.
decfsz Contador,F ;Repite la intermitencia
goto Sec_0_2
;********************************************************************************************
;Imprime el mensaje de texto "Microsystems" en la fila 7ª , columna 0
movlw .7
movwf Y
movlw 0
movwf X
call SET_TEXT_XY ;Calcula la dirección de la fila 7ª, columna 0
movlw Mens_1
call Mensaje ;Visualiza el mensaje
;********************************************************************************************
;Imprime el mensaje de texto "Engineering" en la fila 8ª, 5ª columna
movlw .8
movwf Y
movlw .5
movwf X
call SET_TEXT_XY
movlw Mens_2
call Mensaje ;Visualiza el mensaje
;*********************************************************************************************
;Dibuja una línea gráfica horizontal de 1 pixel de grosor a partir de la 47ª fila y de un
;extremo al otro
movlw high (GRAPH_HOME+(GRAPH_AREA*(47-1)))
movwf DATABUFA
movlw low (GRAPH_HOME+(GRAPH_AREA*(47-1)))
movwf DATABUFB ;Calcula la dirección inicial en función de la fila deseadea
movlw SET_ADDR_PTR
movwf COMMANDBUF
call SEND_2DATA_CMD ;Ajusta dirección de inicio en RAM gráfica para la barra horizontal
movlw (N_COLUMNAS/8)*1
movwf Temporal_1 ;Nº de bytes a escribir en modo gráfico
Sec_0_3 movlw 0xff ;Byte a escribir (0xFF=11111111). Se escriben 8 pixels
movwf DATABUFA ;horizontales por cada byte
movlw 0xc0
movwf COMMANDBUF ;Comando de escritura
call SEND_1DATA_CMD
decfsz Temporal_1,F ;Repetir la escritura
goto Sec_0_3
;*********************************************************************************************
;Dibuja una línea gráfica horizontal de 1 pixel de grosor a partir de la 66ª fila y de un
;extremo al otro
movlw high (GRAPH_HOME+(GRAPH_AREA*(66-1)))
movwf DATABUFA
movlw low (GRAPH_HOME+(GRAPH_AREA*(66-1)))
movwf DATABUFB ;Calcula la dirección inicial en función de la fila deseadea
movlw SET_ADDR_PTR
movwf COMMANDBUF
call SEND_2DATA_CMD ;Ajusta dirección de inicio en RAM gráfica para la barra horizontal
movlw (N_COLUMNAS/8)*1
movwf Temporal_1 ;Nº de bytes a escribir en modo gráfico
Sec_0_4 movlw 0xff ;Byte a escribir (0xFF=11111111). Se escriben 8 pixels
movwf DATABUFA ;horizontales por cada byte
movlw 0xc0
movwf COMMANDBUF ;Comando de escritura
call SEND_1DATA_CMD
decfsz Temporal_1,F ;Repetir la escritura
goto Sec_0_4
Delay 200 Milis ;Temporiza 0,2 seg.
;********************************************************************************************
;Imprime el mensaje de texto "PIC16F." en la fila 16ª, 9ª columna
movlw .16 ;high (TEXT_HOME+(TEXT_AREA*(16-1))+9)
movwf Y ;DATABUFA
movlw .9 ;low (TEXT_HOME+(TEXT_AREA*(16-1))+9)
movwf X ;DATABUFB
call SET_TEXT_XY ;Calcula la dirección de la fila 16ª, 9ª columna
movlw Mens_3
call Mensaje ;Visualiza el mensaje
;*********************************************************************************************
;Dibuja 10 líneas gráficas horizontales de 1 pixel de grosor a partir de la columna 72 hasta
;el final y a partir de la fila 118
movlw high (GRAPH_HOME+(GRAPH_AREA*(119-1))+(72/8))
movwf H_byte
movlw low (GRAPH_HOME+(GRAPH_AREA*(119-1))+(72/8))
movwf L_byte ;Calcula la dirección inicial en función de la fila deseadea
movlw .10
movwf Contador ;Nº de líneas o filas a dibujar
Sec_0_5 movf H_byte,W
movwf DATABUFA
movf L_byte,W
movwf DATABUFB
movlw SET_ADDR_PTR
movwf COMMANDBUF
call SEND_2DATA_CMD ;Ajusta dirección de inicio en RAM gráfica para la 1ª línea horizontal
movlw (N_COLUMNAS-.72)/8
movwf Temporal_1 ;Nº de bytes a escribir en modo gráfico
Sec_0_6 movlw 0xff ;Byte a escribir (0xFF=11111111). Se escriben 8 pixels
movwf DATABUFA ;horizontales por cada byte
movlw 0xc0
movwf COMMANDBUF ;Comando de escritura
call SEND_1DATA_CMD
decfsz Temporal_1,F ;Repetir la escritura
goto Sec_0_6
movlw GRAPH_AREA
addwf L_byte,F
btfsc STATUS,C
incf H_byte,F ;Calcular la dirección de la siguiente fila
decfsz Contador,F ;Se han dibujado todas las líneas ??
goto Sec_0_5 ;No, hacer la siguiente
Delay 2000 Milis
Delay 2000 Milis ;Si, temporizar 4 segundos
;*********************************************************************************************
;Inicia una intermitencia del texto y gráfico mediante la conexión/desconexión de la RAM de
;textos y gráficos
movlw .5
movwf Contador ;Se realizan 5 intermitencias
Sec_0_7 movlw DISPLAY_OFF
movwf COMMANDBUF
call SEND_1DATA_CMD ;Desconecta la RAM de texto y gráficos (DISPLAY_OFF)
Delay 500 Milis ;Temporiza 0,5 seg.
movlw TEXT_ON_GRAPH_ON
movwf COMMANDBUF
call SEND_1DATA_CMD ;Conecta la RAM de texto y gráficos
Delay 500 Milis ;Temporiza 0,5 seg.
decfsz Contador,F ;Repite la intermitencia
goto Sec_0_7
Delay 1000 Milis ;Temporiza 1 seg.
goto Sec_0_0 ;Repetir el bucle
;**************************** Secuencia 1: Puntos aleatorios *********************************
Sec_1 call LCD_GRAPH_INI ;Inicia la pantalla en modo gráfico, y borra pantalla
MOVLW TEXT_OFF_GRAPH_ON
movwf COMMANDBUF
CALL SEND_CMD ; Display gráfico ON, texto en OFF
bsf CTRL_BITS,3 ;El pixel se pinta en negro
Sec_1_0 call Random ;Obtiene un nº aleatorio de 16 bits
movlw ~N_COLUMNAS
subwf Random_H,W
movwf X ;La parte alta del nº determina la coordenada X
movlw ~N_FILAS
subwf Random_L,W
movwf Y ;La parte baja del nº determina la coordenada Y
call PIXEL ;Dibuja el pixel
Delay 2 Milis ;Temporiza 2 miliseg.
goto Sec_1_0 ;Repetición indefinida
;**************************** Secuencia 2: Líneas aleatorias *********************************
Sec_2 call LCD_GRAPH_INI ;Inicia la pantalla en modo gráfico, y borra pantalla
MOVLW TEXT_OFF_GRAPH_ON
movwf COMMANDBUF
CALL SEND_CMD ;Display gráfico ON, texto en OFF
bsf CTRL_BITS,3 ;Los pixels se pintarán en negro
;Dibuja una línea horizantal
Sec_2_0 call Random ;Busca nº aleatorio
movlw ~N_COLUMNAS
subwf Random_H,W
movwf X_org ;La parte alta del nº determina la coordenada X de origen
movlw ~N_FILAS
subwf Random_L,W
movwf Y_org ;La parte baja del nº determina la coordenada Y de origen
call Random ;Busca otro nº aleatroio
movlw ~N_COLUMNAS
subwf Random_H,W
movwf X_des ;La parte alta del nº determina la coordenada X de destino
call LINEA_H ;Dibuja línea horizontal
;Dibuja una línea vertical
call Random ;Busca nº aleatorio
movlw ~N_COLUMNAS
subwf Random_H,W
movwf X_org ;La parte alta del nº determina la coordenada X de origen
movlw ~N_FILAS
subwf Random_L,W
movwf Y_org ;La parte baja del nº determina la coordenada Y de origen
call Random ;Busca otro nº aleatroio
movlw ~N_FILAS
subwf Random_H,W
movwf X_des ;La parte alta del nº determina la coordenada Y de destino
call LINEA_V ;Dibuja línea vertical
Delay 200 Milis ;Temporiza 0.2 seg.
goto Sec_2_0