Contro de Mando a Distancia con el PIC 16F818

#1
hola. por favor si me pueden ayudar a que me pueda simular el circuito en Proteus, el circuito lo descargue de internet, segun lo que encontre leyendo en internet es tengo que desactivar el wachdog, pero no lo encuentro por favor si me pueden ayudar. Desde ya muchas Gracias.
aqui el C del PIC

PHP:
;**********************************************************************
;                                                                     *
;   Receptor de mando a distancia por infrarrojos "La Garita"         *
;                                                                     *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Filename: mando2.asm                                             *
;    Date: 23-2-2006                                                  *
;    File Version: 1.0                                                *
;	 PIC: 16F818													  *
;                                                                     *
;    Autor: "Pablo Martínez Rochela" para "La Garita"                 *
;    Basado en: "JMB: 												  *
;			http://www.fortunecity.es/arcoiris/tarot/572/mandos.html" *
;                                                                     *
;**********************************************************************

;**********************************************************************
;                                                                     *
;    Notas:                                                           *
;      Se utiliza un Reloj de cuarzo de 4MHz.                         *
;      La entrada de la señal es RB0, activa a nivel bajo.            *
;      El mando envía los bits codificados por el tiempo entre        *
;    pulsos.							      						  *
;                                                                     *
;       00000000  11111111  XXXXXXXX  YYYYYYYY                        *
;            cabecera       comando   comando comp.                   *
;                                                                     *
;      La salida del detector de infrarrojos es activa a nivel bajo y *
;    está conectada a RB0.                                            *
;																	  *
;	Configuración IC-Prog para programar el PIC:					  *	
;		Oscilador: XT												  *
;		WDT: OFF													  *
;		PWRT: OFF													  *
;		MCLR: ON													  *
;		BODEN: OFF													  *
;		LVP: OFF													  *
;		CPD: OFF													  *
;		DEBUGGER: OFF												  *
;		CCPMX: ON													  *
;																	  *
;		Palabra de Configuración: 3F29h								  *
;                                                                     *
;**********************************************************************


	list      p=16F818


;***** DEFINICIÓN DE VARIABLES **************************************************

PORTA		equ 	0x05
PORTB		equ 	0x06
TRISA		equ 	0x05  	; Config. PORTA, o sea TRISA
TRISB		equ 	0x06	; Config. PORTB, o sea TRISB
STATUS		equ 	0x03
ADCON1		equ		0x9F
INTCON		equ 	0x0B  	; Registro controlador de interrupciones
TMR0		equ 	0x01  	; Timer0
option_reg	equ 	0x01	; controla el TMR0

w_temp        	EQU   	0x0C	; Variable utilizada para guardar w.
status_temp   	EQU     0x0D	; Variable utilizada para guardar el status.

contador1	EQU	0x2B	; Contadores.
contador2	EQU	0x2C
CONT		EQU	0x2D
CONT2		EQU	0x2E
CONT3		EQU	0x2F
CONT4		EQU	0x30

temp1		EQU	0x27	; Registros donde se guarda la transmisión recibida.
temp2		EQU	0x28
temp3		EQU	0x29
temp4		EQU	0x2A

PUL7		equ 	0x21    ; Variable PUL7
PUL8		equ 	0x22	; Variable PUL8
PUL9		equ 	0x23	; Variable PUL9
PUL10		equ 	0x24	; Variable PUL10
PUL11		equ 	0x25	; Variable PUL11
PUL12		equ 	0x26	; Variable PUL12


;***** CONSTANTES DEL PROGRAMA ***************************************************


num_bits	EQU	D'32'	; Número de bits en una transmisión.

rec_ir		EQU	0		; Entrada de la señal desde el receptor de infrarrojos.
Z			EQU	2

;*********************************************************************************


		ORG     0x000   ; Vector de reset.
  		goto    Main    ; Va al inicio del programa.

		ORG     0x004	; Vector de interrupción: se ha recibido una señal.
		goto	IR

;---------------------------------------------------------------------------------
;		Controlador de interrupción
;---------------------------------------------------------------------------------

IR

		btfss	INTCON,1	; se asegura que la interrupción se ha producido en RB0
		retfie				; si no es de RB0 vuelve al programa principal
	
		movwf   w_temp		; Guarda el contenido de W...
		movf	STATUS,w	; ...y guarda el contenido de status.
		movwf	status_temp

		call	Recibe		; Recibe los datos.
		call	Comprueba	; Comprueba la validez de los datos.
		andlw	1
		btfss	STATUS,Z	; Si son correctos...
		goto	fuera
		call	Envia		; ...envía la orden
		call	Salida		; actualiza las salidas
		call	retardo		; retardo por si se mantiene pulsado algún botón del mando

fuera:	movf    status_temp,w	; restaura el contenido de status...
		movwf	STATUS
		swapf   w_temp,f
		swapf   w_temp,w	; ...y restaura el contenido de w.

		bcf 	INTCON,1	; Borra la bandera de interrupción (INTF)
		bsf 	INTCON,4	; Habilita de nuevo la interrupción (INTE)

		retfie


;----------------------------------------------------------------------------------
;		Subrutina que recibe la transmisión
;----------------------------------------------------------------------------------

Recibe


		clrf	temp1		; Limpia los registros temporales.
		clrf	temp2
		clrf	temp3
		clrf	temp4

		; Primero espera a que acaben el pulso y el espacio de inicio:

		clrf	TMR0

bajo1:	btfsc	PORTB,rec_ir		; Espera a que acabe el espacio inicial
		goto	alto1
		btfsc	TMR0,7		; Si el tiempo es mayor que 128 volvemos al inicio.
		return
		goto	bajo1

alto1:	btfss	PORTB,rec_ir		; Espera a que acabe el pulso inicial
		goto	bajo1.2
		btfsc	TMR0,7		; Si el tiempo es mayor que 128 volvemos al inicio.
		return
		goto	alto1	

bajo1.2:btfsc	PORTB,rec_ir		; Espera a que acabe el segundo espacio inicial
		goto	bits32
		btfsc	TMR0,7		; Si el tiempo es mayor que 128 volvemos al inicio.
		return
		goto	bajo1.2

		btfsc	contador2,7	; Si el tiempo es mayor que 128 volvemos al inicio.
		return

		; Ahora recibe los 32 bits:

bits32:	movlw	num_bits		; Prepara el contador de bits.
		movwf	contador1

rec_bit:clrf	TMR0			; Empieza la cuenta del tiempo del bit.

alto2:	btfss	PORTB,rec_ir		; Espera a que acabe el pulso
		goto	bajo2
		btfsc	TMR0,6		; Si el tiempo es mayor que 64 volvemos al inicio.
		return
		goto	alto2

bajo2:	btfsc	PORTB,rec_ir		; Espera a que acabe el espacio
		goto	t_bit
		btfsc	TMR0,6		; Si el tiempo es mayor que 64 volvemos al inicio.
		return
		goto	bajo2
	
t_bit:	movf	TMR0,w			; Obtiene el tiempo del bit.
		movwf	contador2

		btfsc	contador2,6	; Si el tiempo es mayor que 64 volvemos al inicio.
		return

		movlw	0x0D		; Calcula si el bit es un uno o un cero (si es mayor que 13 -> '1', y si no -> '0'):
		subwf	contador2,w	; Restamos... (contador2 - 13)
		rlf	temp4,f		; ... y metemos el carry en un registro de
		rlf	temp3,f		; desplazamiento de 4 bytes, hacia la izquierda.
		rlf	temp2,f
		rlf	temp1,f

		decfsz	contador1,f	; Continúa repitiendo o sigue adelante.
		goto 	rec_bit

		return


;---------------------------------------------------------------------------------
;               Subrrutina que realiza la verificación de errores
;---------------------------------------------------------------------------------

Comprueba

		movlw	B'00000000'	; Comprueba el valor de la cabecera.
		xorwf	temp1,w
		btfss	STATUS,Z
		retlw	1		; Si no es correcto sale indicando error.

		movlw	B'11111111'	; Comprueba el valor de la cabecera.
		xorwf	temp2,w
		btfss	STATUS,Z
		retlw	1		; Si no es correcto sale indicando error.

		comf	temp4,f		; Complementa el último byte.

		movf	temp4,w		; Compara los bits de comando.
		xorwf	temp3,w
		btfss	STATUS,Z
		retlw	1		; Si son distintos sale indicando error.

		retlw	0		; Si todo va bien, sale victorioso de la comprobación.


;---------------------------------------------------------------------------------
;		Subrutina que modifica los valores de las variables.
;---------------------------------------------------------------------------------

Envia

		; Según el botón pulsado escribimos el valor en la variable necesaria:

c_1:	movf	temp3,w
		xorlw	B'11010000'	; botón 06 (si coincide con la señal que hemos obtenido, Z estará a 1)
		btfss	STATUS,Z
		goto	c_2
		movlw	1			; carga en el registro de trabajo 1
		xorwf	PUL7,f		; Cambia el contenido de PUL7 (de 0 a 1, ó de 1 a 0)
		goto	vuelve

c_2:	movf	temp3,w	
		xorlw	B'01010000'	; botón 05 (si coincide con la señal que hemos obtenido, Z estará a 1)
		btfss	STATUS,Z
		goto	c_3
		movlw	1			; carga en el registro de trabajo 1
		xorwf	PUL8,f		; Cambia el contenido de PUL8 (de 0 a 1, ó de 1 a 0)
		goto	vuelve

c_3:	movf	temp3,w
		xorlw	B'10010000'	; botón 03 (si coincide con la señal que hemos obtenido, Z estará a 1)
		btfss	STATUS,Z
		goto	c_4
		movlw	1			; carga en el registro de trabajo 1
		xorwf	PUL9,f		; Cambia el contenido de PUL9 (de 0 a 1, ó de 1 a 0)
		goto	vuelve

c_4:	movf	temp3,w
		xorlw	B'10110000'	; botón 04 (si coincide con la señal que hemos obtenido, Z estará a 1)
		btfss	STATUS,Z
		goto	c_5
		movlw	1			; carga en el registro de trabajo 1
		xorwf	PUL10,f		; Cambia el contenido de PUL10 (de 0 a 1, ó de 1 a 0)
		goto	vuelve

c_5:	movf	temp3,w
		xorlw	B'11000000'	; botón 02 (si coincide con la señal que hemos obtenido, Z estará a 1)
		btfss	STATUS,Z
		goto	c_6
		movlw	1			; carga en el registro de trabajo 1
		xorwf	PUL11,f		; Cambia el contenido de PUL11 (de 0 a 1, ó de 1 a 0)
		goto	vuelve

c_6:	movf	temp3,w
		xorlw	B'00000000'	; botón 01 (si coincide con la señal que hemos obtenido, Z estará a 1)
		btfss	STATUS,Z
		goto	vuelve
		movlw	1			; carga en el registro de trabajo 1
		xorwf	PUL12,f		; Cambia el contenido de PUL12 (de 0 a 1, ó de 1 a 0)

vuelve:		return			; ...y fuera.


;------------------------------------------------------------------
; subrutina Salida (actualiza las salidas en función de las variables correspondientes)
;------------------------------------------------------------------

Salida
		btfsc	PUL7,0
		bsf	PORTA,1
		btfss	PUL7,0
		bcf	PORTA,1
		
		btfsc	PUL8,0
		bsf	PORTA,0
		btfss	PUL8,0
		bcf	PORTA,0

		btfsc	PUL9,0
		bsf	PORTB,7
		btfss	PUL9,0
		bcf	PORTB,7

		btfsc	PUL10,0
		bsf	PORTB,6
		btfss	PUL10,0
		bcf	PORTB,6

		btfsc	PUL11,0
		bsf	PORTB,4
		btfss	PUL11,0
		bcf	PORTB,4

		btfsc	PUL12,0
		bsf	PORTB,5
		btfss	PUL12,0
		bcf	PORTB,5

		return


;------------------------------------------------------------------
; subrutina retardo	-> genera un retardo de unos 38'5 mseg cuando la entrada del receptor de IR está a 1
;------------------------------------------------------------------

retardo
	movlw	50		; mete 50 en el registro de trabajo
	movwf	CONT2		; mete en la variable CONT2 lo que hay en el registro de trabajo, es decir, 10
bucleR	clrf	CONT		; inicializa a 0 el contador CONT
incre	btfss	PORTB,rec_ir
		goto	retardo
		incfsz	CONT,f	; suma 1 a CONT y lo vuelve a poner en  CONT, luego salta si es igual a 0
	goto	incre		; salta a incre
	decfsz	CONT2,f		; resta 1 a CONT2 y lo vuelve a poner en  CONT2, luego salta si es igual a 0
	goto	bucleR  	; salta a bucleR

	return			; Vuelve al programa principal


;------------------------------------------------------------------
; subrutina Pulsador7
;------------------------------------------------------------------

Pulsador7
		call	rebote	; Llama a la subrutina que previene los rebotes
		movlw	1	; carga en el registro de trabajo 1
		xorwf	PUL7,f	; Cambia el contenido de PUL7 (de 0 a 1, ó de 1 a 0)
espera7		btfsc	PORTA,4	; espera a que se suelte el pulsador para retornar
		goto	espera7	; 
		call	rebote	; Llama a la subrutina que previene los rebotes
		return			

;------------------------------------------------------------------
; subrutina Pulsador8
;------------------------------------------------------------------

Pulsador8
		call	rebote	; Llama a la subrutina que previene los rebotes
		movlw	1		; carga en el registro de trabajo 1
		xorwf	PUL8,f	; Cambia el contenido de PUL8 (de 0 a 1, ó de 1 a 0)
espera8		btfsc	PORTB,1	; espera a que se suelte el pulsador para retornar
		goto	espera8	; 
		call	rebote	; Llama a la subrutina que previene los rebotes
		return			

;------------------------------------------------------------------
; subrutina Pulsador9
;------------------------------------------------------------------

Pulsador9
		call	rebote	; Llama a la subrutina que previene los rebotes
		movlw	1		; carga en el registro de trabajo 1
		xorwf	PUL9,f	; Cambia el contenido de PUL9 (de 0 a 1, ó de 1 a 0)
espera9		btfsc	PORTA,3	; espera a que se suelte el pulsador para retornar
		goto	espera9	; 
		call	rebote	; Llama a la subrutina que previene los rebotes
		return			

;------------------------------------------------------------------
; subrutina Pulsador10
;------------------------------------------------------------------

Pulsador10
		call	rebote	; Llama a la subrutina que previene los rebotes
		movlw	1		; carga en el registro de trabajo 1
		xorwf	PUL10,f	; Cambia el contenido de PUL10 (de 0 a 1, ó de 1 a 0)
espera10	btfsc	PORTB,2	; espera a que se suelte el pulsador para retornar
		goto	espera10; 
		call	rebote	; Llama a la subrutina que previene los rebotes
		return			

;------------------------------------------------------------------
; subrutina Pulsador11
;------------------------------------------------------------------

Pulsador11
		call	rebote	; Llama a la subrutina que previene los rebotes
		movlw	1		; carga en el registro de trabajo 1
		xorwf	PUL11,f	; Cambia el contenido de PUL11 (de 0 a 1, ó de 1 a 0)
espera11	btfsc	PORTA,2	; espera a que se suelte el pulsador para retornar
		goto	espera11; 
		call	rebote	; Llama a la subrutina que previene los rebotes
		return			

;------------------------------------------------------------------
; subrutina Pulsador12
;------------------------------------------------------------------

Pulsador12
		call	rebote	; Llama a la subrutina que previene los rebotes
		movlw	1		; carga en el registro de trabajo 1
		xorwf	PUL12,f	; Cambia el contenido de PUL12 (de 0 a 1, ó de 1 a 0)
espera12	btfsc	PORTB,3	; espera a que se suelte el pulsador para retornar
		goto	espera12; 
		call	rebote	; Llama a la subrutina que previene los rebotes
		return	

;------------------------------------------------------------------
; subrutina rebote
;------------------------------------------------------------------

rebote		movlw	50	; carga en el registro de trabajo 50
		movwf	CONT3	; mueve el contenido del acumulador a retardo
bucleRr		clrf	CONT4
increm		incfsz	CONT4,f
		goto	increm
		decfsz	CONT3,f	; \
		goto	bucleRr ;  }no retorna hasta que retardo llega a cero
		return          ; /

;------------------------------------------------------------------
; subrutina inicializa
;------------------------------------------------------------------

inicializa
		clrf	PUL7		; inicializamos las variables
		clrf	PUL8
		clrf	PUL9
		clrf	PUL10
		clrf	PUL11
		clrf	PUL12
		return

;---------------------------------------------------------------------------------
;		Programa principal
;---------------------------------------------------------------------------------

Main

; Accedemos al segundo banco de RAM de Datos

	bsf STATUS,5

; Configuración puertos

	movlw 0x0F
	movwf TRISB ; RB0, RB1, RB2 y RB3 entradas; RB4, RB5, RB6 y RB7 salidas
	movlw 0x06
	movwf ADCON1; PORTA I/O Digital
	movlw 0xFC
	movwf TRISA ; RA2, RA3 y RA4 entradas; RA0 y RA1 salidas
	movlw 0x86
	movwf option_reg ; Configuramos el prescaler de TMR0 con 128, la interrupción externa de RB0 con pendiente negativa
					 ; y deshabilitamos las resistencias pull-up del PORTB


; Accedemos al primer banco de RAM

	bcf STATUS,5

; Habilitamos las interruciones de RB0

	bsf	INTCON,7	; Habilita la interrupción externa.
	bsf	INTCON,4	; Habilita las interrupciones.

	call	inicializa

bucle:		; revisa si hemos pulsado algún polsador y si es así nos manda a la subrutina correspondiente
	
	btfsc	PORTA,4		; anclado (salida RA1)
	call	Pulsador7

	btfsc	PORTB,1		; anclado (salida RA0)
	call	Pulsador8

	btfsc	PORTA,3		; anclado (salida RB7)
	call	Pulsador9

	btfsc	PORTB,2		; anclado (salida RB6)
	call	Pulsador10

	btfsc	PORTA,2		; anclado (salida RB4)
	call	Pulsador11

	btfsc	PORTB,3		; anclado (salida RB5)
	call	Pulsador12

	call	Salida		; actualiza las salidas

	goto	bucle

	END
 

Adjuntos

Última edición por un moderador:

Temas similares

Arriba