Desde hace tiempo estaba buscando información sobre IRD (InfRareD) para el 16F84. Vi el código. Estaría bueno recopilar información de todo tipo para este proyecto hasta esquemas y si es posible pasarlo hasta en Proteus.
Por ahora he corregido para que el código sea más cómodo para leer en azul. Más adelante haré más cosas.
EDITO:
Mejor colocar los archivos *.ASM y RETARDOS.INC en la misca carpeta y ejecutar el código. Es sistemas de bloques o modular, las cosas se simplifica mejor.
Librería RETARDOS.INC
Por ahora he corregido para que el código sea más cómodo para leer en azul. Más adelante haré más cosas.
Código:
list p=16F84A ; list directive to define processor
#include <p16F84A.inc> ; processor specific variable definitions
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
DATA_IN EQU 0
ERROR_PIN EQU 1
CBLOCK 0x0C
ADDRESS
DATO
CONTADOR
PDel0
PDel1
PDel2
ENDC
;*******Inicialización del microcontrolador y variables***********************************************
bsf STATUS,RP0 ;Pasar al banco 1
movlw B'00000001'
movwf TRISA ;1-7 = salida, 0 = entrada
movlw B'00000000'
movwf TRISB ;0-7 salida
bcf STATUS,RP0 ;Volver al banco 0
clrf PORTA ;Limpiar puertos
clrf PORTB
;*******Fin inicialización del microcontrolador*******************************************************
MAIN
call LEER
movf ADDRESS,W
movwf PORTB
call DEMORA ;demora de un segundo para alcanzar a ver el primer dato
movf DATO,W ;que salió por PORTB, subrutina omitida ahora.
movwf PORTB
call DEMORA ;demora de un segundo para alcanzar a ver el primer dato
goto MAIN
;--------
FIN ;Es para que aqui termine el programa sin que se borre PORTB.
goto FIN
;--------
LEER
btfsc PORTA, DATA_IN ;Esperar a que entre el primer dato para comenzar
goto LEER
call DELAY14 ;Retraso de 1/4 de bit, para estar bien "encima" del bit.
;Una vez comenzada la lectura, comprobar el comienzo de la cadena
btfsc PORTA,DATA_IN ;Probar si primer start bit es 1 (aunque ya es así...)
goto BAD_DATA ;Ir a BAD_DATA si el primer start bit resulta ser cero
call DELAY12 ;Esparar por medio bit
btfss PORTA,DATA_IN ;Probar si entre 1er y 2do Start bit hay un 0
goto BAD_DATA ;Ir a BAD_DATA si el segundo start bit resulta ser cero
call DELAY12 ;Esparar por medio bit
btfsc PORTA,DATA_IN ;Probar si segundo start bit es 1
goto BAD_DATA ;Ir a BAD_DATA si el segundo start bit resulta ser cero. HASTA AQUI, START BIT
call DELAY1 ;Saltarse el Toggle (por sus propiedades complicadas)
call DELAY1
bcf PORTA,ERROR_PIN;Apagar pin de error si todo esta bien, y en caso de que esté activo
;Si esta malo el comienzo de la cadena, será Bad_Data
;Ahora se comienza con la decodificación de datos útiles.
clrf ADDRESS ;Borrar ADDRESS y DATO para empezar con variables limpias
clrf DATO
movlw D'5' ;Cargar contador para leer 5 bits (ADDRESS)
movwf CONTADOR
LEER_ADDRESS
rlf ADDRESS,F
btfss PORTA,DATA_IN ;Leer Most Significant Bit ADDRESS BITS
bsf ADDRESS,0 ;Poner en 1 la variable ADDRESS,bit_corespondiente si fuese necesario
call DELAY1 ;Esperar un bit (para llegar al siguiente)
decfsz CONTADOR,F ;Decrementar CONTADOR en 1 y saltar próximo paso si es 0
goto LEER_ADDRESS ;Volver para leer el siguiente bit
;Terminada la lectura de esta cadena de datos
;Seguir con lo que sigue
call DELAY1 ;Esperar un bit para empezar a leer el comando (próxima función)
movlw D'6' ;Recargar contador para leer 6 bits (comando)
movwf CONTADOR
LEER_DATO
rlf DATO,F
btfss PORTA, DATA_IN ;Leer MostSignificantBit DATA BIT
bsf DATO,0 ;Poner en 1 la variable DATO,bit_corespondiente si fuese necesario
call DELAY1 ;Esperar un bit para leer el siguiente
decfsz CONTADOR,F ;Decrementar CONTADOR en 1 y saltar próximo paso si es 0
goto LEER_DATO ;Volver para leer el siguiente bit
;Terminada la lectura de esta cadena de datos
;Seguir con lo que sigue
rrf DATO,F ;Para que el Bit 0 esté en la pata PORTB,0
rrf ADDRESS ;Para que el Bit 0 esté en la pata PORTB,0
return ;La lectura de datos está terminada, ahora volver.
BAD_DATA
bsf PORTA, ERROR_PIN;Avisar que hay error
goto MAIN ;Volver al inicio, o salir de LEER
DELAY1
call DELAY14 ;Llamar 4 veces al DELAY de 1/4 de Bit para que sea 1 Bit
call DELAY14 ;Todos los DELAYs son para 4MHz, y DELAY1 = 1,778 ms
call DELAY14
call DELAY14
return
DELAY12
call DELAY14 ;Llamar 2 veces al DELAY de 1/4 de Bit para que sea 1/2 de Bit
call DELAY14
return
;446 uS (la cuarta parte del tiempo de un bit).
DELAY14 movlw .110 ; 1 set numero de repeticion
movwf PDel0 ; 1 |
PLoop0 clrwdt ; 1 clear watchdog
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ?
goto PLoop0 ; 2 no, loop
return ; 2+2 Fin.
DEMORA movlw .14 ; 1 set numero de repeticion (C)
movwf PDel0 ; 1 |
PLop0 movlw .72 ; 1 set numero de repeticion (B)
movwf PDel1 ; 1 |
PLop1 movlw .247 ; 1 set numero de repeticion (A)
movwf PDel2 ; 1 |
PLop2 clrwdt ; 1 clear watchdog
decfsz PDel2, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLop2 ; 2 no, loop
decfsz PDel1, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLop1 ; 2 no, loop
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ? (C)
goto PLop0 ; 2 no, loop
PDelL1 goto PDelL2 ; 2 ciclos delay
PDelL2 clrwdt ; 1 ciclo delay
return ; 2+2 Fin.
END
Mejor colocar los archivos *.ASM y RETARDOS.INC en la misca carpeta y ejecutar el código. Es sistemas de bloques o modular, las cosas se simplifica mejor.
Código:
list p=16F84A ; list directive to define processor
#include <p16F84A.inc> ; processor specific variable definitions
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
DATA_IN EQU 0
ERROR_PIN EQU 1
CBLOCK 0x0C
ADDRESS
DATO
CONTADOR
PDel0
PDel1
PDel2
ENDC
;*******Inicialización del microcontrolador y variables***********************************************
bsf STATUS,RP0 ;Pasar al banco 1
movlw B'00000001'
movwf TRISA ;1-7 = salida, 0 = entrada
movlw B'00000000'
movwf TRISB ;0-7 salida
bcf STATUS,RP0 ;Volver al banco 0
clrf PORTA ;Limpiar puertos
clrf PORTB
;*******Fin inicialización del microcontrolador*******************************************************
MAIN
call LEER
movf ADDRESS,W
movwf PORTB
call DEMORA ;demora de un segundo para alcanzar a ver el primer dato
movf DATO,W ;que salió por PORTB, subrutina omitida ahora.
movwf PORTB
call DEMORA ;demora de un segundo para alcanzar a ver el primer dato
goto MAIN
;--------
FIN ;Es para que aqui termine el programa sin que se borre PORTB.
goto FIN
;--------
LEER
btfsc PORTA, DATA_IN ;Esperar a que entre el primer dato para comenzar
goto LEER
call DELAY14 ;Retraso de 1/4 de bit, para estar bien "encima" del bit.
;Una vez comenzada la lectura, comprobar el comienzo de la cadena
btfsc PORTA,DATA_IN ;Probar si primer start bit es 1 (aunque ya es así...)
goto BAD_DATA ;Ir a BAD_DATA si el primer start bit resulta ser cero
call DELAY12 ;Esparar por medio bit
btfss PORTA,DATA_IN ;Probar si entre 1er y 2do Start bit hay un 0
goto BAD_DATA ;Ir a BAD_DATA si el segundo start bit resulta ser cero
call DELAY12 ;Esparar por medio bit
btfsc PORTA,DATA_IN ;Probar si segundo start bit es 1
goto BAD_DATA ;Ir a BAD_DATA si el segundo start bit resulta ser cero. HASTA AQUI, START BIT
call DELAY1 ;Saltarse el Toggle (por sus propiedades complicadas)
call DELAY1
bcf PORTA,ERROR_PIN;Apagar pin de error si todo esta bien, y en caso de que esté activo
;Si esta malo el comienzo de la cadena, será Bad_Data
;Ahora se comienza con la decodificación de datos útiles.
clrf ADDRESS ;Borrar ADDRESS y DATO para empezar con variables limpias
clrf DATO
movlw D'5' ;Cargar contador para leer 5 bits (ADDRESS)
movwf CONTADOR
LEER_ADDRESS
rlf ADDRESS,F
btfss PORTA,DATA_IN ;Leer Most Significant Bit ADDRESS BITS
bsf ADDRESS,0 ;Poner en 1 la variable ADDRESS,bit_corespondiente si fuese necesario
call DELAY1 ;Esperar un bit (para llegar al siguiente)
decfsz CONTADOR,F ;Decrementar CONTADOR en 1 y saltar próximo paso si es 0
goto LEER_ADDRESS ;Volver para leer el siguiente bit
;Terminada la lectura de esta cadena de datos
;Seguir con lo que sigue
call DELAY1 ;Esperar un bit para empezar a leer el comando (próxima función)
movlw D'6' ;Recargar contador para leer 6 bits (comando)
movwf CONTADOR
LEER_DATO
rlf DATO,F
btfss PORTA, DATA_IN ;Leer MostSignificantBit DATA BIT
bsf DATO,0 ;Poner en 1 la variable DATO,bit_corespondiente si fuese necesario
call DELAY1 ;Esperar un bit para leer el siguiente
decfsz CONTADOR,F ;Decrementar CONTADOR en 1 y saltar próximo paso si es 0
goto LEER_DATO ;Volver para leer el siguiente bit
;Terminada la lectura de esta cadena de datos
;Seguir con lo que sigue
rrf DATO,F ;Para que el Bit 0 esté en la pata PORTB,0
rrf ADDRESS ;Para que el Bit 0 esté en la pata PORTB,0
return ;La lectura de datos está terminada, ahora volver.
BAD_DATA
bsf PORTA, ERROR_PIN;Avisar que hay error
goto MAIN ;Volver al inicio, o salir de LEER
INCLUDE <RETARDOS.INC>
END
Código:
DELAY1
call DELAY14 ;Llamar 4 veces al DELAY de 1/4 de Bit para que sea 1 Bit
call DELAY14 ;Todos los DELAYs son para 4MHz, y DELAY1 = 1,778 ms
call DELAY14
call DELAY14
return
DELAY12
call DELAY14 ;Llamar 2 veces al DELAY de 1/4 de Bit para que sea 1/2 de Bit
call DELAY14
return
;446 uS (la cuarta parte del tiempo de un bit).
DELAY14 movlw .110 ; 1 set numero de repeticion
movwf PDel0 ; 1 |
PLoop0 clrwdt ; 1 clear watchdog
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ?
goto PLoop0 ; 2 no, loop
return ; 2+2 Fin.
DEMORA movlw .14 ; 1 set numero de repeticion (C)
movwf PDel0 ; 1 |
PLop0 movlw .72 ; 1 set numero de repeticion (B)
movwf PDel1 ; 1 |
PLop1 movlw .247 ; 1 set numero de repeticion (A)
movwf PDel2 ; 1 |
PLop2 clrwdt ; 1 clear watchdog
decfsz PDel2, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLop2 ; 2 no, loop
decfsz PDel1, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLop1 ; 2 no, loop
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ? (C)
goto PLop0 ; 2 no, loop
PDelL1 goto PDelL2 ; 2 ciclos delay
PDelL2 clrwdt ; 1 ciclo delay
return ; 2+2 Fin.
Última edición por un moderador: