Hola amigos,
Estoy trabajando con un proyecto de un medidor de baterias ya desde hace tiempo. Ya tengo trabajando el display, tambien la parte del teclado y hasta la del conversor AD solo que estoy integrandolo todo poco a poco. Por esta razon de que voy armando e integrando por partes, les comento que en el display puse un menu de 6 opciones, estos letreros aparecen perfectamente. En otra rutina que he probado aparte probe el teclado que va moviendo un cursor (->) de arriba hacia abajo y donde se quede se puede presionar otra tecla de Enter y seleccionar esa opcion del menu. Esta parte tambien ya la tengo probada. Mi problma es al tratar de integrar ambas partes, me explico.... la prueba de ir hacia arriba y hacia abbajo con el teclado y seleccionar con Enter la hice de una manera muy simple es decir solo puse los numeros del menu para verificar que el cursor sube y baja adecuadamente:
-> 1
2
3
4
5
6
Como les comento esta parte funciona bien. Por separado los letreros del Menu son:
-> 1-Lect SIN Resistencia
2-Lect CON Resistencia
3-Cargar Datos de Mem
4-Guardar Datos en Mem
5-Borrar Datos de Mem
6-Enviar Datos a PC
Esta parte por separado tambien trabaja bien. Cuando integro a esta secuencia del Menu la parte de la deteccion de las teclas para que suba y baje el cursor algunas secciones del menu (caracteres) desaparecen o sale todo cambiado el menu o como si se bloqueara en el despliegue del mismo, en general ya no aparece correctamente, insisto aun cuando ambas partes o secciones funcionan bien de manera individual. Pareciera como si se bloqueara el PIC a partir de cierto numero de renglones del codigo pero no es tan grande como para que haga esto.
A continuacion listo el codigo que muestra el Menu correctamente y aparte el que trato de integrar o adicionar y causa que ya nalga bien el menu
;*******************************************************************************************************************
;*********************************** MEDIDOR DE BATERIAS ******************************************
;*********************************** DC Sentinel ******************************************
;*********************************** CON DISPLAY SS16D80DLGW-E ******************************************
;*********************************** y PIC16F877A ******************************************
;*******************************************************************************************************************
list p=16f877A
include "p16f877A.inc"
errorlevel -302 ; supress "register not in bank0, check page bits" message
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _LVP_OFF & _CPD_OFF; & _WRT_ENABLE_ON & _DEBUG_ON
#DEFINE VBAT PORTA, 0 ;Input - Voltaje de Entrada de Baterias
#DEFINE Q1SW PORTA, 1 ;Output - Activacion de Switch de disparo para Resistencia de Descarga
#DEFINE BUZZER PORTA, 2 ;Output - Activacion del Buzzer
#DEFINE BatLev PORTA, 3 ;Input - Deteccion de Nivel de Bateria
#DEFINE DC_OK_NOK PORTA, 4 ;Output - Deteccion de conexion en baterias: No Conexion, Polaridad
#DEFINE DC_OV_PROT PORTA, 5 ;Input - Deteccion de Sobrevoltaje de Baterias
#DEFINE lcd_DAT PORTB ;Output - Datos para el display LCD
#DEFINE lcd_RS PORTC, 0 ;LCD Register Select: Data = 0 / Instruction = 1
#DEFINE lcd_RW PORTC, 1 ;LCD Read/Write Selection
#DEFINE lcd_E PORTC, 2 ;LCD Enable Signal
#DEFINE lcd_DOFF PORTC, 4 ;LCD Display Off Signal DISP OFF=0 DISP ON=1
#DEFINE lcd_RST PORTC, 5 ;LCD Reset Signal ACTIVE LOW
#DEFINE TXsend PORTC, 6 ;Envio de datos por RS232
PDel0 equ 0x26 ;PDel0 a PDel9 variables de retardos
PDel1 equ 0x27
PDel2 equ 0x28
PDel3 equ 0x29
PDel4 equ 0x2A
PDel5 equ 0x2B
PDel6 equ 0x2C
TEMP equ 0x2D
TEMP1 equ 0x2E
TEMP2 equ 0x2F
TEMP3 equ 0x30
ARR equ 0x31
J equ 0x32
K equ 0x33
TxtDat equ 0x34
TECLA EQU 0x38
KEY1 EQU 0x39
KEY2 EQU 0x3A
org 0x00 ;Inicio de Programa
goto INICIO
;*****************************************************************************************
;Main program
;*****************************************************************************************
INICIO:
banksel ADCON1 ;Cambia a Bank 1
movlw 0x29 ;PORTA RA0:RA5 = 101001 = 29H
movwf PORTA
movlw 0x00 ;Pone a w = 00000000
movwf PORTB ;Pone a PORTB como salidas
movlw 0x80 ;Pone a w = 10000000
movwf PORTC ;Pone a RC0-RC6 como salidas y RC7-TX como entrada
movlw 0x06 ;Pone a RA0-RA5 como digitales
movwf ADCON1 ;ADFM, A/D Result Format = Left justified
banksel ADCON0 ;Cambia a Bank 0
clrf STATUS
bcf lcd_DOFF
call LCD_TXT_INIT
call ClrDisp
bsf lcd_DOFF
;*******************************************************************************
;*************************** DC Sentinel Menu Principal *********************
;*******************************************************************************
MenuPal
movlw 0x0A ;Cursor low address setting
call Send_CMD
movlw 0x06 ;Low address start
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
clrf J
banksel PCL
GetDat movlw HIGH Txt_Menu
movwf PCLATH
movf J,W
call Txt_Menu
movwf TxtDat ;Pone el dato recibido en W en TxtDat
movlw 0x0C ;Write Display Data
call Send_CMD
movf TxtDat,W
call Send_DAT
incf J,1
movlw 0x0E
xorwf J,W
btfss STATUS,Z ;Si XOR entre J y W dio cero, son iguales y salta Z=1
goto GetDat
;*****************************************************************************
;*************************** 1 - Lect SIN Resistencia ***********************
;*****************************************************************************
movlw 0x3A
movwf K
movlw 0x0A ;Cursor low address setting
call Send_CMD
movf K,W ;Low address start
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
movlw 0x0C ;Write Display Data
call Send_CMD
movlw 0x7E ;->
call Send_DAT
clrf J
banksel PCL
GetDat1 movlw HIGH Txt_Menu1
movwf PCLATH
movf J,W
call Txt_Menu1
movwf TxtDat ;Pone el dato recibido en W en TxtDat
movlw 0x0C ;Write Display Data
call Send_CMD
movf TxtDat,W
call Send_DAT
incf J,1
movlw 0x16
xorwf J,W
btfss STATUS,Z ;Si XOR entre J y W dio cero, son iguales y salta Z=1
goto GetDat1
;******************************************************************************
;*************************** 2 - Lect CON Resistencia ***********************
;******************************************************************************
movlw 0x0A ;Cursor low address setting
call Send_CMD
movlw 0x57 ;Low address start
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
clrf J
banksel PCL
GetDat2 movlw HIGH Txt_Menu2
movwf PCLATH
movf J,W
call Txt_Menu2
movwf TxtDat ;Pone el dato recibido en W en TxtDat
movlw 0x0C ;Write Display Data
call Send_CMD
movf TxtDat,W
call Send_DAT
incf J,1
movlw 0x16
xorwf J,W
btfss STATUS,Z ;Si XOR entre J y W dio cero, son iguales y salta Z=1
goto GetDat2
;*******************************************************************************
;*************************** 3 - Cargar Datos de Mem ************************
;*******************************************************************************
movlw 0x0A ;Cursor low address setting
call Send_CMD
movlw 0x73 ;Low address start
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
clrf J
banksel PCL
GetDat3 movlw HIGH Txt_Menu3
movwf PCLATH
movf J,W
call Txt_Menu3
movwf TxtDat ;Pone el dato recibido en W en TxtDat
movlw 0x0C ;Write Display Data
call Send_CMD
movf TxtDat,W
call Send_DAT
incf J,1
movlw 0x16
xorwf J,W
btfss STATUS,Z ;Si XOR entre J y W di cero, son iguales y salta Z=1
goto GetDat3
;*******************************************************************************
;*************************** 4 - Guardar Datos en Mem **********************
;*******************************************************************************
movlw 0x0A ;Cursor low address setting
call Send_CMD
movlw 0x8F ;Low address start
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
clrf J
banksel PCL
GetDat4 movlw HIGH Txt_Menu4
movwf PCLATH
movf J,W
call Txt_Menu4
movwf TxtDat ;Pone el dato recibido en W en TxtDat
movlw 0x0C ;Write Display Data
call Send_CMD
movf TxtDat,W
call Send_DAT
incf J,1
movlw 0x15
xorwf J,W
btfss STATUS,Z ;Si XOR entre J y W dio cero, son iguales y salta Z=1
goto GetDat4
;*******************************************************************************
;*************************** 5 - Borrar Datos de Mem ************************
;*******************************************************************************
movlw 0x0A ;Cursor low address setting
call Send_CMD
movlw 0xAB ;Low address start
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
clrf J
banksel PCL
GetDat5 movlw HIGH Txt_Menu5
movwf PCLATH
movf J,W
call Txt_Menu5
movwf TxtDat ;Pone el dato recibido en W en TxtDat
movlw 0x0C ;Write Display Data
call Send_CMD
movf TxtDat,W
call Send_DAT
incf J,1
movlw 0x15
xorwf J,W
btfss STATUS,Z ;Si XOR entre J y W dio cero, son iguales y salta Z=1
goto GetDat5
;*******************************************************************************
;*************************** 6 - Enviar Datos a PC ****************************
;*******************************************************************************
movlw 0x0A ;Cursor low address setting
call Send_CMD
movlw 0xC7 ;Low address start
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
clrf J
banksel PCL
GetDat6 movlw HIGH Txt_Menu6
movwf PCLATH
movf J,W
call Txt_Menu6
movwf TxtDat ;Pone el dato recibido en W en TxtDat
movlw 0x0C ;Write Display Data
call Send_CMD
movf TxtDat,W
call Send_DAT
incf J,1
movlw 0x13
xorwf J,W
btfss STATUS,Z ;Si XOR entre J y W dio cero, son iguales y salta Z=1
goto GetDat6
; goto MenuPal
; return
;*****************************************************************************************************
;********************** SECUENCIA DE DETECCION DE TECLAS EN KEYPAD *********************
;*****************************************************************************************************
;********************************************************************************************************
;***************** SUBRUTINA DE INICIALIZACION DE DISPLAY EN TEXT MODE *******************
;********************************************************************************************************
LCD_TXT_INIT:
bcf lcd_RST ;Reset siganl on
bsf lcd_RST ;Reset signal off
movlw 0x00 ;Command code--Mode control
call Send_CMD
movlw 0x30 ;Set 110000
;Display ON, Master Mode, Cursor OFF, Internal CG, Character Mode
call Send_DAT ;Data complete
movlw 0x01 ;Character pitch setting
call Send_CMD
movlw 0x75 ;Set 01110101
;Vp=8, Hp=6 -> 5x7
call Send_DAT ;Data complete
movlw 0x02 ;Character number setting
call Send_CMD
movlw 0x1A ;Hn=160/6=26.66 -> 27 Char in one line
;Hn-1=26Dec -> 1AH
; movlw 0x1F ;Hn=160/5=32 Char in one line
;Hn-1=31Dec -> 1FH
call Send_DAT ;Data complete
movlw 0x03 ;Display duty setting
call Send_CMD
movlw 0x4F ;Set Nx=80
;Nx-1=79Dec -> 4FH
call Send_DAT ;Data complete
movlw 0x08 ;Cursor low address setting
call Send_CMD
movlw 0x00 ;Low address start from 00H
call Send_DAT ;Data complete
movlw 0x09 ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
return
;************************ Envia Comando al lcd ***********************
;write instruction sub routine
;RS=0,RW=0,E=high pulse ,D0-D7=code of instruction
;*********************************************************************
Send_CMD:
movwf TEMP ;Registro temporal para guardar dato
call CHK_BUSY ;Checa la linea de Busy
nop
bcf lcd_RW ;Modo Write
bsf lcd_RS ;Modo Instruction Register
bsf lcd_E
nop
movfw TEMP
movwf PORTB ;Envia comando
bcf lcd_E
nop
nop
nop
nop
return
;************************ Envia Datos al lcd ***********************
;write data subroutine.
;RS=1,RW=0,E=high pulse ,D0-D7=data
;**********************************************************
Send_DAT:
movwf TEMP ;Registro temporal para guardar dato
call CHK_BUSY ;Checa la linea de Busy
nop
bcf lcd_RW ;Modo Write
bcf lcd_RS ;Modo Data Register
bsf lcd_E
nop
movfw TEMP
movwf PORTB ;Envia comando
bcf lcd_E
nop
nop
nop
nop
return
;************************** Checa la linea de Busy **********************
;test busy subroutine
;RS=0,RW=1,E=H,D0-D7=status byte
;************************************************************************
CHK_BUSY:
banksel ADCON1 ;Cambia a Bank 1
movlw 0xFF ;Pone a w = 11111111
movwf PORTB ;Pone a PORTB como entradas
banksel ADCON0 ;Cambia a Bank 0
bcf lcd_RS
bsf lcd_RW
bsf lcd_E
BUSY_1 btfsc PORTB,7 ;Si D7=1 indica que Busy esta activo
goto BUSY_1
bcf lcd_E
banksel ADCON1 ;Cambia a Bank 1
movlw 0x00 ;Pone a w = 00000000
movwf PORTB ;Pone a PORTB como salidas
banksel ADCON0 ;Cambia a Bank 0
return
;******************************************************************************
;*********************** Rutina para limpiar display ************************
;******************************************************************************
ClrDisp:
movlw 0x0A ;Cursor low address setting
call Send_CMD
movlw 0x00 ;Low address start from 00H
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
movlw 0xFF
movwf TEMP1
ClrTxt1 movlw 0x0C ;Write Display Data
call Send_CMD
movlw 0x20
call Send_DAT
decfsz TEMP1, F
goto ClrTxt1
movlw 0x3C
movwf TEMP1
ClrTxt2 movlw 0x0C ;Write Display Data
call Send_CMD
movlw 0x20
call Send_DAT
decfsz TEMP1, F
goto ClrTxt2
return
;*************************************************************************
;************************ Delay subroutines **************************
;*************************************************************************
Delay_10ms:
movlw .21
movwf PDel0
PLoop0 movlw .237
movwf PDel1
PLoop1 clrwdt
decfsz PDel1, 1
goto PLoop1
decfsz PDel0, 1
goto PLoop0
goto PDelL0
PDelL0 clrwdt
return
;***********************************************************************
Delay_50ms:
movlw .110
movwf PDel2
PLoop2 movlw .181
movwf PDel3
PLoop3 clrwdt
clrwdt
decfsz PDel3, 1
goto PLoop3
decfsz PDel2, 1
goto PLoop2
goto PDelL1
PDelL1 goto PDelL2
PDelL2 clrwdt
return
;***********************************************************************
Delay_500ms:
movlw .14
movwf PDel4
PLoop4 movlw .72
movwf PDel5
PLoop5 movlw .247
movwf PDel6
PLoop6 clrwdt
decfsz PDel6, 1
goto PLoop6
decfsz PDel5, 1
goto PLoop5
decfsz PDel4, 1
goto PLoop4
goto PDelL3
PDelL3 clrwdt
return
;********************************************************************************************************************************
Txt_Menu:
addwf PCL, f ;14dec - 0EH caracteres
dt 0x4D,0x65,0x6E,0x75,0x20,0x50,0x72,0x69,0x6E,0x63,0x69,0x70,0x61,0x6C
Txt_Menu1:
addwf PCL, f ;22dec - 16H caracteres
dt 0x31,0x2D,0x4C,0x65,0x63,0x74,0x20,0x53,0x49,0x4E,0x20,0x52,0x65,0x73,0x69,0x73,0x74,0x65,0x6E,0x63,0x69,0x61
Txt_Menu2:
addwf PCL, f ;22dec - 16H caracteres
dt 0x32,0x2D,0x4C,0x65,0x63,0x74,0x20,0x43,0x4F,0x4E,0x20,0x52,0x65,0x73,0x69,0x73,0x74,0x65,0x6E,0x63,0x69,0x61
Txt_Menu3:
addwf PCL, f ;21dec - 15H caracteres
dt 0x33,0x2D,0x47,0x75,0x61,0x72,0x64,0x61,0x72,0x20,0x44,0x61,0x74,0x6F,0x73,0x20,0x65,0x6E,0x20,0x4D,0x65,0x6D
Txt_Menu4:
addwf PCL, f ;22dec - 16H caracteres
dt 0x34,0x2D,0x43,0x61,0x72,0x67,0x61,0x72,0x20,0x44,0x61,0x74,0x6F,0x73,0x20,0x64,0x65,0x20,0x4D,0x65,0x6D
Txt_Menu5:
addwf PCL, f ;21dec - 15H caracteres
dt 0x35,0x2D,0x42,0x6F,0x72,0x72,0x61,0x72,0x20,0x44,0x61,0x74,0x6F,0x73,0x20,0x64,0x65,0x20,0x4D,0x65,0x6D
Txt_Menu6:
addwf PCL, f ;19dec - 13H caracteres
dt 0x36,0x2D,0x45,0x6E,0x76,0x69,0x61,0x72,0x20,0x44,0x61,0x74,0x6F,0x73,0x20,0x61,0x20,0x50,0x43
end
;*****************************************************************************************************
;********************** SECUENCIA DE DETECCION DE TECLAS EN KEYPAD *********************
;*****************************************************************************************************
;KEYDETECT
banksel ADCON1 ;Cambia a Bank 1
movlw 0x38 ;Carga w = 11111000
movwf PORTD ;RD0-RD2 como salidas y RD3-RD5 como entradas
banksel ADCON0 ;Cambia a Bank 0
movlw 0x03 ;No de columnas a explorar N+1=3
movwf KEY1
movlw 0x3B ;Se activa con 0 la primera columna w = 11111011
movwf TECLA
KEY_SCAN
movf TECLA, w
movwf PORTD
nop
movf PORTD, w ;Se lee el puerto D y se almacena en KEY2
movwf KEY2
subwf TECLA, w ;Se comparan TECLA y KEY2 => w = TECLA - KEY2
btfss STATUS, Z ;Si w = TECLA - KEY2 = 0, STATUS (Z) = 1, no se activo la tecla y salta
goto KEY_ACT ;Si w = TECLA - KEY2 no es cero, entonces se activo una tecla
bsf STATUS, C
rrf TECLA, F ;Se selecciona la siguiente columna
decfsz KEY1, F ;Se decrementa el No de columnas a explorar. Si es cero salta
goto KEY_SCAN ;El No de columnas no es cero
movlw 0x03 ;No de columnas a explorar
movwf KEY1
movlw 0x3B ;Se activa con 0 la primera columna w = 11111011
movwf TECLA
goto KEY_SCAN
KEY_ACT
goto MenuPal
; return
Espero haberme explicado en cuanto lo que hace este programita y lo que no hace o el problema en si que tiene. Espero me puedan orientar en cuanto que debo hacer. No creo quea cuestion del hardware ya lo revise y esta todo bien cableado, lo tengo montado en una tablilla perforada, estaba pensando en que me falte declarar algo en los bits de configuracion o en que alguna secuencia pueda estar causando el "bloqueo" aun cuando independientes funcionesn bien. Ahora les pongo el codigo de subir y bajar el cursor:
;*******************************************************************************************************************
;*********************************** MEDIDOR DE BATERIAS ******************************************
;*********************************** DC Sentinel ******************************************
;*********************************** CON DISPLAY SS16D80DLGW-E ******************************************
;*********************************** y PIC16F877A ******************************************
;*******************************************************************************************************************
list p=16f877A
include "p16f877A.inc"
errorlevel -302 ; supress "register not in bank0, check page bits" message
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _HS_OSC & _LVP_OFF & _CPD_OFF; & _WRT_ENABLE_ON & _DEBUG_ON
#DEFINE VBAT PORTA, 0 ;Input - Voltaje de Entrada de Baterias
#DEFINE Q1SW PORTA, 1 ;Output - Activacion de Switch de disparo para Resistencia de Descarga
#DEFINE BUZZER PORTA, 2 ;Output - Activacion del Buzzer
#DEFINE BatLev PORTA, 3 ;Input - Deteccion de Nivel de Bateria
#DEFINE DC_OK_NOK PORTA, 4 ;Output - Deteccion de conexion en baterias: No Conexion, Polaridad
#DEFINE DC_OV_PROT PORTA, 5 ;Input - Deteccion de Sobrevoltaje de Baterias
#DEFINE lcd_DAT PORTB ;Output - Datos para el display LCD
#DEFINE lcd_RS PORTC, 0 ;LCD Register Select: Data = 0 / Instruction = 1
#DEFINE lcd_RW PORTC, 1 ;LCD Read/Write Selection
#DEFINE lcd_E PORTC, 2 ;LCD Enable Signal
#DEFINE lcd_DOFF PORTC, 4 ;LCD Display Off Signal DISP OFF=0 DISP ON=1
#DEFINE lcd_RST PORTC, 5 ;LCD Reset Signal ACTIVE LOW
#DEFINE TXsend PORTC, 6 ;Envio de datos por RS232
PDel0 equ 0x26 ;PDel0 a PDel9 variables de retardos
PDel1 equ 0x27
PDel2 equ 0x28
PDel3 equ 0x29
PDel4 equ 0x2A
PDel5 equ 0x2B
PDel6 equ 0x2C
TEMP equ 0x2D
TEMP1 equ 0x2E
TEMP2 equ 0x2F
TEMP3 equ 0x30
J equ 0x31
K equ 0x32
TxtDat equ 0x33
TECLA EQU 0x38
KEY1 EQU 0x39
KEY2 EQU 0x3A
org 0x00 ;Inicio de Programa
goto INICIO
;*****************************************************************************************
;Main program
;*****************************************************************************************
INICIO:
banksel ADCON1 ;Cambia a Bank 1
movlw 0x29 ;PORTA RA0:RA5 = 101001 = 29H
movwf PORTA
movlw 0x00 ;Pone a w = 00000000
movwf PORTB ;Pone a PORTB como salidas
movlw 0x80 ;Pone a w = 10000000
movwf PORTC ;Pone a RC0-RC6 como salidas y RC7-TX como entrada
movlw 0x06 ;Pone a RA0-RA5 como digitales
movwf ADCON1 ;ADFM, A/D Result Format = Left justified
banksel ADCON0 ;Cambia a Bank 0
clrf STATUS
bcf lcd_DOFF
call LCD_TXT_INIT
call ClrDisp
bsf lcd_DOFF
movlw 0x42
movwf K
movlw 0x0A ;Cursor low address setting
call Send_CMD
movf K,W ;Low address start
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
movlw 0x0C ;Write Display Data
call Send_CMD
movlw 0x7E ;->
call Send_DAT
IniMenu call MenuPal
call KEYDETECT
goto IniMenu
;*******************************************************************************
;*************************** DC Sentinel Menu Principal *********************
;*******************************************************************************
;*****************************************************************************
;*************************** 1 - Lect SIN Resistencia ***********************
;*****************************************************************************
MenuPal:
movlw 0x0A ;Cursor low address setting
call Send_CMD
movlw 0x43 ;Low address start
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
movlw 0x0C ;Write Display Data
call Send_CMD
movlw 0x31 ;1
call Send_DAT
;******************************************************************************
;*************************** 2 - Lect CON Resistencia ***********************
;******************************************************************************
movlw 0x0A ;Cursor low address setting
call Send_CMD
movlw 0x63 ;Low address start
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
movlw 0x0C ;Write Display Data
call Send_CMD
movlw 0x32 ;2
call Send_DAT
;*******************************************************************************
;*************************** 3 - Cargar Datos de Mem ************************
;*******************************************************************************
movlw 0x0A ;Cursor low address setting
call Send_CMD
movlw 0x83 ;Low address start
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
movlw 0x0C ;Write Display Data
call Send_CMD
movlw 0x33 ;3
call Send_DAT
;*******************************************************************************
;*************************** 4 - Guardar Datos en Mem **********************
;*******************************************************************************
movlw 0x0A ;Cursor low address setting
call Send_CMD
movlw 0xA3 ;Low address start
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
movlw 0x0C ;Write Display Data
call Send_CMD
movlw 0x34 ;4
call Send_DAT
;*******************************************************************************
;*************************** 5 - Borrar Datos de Mem ************************
;*******************************************************************************
movlw 0x0A ;Cursor low address setting
call Send_CMD
movlw 0xC3 ;Low address start
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
movlw 0x0C ;Write Display Data
call Send_CMD
movlw 0x35 ;5
call Send_DAT
;*******************************************************************************
;*************************** 6 - Enviar Datos a PC ****************************
;*******************************************************************************
movlw 0x0A ;Cursor low address setting
call Send_CMD
movlw 0xE3 ;Low address start
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
movlw 0x0C ;Write Display Data
call Send_CMD
movlw 0x36 ;6
call Send_DAT
return
;*****************************************************************************************************
;********************** SECUENCIA DE DETECCION DE TECLAS EN KEYPAD *********************
;*****************************************************************************************************
KEYDETECT:
banksel ADCON1 ;Cambia a Bank 1
movlw 0xF8 ;Carga w = 11111000
movwf PORTD ;RD0-RD2 como salidas y RD3-RD5 como entradas
banksel ADCON0 ;Cambia a Bank 0
movlw 0x03 ;No de columnas a explorar N+1=3
movwf KEY1
movlw 0xFB ;Se activa con 0 la primera columna w = 11111011
movwf TECLA
KEY_SCAN
movf TECLA, w
movwf PORTD
nop
movf PORTD, w ;Se lee el puerto D y se almacena en KEY2
movwf KEY2
subwf TECLA, w ;Se comparan TECLA y KEY2 => w = TECLA - KEY2
btfss STATUS, Z ;Si w = TECLA - KEY2 = 0, STATUS (Z) = 1, no se activo la tecla y salta
goto KEY_ACT ;Si w = TECLA - KEY2 no es cero, entonces se activo una tecla
bsf STATUS, C
rrf TECLA, F ;Se selecciona la siguiente columna
decfsz KEY1, F ;Se decrementa el No de columnas a explorar. Si es cero salta
goto KEY_SCAN ;El No de columnas no es cero
movlw 0x03 ;No de columnas a explorar
movwf KEY1
movlw 0xFB ;Se activa con 0 la primera columna w = 11111011
movwf TECLA
goto KEY_SCAN
KEY_ACT
call Delay_10ms
call Delay_50ms
movf TECLA, w
movwf PORTD
nop
movf PORTD, w ;Se lee el puerto D y se almacena en KEY2
subwf KEY2, w ;para verificar la tecla activada y evitar rebotes
btfss STATUS, Z ;Si w = PORTD - KEY2 = 0 es la misma tecla activada y salta
goto KEY_SCAN
; movf KEY2,W
; movwf TECLA
call KEY_SEL
return
;***************************************************************************************************
;*************** SUBRUTINAS PARA LA TECLA PRESIONADA ***********************************
;***************************************************************************************************
KEY_SEL:
movlw 0xF6 ;Corresponde a la Tecla UP
xorwf KEY2,W
btfsc STATUS,Z ;Si XOR entre KEY2 y W es igual a cero, no son iguales y salta
call Key_UP
movlw 0xF3 ;Corresponde a la Tecla DOWN
xorwf KEY2,W
btfsc STATUS,Z ;Si XOR entre KEY2 y W dio cero, son iguales
call Key_DN
return
;*******************************************************************************
;*************************** Key_DOWN Activada ****************************
;*******************************************************************************
;3B - 1
;57 - 2
;73 - 3
;8F - 4
;AB - 5
;C7 - 6
Key_DN:
bsf STATUS, C
movlw 0x0A ;Cursor low address setting
call Send_CMD
movf K,W ;Low address start
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
movlw 0x0C ;Write Display Data
call Send_CMD
movlw 0x20
call Send_DAT
movlw 0xC7
xorwf K,W
btfss STATUS,Z ;Si XOR entre TEMP3 y W no dio cero, son iguales y salta
goto K1
movlw 0x1F
movwf K
K1 movlw 0x1C
addwf K,1
movlw 0x0A ;Cursor low address setting
call Send_CMD
movf K,W ;Low address start
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
movlw 0x0C ;Write Display Data
call Send_CMD
movlw 0x7E ;->
call Send_DAT
return
;*******************************************************************************
;*************************** Key_UP Activada ********************************
;*******************************************************************************
;3B - 1
;57 - 2
;73 - 3
;8F - 4
;AB - 5
;C7 - 6
Key_UP:
bsf STATUS, C
movlw 0x0A ;Cursor low address setting
call Send_CMD
movf K,W ;Low address start
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
movlw 0x0C ;Write Display Data
call Send_CMD
movlw 0x20
call Send_DAT
movlw 0x3A
xorwf K,W
btfss STATUS,Z ;Si XOR entre TEMP3 y W no dio cero, son iguales y salta
goto K2
movlw 0xE2
movwf K
goto K3
K2 movlw 0x20
subwf K,1
K3 movlw 0x0A ;Cursor low address setting
call Send_CMD
movf K,W ;Low address start
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
movlw 0x0C ;Write Display Data
call Send_CMD
movlw 0x7E ;->
call Send_DAT
return
;********************************************************************************************************
;***************** SUBRUTINA DE INICIALIZACION DE DISPLAY EN TEXT MODE *******************
;********************************************************************************************************
LCD_TXT_INIT:
movlw 0x00 ;Command code--Mode control
call Send_CMD
movlw 0x30 ;Set 110000
;Display ON, Master Mode, Cursor OFF, Internal CG, Character Mode
call Send_DAT ;Data complete
movlw 0x01 ;Character pitch setting
call Send_CMD
movlw 0x75 ;Set 01110101
;Vp=8, Hp=6 -> 5x7
call Send_DAT ;Data complete
movlw 0x02 ;Character number setting
call Send_CMD
movlw 0x1F ;Hn=160/5=32 Char in one line
;Hn-1=31Dec -> 1FH
call Send_DAT ;Data complete
movlw 0x03 ;Display duty setting
call Send_CMD
movlw 0x4F ;Set Nx=80
;Nx-1=79Dec -> 4FH
call Send_DAT ;Data complete
movlw 0x08 ;Cursor low address setting
call Send_CMD
movlw 0x00 ;Low address start from 00H
call Send_DAT ;Data complete
movlw 0x09 ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
return
;************************ Envia Comando al lcd ***********************
;write instruction sub routine
;RS=0,RW=0,E=high pulse ,D0-D7=code of instruction
;*********************************************************************
Send_CMD:
movwf TEMP ;Registro temporal para guardar dato
call CHK_BUSY ;Checa la linea de Busy
nop
bcf lcd_RW ;Modo Write
bsf lcd_RS ;Modo Instruction Register
bsf lcd_E
nop
movfw TEMP
movwf PORTB ;Envia comando
bcf lcd_E
nop
nop
nop
nop
return
;************************ Envia Datos al lcd ***********************
;write data subroutine.
;RS=1,RW=0,E=high pulse ,D0-D7=data
;**********************************************************
Send_DAT:
movwf TEMP ;Registro temporal para guardar dato
call CHK_BUSY ;Checa la linea de Busy
nop
bcf lcd_RW ;Modo Write
bcf lcd_RS ;Modo Data Register
bsf lcd_E
nop
movfw TEMP
movwf PORTB ;Envia comando
bcf lcd_E
nop
nop
nop
nop
return
;************************** Checa la linea de Busy **********************
;test busy subroutine
;RS=0,RW=1,E=H,D0-D7=status byte
;************************************************************************
CHK_BUSY:
banksel ADCON1 ;Cambia a Bank 1
movlw 0xFF ;Pone a w = 11111111
movwf PORTB ;Pone a PORTB como entradas
banksel ADCON0 ;Cambia a Bank 0
bcf lcd_RS
bsf lcd_RW
bsf lcd_E
BUSY_1 btfsc PORTB,7 ;Si D7=1 indica que Busy esta activo
goto BUSY_1
bcf lcd_E
banksel ADCON1 ;Cambia a Bank 1
movlw 0x00 ;Pone a w = 00000000
movwf PORTB ;Pone a PORTB como salidas
banksel ADCON0 ;Cambia a Bank 0
return
;******************************************************************************
;*********************** Rutina para limpiar display ************************
;******************************************************************************
ClrDisp:
movlw 0x0A ;Cursor low address setting
call Send_CMD
movlw 0x00 ;Low address start from 00H
call Send_DAT ;Data complete
movlw 0x0B ;Cursor high address setting
call Send_CMD
movlw 0x00 ;High address start from 00H
call Send_DAT ;Data complete
movlw 0xFF
movwf TEMP1
ClrTxt1 movlw 0x0C ;Write Display Data
call Send_CMD
movlw 0x20
call Send_DAT
decfsz TEMP1, F
goto ClrTxt1
movlw 0x3C
movwf TEMP1
ClrTxt2 movlw 0x0C ;Write Display Data
call Send_CMD
movlw 0x20
call Send_DAT
decfsz TEMP1, F
goto ClrTxt2
return
;*************************************************************************
;************************ Delay subroutines **************************
;*************************************************************************
Delay_10ms:
movlw .21
movwf PDel0
PLoop0 movlw .237
movwf PDel1
PLoop1 clrwdt
decfsz PDel1, 1
goto PLoop1
decfsz PDel0, 1
goto PLoop0
goto PDelL0
PDelL0 clrwdt
return
;***********************************************************************
Delay_50ms:
movlw .110
movwf PDel2
PLoop2 movlw .181
movwf PDel3
PLoop3 clrwdt
clrwdt
decfsz PDel3, 1
goto PLoop3
decfsz PDel2, 1
goto PLoop2
goto PDelL1
PDelL1 goto PDelL2
PDelL2 clrwdt
return
;***********************************************************************
Delay_500ms:
movlw .14
movwf PDel4
PLoop4 movlw .72
movwf PDel5
PLoop5 movlw .247
movwf PDel6
PLoop6 clrwdt
decfsz PDel6, 1
goto PLoop6
decfsz PDel5, 1
goto PLoop5
decfsz PDel4, 1
goto PLoop4
goto PDelL3
PDelL3 clrwdt
return
;********************************************************************************************************************************
end
De antemano muchas gracias por el apoyo y soporte que me puedan brindar