Muy buenas. Mas que el teclado lo que no funciona es el salto a la interrupcion. No se que error cometo, pero he probado muchas configuraciones y cosas raras y tampoco funciona. El tema es que lo dejo en sleep y cuando salte la interrupcion solamente me muestre algo en pantalla, porque con el teclado no hay manera y sin embargo el LCD funciona bien, pero ni con esas, la interrupcion por actividad en el puerto B no furrula, y la conexion al teclado es bastante sencilla, no se si cambiando a otras configuraciones que he visto con las resistencias pull up fuera del micro puede que funcione...
Si alguien ve algun fallo por favor que lo diga.
Gracias y un saludo.
processor 16F876A
LIST P=16F876A ;Se indica el modo de procesador
INCLUDE <P16f876A.inc> ;se incluye la definicion de los
;registros internos
__config 3D31
PDel0 EQU 0x21
PDel1 EQU 0x22
PDel2 EQU 0x23
BUFFER EQU 0x24
INNER EQU 0x25 ;delay variable mS
OUTER EQU 0x26 ;delay variable mS
Digito EQU 0x27
ASCII_H EQU 0x31
ASCII_M EQU 0x32
ASCII_L EQU 0x33
HEXADECIMAL EQU 0x34
;*************** PARA EL TECLADO ***************************
;
;*********************************************************
;----------------------------------------------------------------------------
org 0x00 ;vector de inicio
goto INICIO
org 0x05 ;despues del vector de interrupcion
goto ServicioInterrupcion
;<<<<<<----------------- INICIO PROGRAMA PRINCIPAL ------------------->>>>>>>
;----------------------------------------------------------------------------
INICIO
bcf STATUS,RP0 ;banco 0 _-_-_-_-_-_-_-_-_-_-_-_-_-_-
bcf STATUS,RP1
clrf PORTA ;Limpia latches puerto
clrf PORTB ;Limpia latches puerto
clrf PORTC ;Limpia latches puerto
bsf STATUS,RP0 ;banco 1 _-_-_-_-_-_-_-_-_-_-_-_-_-_-
movlw 0x06 ;Puerto A en modo digital
movwf ADCON1
clrf TRISA ;PortA como entrada
clrf TRISB ;PortB como salida
clrf TRISC ;PortC como salida
bcf STATUS,RP0 ;banco 0 _-_-_-_-_-_-_-_-_-_-_-_-_-_-
clrf PORTA ;Limpia latches puerto
clrf PORTB ;Limpia latches puerto
clrf PORTC ;Limpia latches puerto
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
call LCD_INI
movlw b'00000001' ;Borrar LCD y Home
call LCD_REG
movlw b'00000110' ;
call LCD_REG
movlw b'00001100' ;LCD On, cursor Off,Parpadeo Off
movlw 0x80 ;Direccion caracter
call LCD_REG
movlw '0'
call LCD_DATOS ;Visualiza caracter
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
;###############################################################################
; PROBANDO TECLADO
call Teclado_Inicializa
movlw b'11001000' ; Habilita la interrupción RBI, perifericos y la general.
movwf INTCON
sleep
; movlw b'00000000' ; deshabilita las interrupciónes del teclado
; movwf INTCON
aux2 call PDelay ;retardo de 2 segundos
goto aux2
;###########################################################################
;###########################################################################
del_1ms movlw d'199' ;delay 1mS
movwf INNER
in_lp nop
nop
decfsz INNER,F
goto in_lp
return
delay movwf OUTER ;vueltas de 1mS
out_lp call del_1ms
decfsz OUTER,F
goto out_lp
return
;()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()
;()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()
;()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()
Hex_Ascii ;cargar en W el dato hex.
;
;MOVLW .254
MOVWF HEXADECIMAL
clrf ASCII_H ;Para BCD D'0'
clrf ASCII_M ;Para BCD D'0'
clrf ASCII_L ;Para BCD D'0'
;
Centenas
;
movlw D'100' ;D'100' --> W
subwf HEXADECIMAL,W ;HEXADECIMAL - D'100' --> W
btfss STATUS,C ;¿ HEXADECIMAL es menor que D'100' ?
goto Decenas ;Si
movwf HEXADECIMAL ;Salva el resto
incf ASCII_H,F ;Incrementa el contador de centenas BCD
goto Centenas ;Vuelve por otros D'100'
;
Decenas
;
movlw D'10' ;D'10' --> W
subwf HEXADECIMAL,W ;HEXADECIMAL - D'10' --> W
btfss STATUS,C ;¿ HEXADECIMAL es menor que D'10' ?
goto Unidades ;Si
movwf HEXADECIMAL ;Salva el resto
incf ASCII_M,F ;Incrementa el contador de decenas BCD
goto Decenas ;Vuelve por otros D'10'
;
Unidades
;
movf HEXADECIMAL,W ;El resto pertenece
movwf ASCII_L ;a las unidades BCD
clrf HEXADECIMAL ;Pone a cero el registro HEXADECIMAL
;
Bcd_A_Ascii
;
movlw H'30' ;H'30' --> W
iorwf ASCII_L,F ;Convierte de BCD a ASCII
iorwf ASCII_M,F ;Convierte de BCD a ASCII
;
movf ASCII_H,F ;ASCII_H --> F
btfsc STATUS,Z ;? ASCII_H es D'00' ?
goto Espacio ;Si
movlw H'30' ;H'30' --> W
iorwf ASCII_H,F ;Convierte de BCD a ASCII
return ;Retorna
;
Espacio
;
movlw '0' ;A' ' --> W
movwf ASCII_H ;A' ' --> ASCII_H
;movwf ASCII_M ;A' ' --> ASCII_H
;movwf ASCII_L ;A' ' --> ASCII_H
return ;Retorna
;()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()
;()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()
;()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()
;###########################################################################
;===========================================================================
;--------------------- RUTINAS LCD 2x16 ------------------------------------
;===========================================================================
;###########################################################################
LCD_E BSF PORTA,2 ;Activa señal E
NOP
NOP
NOP ;Espera 1uS
BCF PORTA,2 ;Desactiva señal E
RETURN
LCD_BUSY BSF PORTA,1 ;Pone el LCD en modo lectura
BSF STATUS,RP0 ;Selecciona el Banco 1
MOVLW 0xFF
MOVWF TRISB ;Puerta B act£a de entrada
BCF STATUS,RP0 ;Selecciona el Banco 0
BSF PORTA,2 ;Activa el LCD (Señal E)
NOP
L_BUSY BTFSC PORTB,7 ;Chequea el bit BUSY
GOTO L_BUSY ;Est a "1" (Ocupado)
BCF PORTA,2 ;Desactiva el LCD (Se¤al E)
BSF STATUS,RP0 ;Selecciona el Banco 1
CLRF TRISB ;Puerta B actua como salida
BCF STATUS,RP0 ;Selecciona el Banco 0
BCF PORTA,1 ;Pone el LCD en modo escritura
RETURN
LCD_REG BCF PORTA,0 ;Desactiva RS (Modo instruccion)
MOVWF PORTB ;Saca el codigo de instruccion
CALL LCD_BUSY ;Espera a que se libere el LCD
GOTO LCD_E ;Genera pulso en señal E
LCD_DATOS BCF PORTA,0 ;Desactiva RS (Modo instrucci¢n)
MOVWF PORTB ;Valor ASCII a sacar por PORTB
CALL LCD_BUSY ;Espera a que se libere el LCD
BSF PORTA,0 ;Activa RS (Modo dato)
GOTO LCD_E ;Genera pulso en señal E
LCD_INI MOVLW b'00111000'
CALL LCD_REG ;Codigo de instruccion
CALL DELAY_5MS ;Temporiza 5 mS.
MOVLW b'00111000'
CALL LCD_REG ;Codigo de instruccion
CALL DELAY_5MS ;Temporiza 5 mS.
MOVLW b'00111000'
CALL LCD_REG ;Codigo de instruccion
CALL DELAY_5MS ;Temporiza 5 mS.
RETURN
;****************************************************************************
;DELAY_5MS genera una temporizacion de 5mS necesario para la secuencia de
;inicio del LCD
DELAY_5MS movlw .6 ; 1 set number of repetitions (
movwf PDel0 ; 1 |
PLoop1 movlw .207 ; 1 set number of repetitions (A)
movwf PDel1 ; 1 |
PLoop2 nop ; 1 clear watchdog
decfsz PDel1, 1 ; 1 + (1) is the time over? (A)
goto PLoop2 ; 2 no, loop
decfsz PDel0, 1 ; 1 + (1) is the time over? (
goto PLoop1 ; 2 no, loop
PDelL1 goto PDelL2 ; 2 cycles delay
PDelL2 nop ; 1 cycle delay
return ; 2+2 Done
;###########################################################################
;-------------------------------------------------------------
; Description: Waits 2000000 cycles 2 segundos
;-------------------------------------------------------------
PDelay movlw .167 ; 1 set number of repetitions (C)
movwf PDel0 ; 1 |
PLoop0s movlw .41 ; 1 set number of repetitions (
movwf PDel1 ; 1 |
PLoop1s movlw .72 ; 1 set number of repetitions (A)
movwf PDel2 ; 1 |
PLoop2s nop ; 1 clear watchdog
decfsz PDel2, 1 ; 1 + (1) is the time over? (A)
goto PLoop2s ; 2 no, loop
decfsz PDel1, 1 ; 1 + (1) is the time over? (
goto PLoop1s ; 2 no, loop
decfsz PDel0, 1 ; 1 + (1) is the time over? (C)
goto PLoop0s ; 2 no, loop
PDelL1s goto PDelL2s ; 2 cycles delay
PDelL2s nop ; 1 cycle delay
return ; 2+2 Done
;-------------------------------------------------------------
ServicioInterrupcion
call LCD_INI
movlw b'00000001' ;Borrar LCD y Home
call LCD_REG
movlw b'00000110' ;
call LCD_REG
movlw b'00001100' ;LCD On, cursor Off,Parpadeo Off
movlw 0x81 ;Direccion caracter
call LCD_REG
movlw '0'
call LCD_DATOS ;Visualiza caracter
retfie
END