Protocolo RC5 IR con PIC, ahora Funciona

#21
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.

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
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.

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
Librería RETARDOS.INC
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:
#22
disculpen pero quisiera saber si el comando:
rlf es igual a RLCF y
rrf es igual a RRCF

pues en el compilador me aparecen como error.
 
#25
Yo y mis dudas al querer pasar el codigo para el pic 18f452 me aparece ciertos errores:

Error[113] : Symbol not previously defined (RP0)
Error[113] : Symbol not previously defined (_CP_OFF)
Error[113] : Symbol not previously defined (_WDT_OFF)
Error[113] : Symbol not previously defined (_PWRTE_ON)
Error[113] : Symbol not previously defined (_XT_OSC)
y si intento con el pic :
16F84A
error (__MAXRAM must be used first)
 
#26
Revisando encontre que:
en el pic 16F84A
STATUS Bits
RP0 EQU H'0005'

y en el pic 18f452 no aparece y de ahi el error y no se cual sera su sustituto:
;----- STATUS Bits -
N EQU H'0004'
OV EQU H'0003'
Z EQU H'0002'
DC EQU H'0001'
C EQU H'0000'
 
#27
He realizado el proyecto con un TSOP1736 y no me funciona. ¿Habéis vosotros realizado el circuito? ¿Que sensor habéis usado?
Gracias
Josemari
 
#31
Hola a todos!
Que honor que hayan seguido trabajando en este Post.

Tendré que disculparme, ya que podré subir los archivos (Todos: esquemas y programa) recién el lunes. Lo que pasa es que estoy lejos de mi computador ahora. Allí sabrán qué circuitos ocupé.

Saludos!
 
#33
Aquí les tengo todos mis archivos que tienen que ver con el tema. La idea de este "pack", es que contenga toda la información necesaria para realizar el proyecto de comienzo a fin.

El amigo jsemari parece que tiene una versión más nueva del programa hecho en assembler para PIC. Es así?

Si tienen más preguntas... obvio que escriben!
Saludos!
 

Adjuntos

#36
Hola!!
Somos dos estudiantes de 2º de ingenieria de telecomunicaciones de españa y tenemos que hacer un proyecto muy parecido al de ELIUSM. Nuestro proyecto consiste en controlar por control remoto (con el protocolo RC5) 8 leds. 4 de ellos seran de salida por pines digitales para simplemente apagarlos y encenderlos y los otros 4 seran por salida analogica para regularlos en intensidad mediante el boton de volumen del mando a distancia.
Nuestro conocimiento en este campo es bastante escaso, es posible que nos envieis el codigo del programa o algo que sea parecido??os lo agradeceriamos muxoo!!!
graciasssss!!!!!!!!!!!!!!!!!!!!!!!
 
#37
en caso de que nos les funcione con todos los controles remotos ..por que no crean ustedes mismos su propio control remoto RC5.....para poder ver los pulsos que envían los controles remotos convencionales...podrían hacer un adaptador para mostrar los pulsos en el analizador lógico del PICKIT2...para los que tengan ese programador.
 
#39
me gustaria saber si alguno de ustedes tiene el codigo para que el pic pueda decodificar un control remoto no importa si es sony o philips, yo tengo los dos, estoy haciendo un proyecto que se controla con un control remoto pero no puedo hacer que el pic 16f84a decodifique la trama del infrarrojo, si tienen el codigo en c ( ccs ) mejor ya le estoy agarrando un poco a c o si lo tienen en asm no importa buscare la manera de entenderle.

Desde ya muchas gracias
 
#40
hola compañeros del foro. Me parecio muy interesante los aportes ELIUSM y los demas integrantes de este foro, aunque el unico problema que tengo es que trabajo con microcontroladores HC08, especificamente con el GP32 y me gustaria saber como hacer el mismo proyecto utilizando este microcontrolador. Mi otro inconveniente es que en programo en C y mi fuerte no es assembler. Porfavor podrian asesorarme un poco.
 

Temas similares

Arriba