__config _CP_OFF & _DEBUG_OFF & _PWRTE_ON & _CPD_OFF & _LVP_OFF & _WDT_OFF & _XT_OSC
list p=16f877A
include "P16F877A.inc"
CBLOCK 0xA0
HTIM01 ;Primera variable
HTIM02
HTIM03
HTIM04
HTIM05
HTIM06
HTIM07
HTIM08
HTIM09
HTIM10
HTIM11
HTIM12
HTIM13
HTIM14
HTIM15
HTIM16
HTIM17
HTIM18
HTIM19
HTIM20
HTIM21
HTIM22
HTIM23
HTIM24
HTIM25
HTIM26
HTIM27
HTIM28
HTIM29
HTIM30
HTIM31
HTIM32
HTIM33
HTIM34
HTIM35
HTIM36
HTIM37
HTIM38
HTIM39
HTIM40
HTIM41
HTIM42
HTIM43
HTIM44
HTIM45
HTIM46
HTIM47
HTIM48
HTIM49
HTIM50 ;Ultima variable
ENDC
CBLOCK 0x20
LTIM01 ;Primera variable
LTIM02
LTIM03
LTIM04
LTIM05
LTIM06
LTIM07
LTIM08
LTIM09
LTIM10
LTIM11
LTIM12
LTIM13
LTIM14
LTIM15
LTIM16
LTIM17
LTIM18
LTIM19
LTIM20
LTIM21
LTIM22
LTIM23
LTIM24
LTIM25
LTIM26
LTIM27
LTIM28
LTIM29
LTIM30
LTIM31
LTIM32
LTIM33
LTIM34
LTIM35
LTIM36
LTIM37
LTIM38
LTIM39
LTIM40
LTIM41
LTIM42
LTIM43
LTIM44
LTIM45
LTIM46
LTIM47
LTIM48
LTIM49
LTIM50 ;Ultima variable
REG_SAVEL ;Sabremos en que variable guardaremos el tiempo LOW
REG_SAVEH ;Sabremos en que variable guardaremos el tiempo HIGH
TIEMPO ;La usaremos para no alterar mucho el tiempo de la onda cuadrada
R_ContA
R_ContB
ENDC
#DEFINE IR PORTA,3 ;Puerto del IR
#DEFINE BANCO0 bcf STATUS,RP0
#DEFINE BANCO1 bsf STATUS,RP0
#DEFINE PLED bsf PORTB,6
#DEFINE BOTON PORTA,2
ORG 0x01
nop
nop
goto INICIO
ORG 0x04
goto Serv_de_Interr ;Vector de interrupción
;****************El IR
INICIO
; clrf T2CON ;Detiene el TImer2, con un Prescaler = 1:1, Postscaler=1:1 **
; clrf TMR2 ;Limpia el registro Timer2 **
; clrf INTCON ;Desactiva interrupciones **
; bsf STATUS,RP0 ;Banco 1 **
; clrf PIE1 ;Desactiva las interrupciones perifericas **
; bcf STATUS,RP0 ;Banco 0 **
; clrf PIR1 ;Limpia las banderas perifericas de interrupcion **
; movlw 0x72 ;PostScaler = 1:15, Presccaler = 1:16 **
; movwf T2CON ;Timer2 esta apagado **
; bsf T2CON,TMR2ON ;Timer2 comienza a incrementar **
BANCO1 ;Seleccionamos el banco 1
movlw 0x06 ;Asignamos al PORTA
movwf ADCON1 ;como digital
clrf TRISB ;Marcamos el PORTB como salida
movlw 0xF0 ;Marcamos el PORTC para teclado
movwf TRISC ;El nibble alto entrada y otro salida
movlw 0x3F ;Marcamos PORTA como entrada
movwf TRISA
movlw 0x08 ;Desahabilitamos el preescaler del TMR0
movwf OPTION_REG ;asignandoselo al WatchDog
BANCO0 ;Cambiamos al banco 0
clrf PORTB ;Limpiamos el PORTB
bsf PORTB,0
call LIMPIARTIEMPOS ;Limpiamos los tiempos
movlw 0x1F ;Primer registro de tiempo bajo
movwf REG_SAVEL ;El primero en que guardara, posteriormente se incrementara tiempo bajo
movlw 0x9F ;Primer registro de tiempo alto
movwf REG_SAVEH ;El primero en que guardara, posteriormente se incrementara tiempo alto
SEÑAL
bsf PORTB,0
btfsc IR ;Esperamos al que se reciba una señal, el IR trabaja con logica negativa
goto SEÑAL ;Sino ha recibidO esperamos nuevamente
clrf TMR0 ;Limpiamos el timer 0
goto ACTIVARTIMER ;Empezamos a guardar la señal
ACTIVARTIMER
movlw 0xA0 ;Activamos las interrupciones
movwf INTCON ;en especifico la interrupcion del TMR0
GUARDAR
call CAMBIAR_VARIABLE ;Siguiente instruccion de tiempo
CAMBIO1
btfss IR ;Esperamos a que cambie de señal
goto CAMBIO1 ;Avanzara hasta que cambie a 1
call GUARDAR_TIEMPO ;Guardamos el tiempo en el registro actual
call CAMBIAR_VARIABLE ;Siguiente instruccion de tiempo
CAMBIO2
movf REG_SAVEH,W
BANCO1
movwf FSR
btfsc INDF,7
goto SEÑAL_LISTA
BANCO0
btfsc IR ;Esperamos a que cambie de señal
goto CAMBIO2 ;Avanzara hasta que cambie a 0
call GUARDAR_TIEMPO ;Guardamos el tiempo en el registro actual
goto GUARDAR ;Repetimos el proceso
;******************************************************
SEÑAL_LISTA
BANCO0
clrf INTCON ;Desactivamos interrupciones
;Todo lo demas que se tenga que hacer**************
PLED
P_BOTON
btfss BOTON
goto P_BOTON
call Retardo_20ms
btfss BOTON
goto P_BOTON
REPRODUCIR_SEÑAL
movlw 0x1F
movwf REG_SAVEL
movlw 0x9F
movwf REG_SAVEH
movlw 0x00
movwf T1CON
call CAMBIAR_VARIABLE
bsf PORTB,3
call PONERTMR1
bcf PIR1,TMR1IF
bsf T1CON,TMR1ON
EMPIEREPRO
call CAMBIAR_VARIABLE
ESPERATER
btfss PIR1,TMR1IF
goto ESPERATER
bcf PORTB,3
bcf T1CON,TMR1ON
call PONERTMR1
bsf T1CON,TMR1ON
bcf PIR1,TMR1IF
call CAMBIAR_VARIABLE
ESPERATER2
btfss PIR1,TMR1IF
goto ESPERATER2
bsf PORTB,3
bcf T1CON,TMR1ON
call PONERTMR1
bsf T1CON,TMR1ON
bcf PIR1,TMR1IF
movf INDF,F
btfss STATUS,Z
goto EMPIEREPRO
movf REG_SAVEL,W
movwf FSR
movf INDF,F
btfss STATUS,Z
goto EMPIEREPRO
bcf PORTB,3
goto P_BOTON
;********************SUB RUTINAS********************
GUARDAR_TIEMPO
clrf INTCON ;Desactivamos interrupciones
movf TMR0,W ;Guardamos el tiempo en una variable
movwf TIEMPO ;temporalmente
movlw 0x06 ;Inicializamos el timer con el tiempo
movwf TMR0 ;6microS, debido a El tiempo de las instrucciones
movf REG_SAVEL,W ;Ubicamos el lugar en donde
movwf FSR ;guardaremos el tiempo bajo
movf TIEMPO,W
movwf INDF ;correspondiente
movlw 0xA0 ;Activamos las interrupciones
movwf INTCON ;en especifico la interrupcion del TMR0
return
CAMBIAR_VARIABLE
incf REG_SAVEL,F ;Escoge el siguiente registro BAJO
incf REG_SAVEH,F ;Escoge el siguiente registro ALTO
return
PONERTMR1
movf REG_SAVEL,W
movwf FSR
movf INDF,W
movwf TMR1L
movf REG_SAVEH,W
BANCO1
movwf FSR
movf INDF,W
BANCO0
movwf TMR1H
comf TMR1L,F
comf TMR1H,F
bcf STATUS,C
movlw 0x16
addwf TMR1L,F
btfsc STATUS,C
incf TMR1H,F
return
Retardo_20ms ; La llamada "call" aporta 2 ciclos máquina.
movlw d'20' ; Aporta 1 ciclo máquina. Este es el valor de "M".
movwf R_ContB ; Aporta 1 ciclo máquina.
R1ms_BucleExterno
movlw d'249' ; Aporta Mx1 ciclos máquina. Este es el valor de "K".
movwf R_ContA ; Aporta Mx1 ciclos máquina.
R1ms_BucleInterno
nop ; Aporta KxMx1 ciclos máquina.
decfsz R_ContA,F ; (K-1)xMx1 cm (cuando no salta) + Mx2 cm (al saltar).
goto R1ms_BucleInterno ; Aporta (K-1)xMx2 ciclos máquina.
decfsz R_ContB,F ; (M-1)x1 cm (cuando no salta) + 2 cm (al saltar).
goto R1ms_BucleExterno ; Aporta (M-1)x2 ciclos máquina.
return
;***************************Interrupciones********************************
Serv_de_Interr
; btfsc PIE1,TMR1IE ;No utilizo la F, por que puede que haya dos interrupciones a la vez
; goto TIMER1_INTER ;se sabe que no es posible, sin embargo cuando se hace una interrupcion
btfsc INTCON,TMR0IF ;la otra bandera podria ponerse a 1 y no me haria la interupciion que
goto TIMER_INTER ;yo quiero.
retfie
TIMER_INTER
btfsc STATUS,RP0
goto P_BANCO1
movf REG_SAVEH,W
BANCO1
movwf FSR
incf INDF,F
BANCO0
bcf INTCON,TMR0IF
retfie
P_BANCO1
BANCO0
movf REG_SAVEH,W
BANCO1
movwf FSR
incf INDF,F
bcf INTCON,TMR0IF
retfie
LIMPIARTIEMPOS ;Limpiamos todas la variables de tiempo**************
;*****************************************************************************************Hay que modificarlo por el FSR
clrf LTIM01
clrf LTIM02
clrf LTIM03
clrf LTIM04
clrf LTIM05
clrf LTIM06
clrf LTIM07
clrf LTIM08
clrf LTIM09
clrf LTIM10
clrf LTIM11
clrf LTIM12
clrf LTIM13
clrf LTIM14
clrf LTIM15
clrf LTIM16
clrf LTIM17
clrf LTIM18
clrf LTIM19
clrf LTIM20
clrf LTIM21
clrf LTIM22
clrf LTIM23
clrf LTIM24
clrf LTIM25
clrf LTIM26
clrf LTIM27
clrf LTIM28
clrf LTIM29
clrf LTIM30
clrf LTIM31
clrf LTIM32
clrf LTIM33
clrf LTIM34
clrf LTIM35
clrf LTIM36
clrf LTIM37
clrf LTIM38
clrf LTIM39
clrf LTIM40
clrf LTIM41
clrf LTIM42
clrf LTIM43
clrf LTIM44
clrf LTIM45
clrf LTIM46
clrf LTIM47
clrf LTIM48
clrf LTIM49
clrf LTIM50
BANCO1
clrf HTIM01
clrf HTIM02
clrf HTIM03
clrf HTIM04
clrf HTIM05
clrf HTIM06
clrf HTIM07
clrf HTIM08
clrf HTIM09
clrf HTIM10
clrf HTIM11
clrf HTIM12
clrf HTIM13
clrf HTIM14
clrf HTIM15
clrf HTIM16
clrf HTIM17
clrf HTIM18
clrf HTIM19
clrf HTIM20
clrf HTIM21
clrf HTIM22
clrf HTIM23
clrf HTIM24
clrf HTIM25
clrf HTIM26
clrf HTIM27
clrf HTIM28
clrf HTIM29
clrf HTIM30
clrf HTIM31
clrf HTIM32
clrf HTIM33
clrf HTIM34
clrf HTIM35
clrf HTIM36
clrf HTIM37
clrf HTIM38
clrf HTIM39
clrf HTIM40
clrf HTIM41
clrf HTIM42
clrf HTIM43
clrf HTIM44
clrf HTIM45
clrf HTIM46
clrf HTIM47
clrf HTIM48
clrf HTIM49
clrf HTIM50
BANCO0
return