.: Código para el control de; Portón, Semáforo, Timbre y Luz de cochera
Esta vez no haré comentarios respecto al código, ya que habla por sí sólo y a demás ya lo analizamos bastante, no sea cosa que te me duermas... jaja...
;---------------- Encabezado --------------------
LIST P=16F84
#include <P16F84.INC>
;----------- Registros de tiempo ----------------
reg1 EQU 0x0C
reg2 EQU 0x0D
;-------------- Vector de Reset -----------------
ORG 0x00
GOTO inicio
;----------Rutina de interrupción (ISR)----------
ORG 0x04
BTFSS INTCON,1 ; salta si la interrup. es por RB0
GOTO tmr ; sino, es por TMR0 y ahí lo atiende
BCF INTCON,1 ; limpia bandera INTF
RETFIE ; retorno de interrupción
tmr BCF INTCON,2 ; limpia bandera de T0IF
RETFIE ; retorno de interrupción
;----------- Configuración de puertos -----------
inicio BSF STATUS,RP0
MOVLW 0XFF ; carga w con 1111 1111
MOVWF TRISA ; PORTA es entradas
MOVLW 0x01 ; carga w con 0000 0001
MOVWF TRISB ; RB0=entrada, el resto salida
MOVLW 0X47 ; carga w con 0100 0111
MOVWF OPTION_REG ; RB0=flanco ascendente, prescaler=256
BCF STATUS,RP0
;------- Habilitación interrupción por RB0 -------
MOVLW 0x90 ; habilitamos interrupciones 1001 0000
MOVWF INTCON ; GIE e INTE(para RB0)
CLRF PORTB ; limpio el puerto B
;------------ El portón está abierto? ------------
BTFSC PORTA,2 ; salta si Dcerrar=0 (portón abierto)
GOTO dormir ; sino (portón cerrado) va a dormir
;------- Si está abierto espera instrucción ------
espera BTFSC PORTB,0 ; salta si no se pulsa Abrir
GOTO abrir ; sino, fue pulsado y lo atiende en abrir
BTFSC PORTA,0 ; salta si no se pulsa cerrar
GOTO c_rrar ; sino, fue pulsado y lo atiende en c_rrar
GOTO espera
;-------- micro en estado de bajo consumo --------
dormir SLEEP ; Espera interrupción por RB0
;--------- Rutina para abrir el portón -----------
abrir BCF PORTB,4 ; prepara motor para subir
CALL retardo ; hace un pequeño retardo
BSF PORTB,1 ; enciende motor (abre)
BSF PORTB,2 ; enciende semáforo
d_abrir BTFSS PORTA,1 ; salta si se pulsa Dabrir (sensor)
GOTO d_abrir ; sino lo atiende en d_abrir
BCF PORTB,1 ; Dabrir=1, entonces detiene motor
BSF PORTB,3 ; y enciende timbre
espero BTFSC PORTA,0 ; salta si no se pulsa cerrar (pulsador)
GOTO c_rrar ; sino, fue activado y lo atiende en c_rrar
GOTO espero ; espero que se pulse cerrar
;--------- Rutina para cerrar el portón -----------
c_rrar BCF PORTB,3 ; apaga timbre
BSF PORTB,4 ; invierte motor para bajar
CALL retardo ; hace un pequeño retardo
BSF PORTB,1 ; enciende motor
dcerrar BTFSS PORTA,2 ; salta si se activa Dcerrar (sensor)
GOTO dcerrar ; sino, espero que se active
BCF PORTB,1 ; Dcerrar=1, entonces detiene motor
BSF PORTB,5 ; enciende luz de cochera
BCF PORTB,2 ; apaga semáforo
;------- Rutina de temporización 50 segundos -------
MOVLW 0xA0 ; habilita T0IE interrupción por TMR0
MOVWF INTCON
MOVLW 0x2D ; cargo w con d'45'=0x2D
MOVWF reg1 ; lo pasa a reg1
tiempo1 MOVLW 0x64 ; cargo w con 100
MOVWF reg2 ; y lo pasa a reg2
tiempo MOVLW 0xD8 ; cargo w con 216
MOVWF TMR0 ; lo pasa a TMR0
nada BTFSC TMR0,7 ; Salta si Bit7 de TMR0 es cero
GOTO nada ; sino espera interrupción por TMR0
DECFSZ reg2,1 ; decremento reg2 y salta si reg2=0
GOTO tiempo ; sino vuelve a cargar TMR0
DECFSZ reg1,1 ; decrementa reg1 y salta si reg1=0
GOTO tiempo1 ; sino vuelve a cargar reg2
BCF PORTB,5 ; 50 seg. cumplidos apago luz de cochera
CLRF INTCON ; deshabilito interrupciones
GOTO inicio ; vuelve a empezar para dormir al micro
; ------ retardo de 189000 us. aproximadamente --------
retardo MOVLW 0xFA ; Aquí se cargan los registros
MOVWF reg1 ; carga reg1 con 250
dos MOVWF reg2 ; y reg2 con 250
uno DECFSZ reg2,1 ; decrementa y salta si reg2=0
GOTO uno
DECFSZ reg1,1 ; decrementa y salta si reg1=0
GOTO dos ; irá a cargar reg2 nuevamente
RETURN ; regreso del retardo
;------------------------------------------
END
;------------------------------------------
|
|
Observa aquello que está en rojo...
CLRF INTCON ; deshabilito interrupciones
GOTO inicio ; vuelve a empezar para dormir al micro
Eso de deshabilitar las interrupciones lo hice por que ya no será necesaria la interrupción por TMR0 por que terminó la temporización, y lo de regresar al inicio del código es por permitir la habilitación de la interrupción para RB0 y finalmente poner al micro en modo SLEEP.
En la temporización de los 189 milisegundos hay algo muy curioso...
retardo MOVLW 0xFA ; Aquí se cargan los registros
MOVWF reg1 ; carga reg1 con 250
dos MOVWF reg2 ; y reg2 con 250
Primero se cargó w con d'250' y luego se pasó el valor a reg1 y a reg2, mientras el decremento en la temporización se ejecuta, hay un salto a la etiqueta dos, donde sólo se hace MOVWF reg2, Lo curioso es que no se carga nuevamente el registro w con el valor 250 para pasarlo a reg2, y esto es así por que el registro w no fue utilizado para nada mientras se ejecutaba el retardo, por lo tanto w aún retiene los 250 que le cargamos anteriormente. Cuando hagas esto, debes tener mucho cuidado y asegurarte de que no utilizaste w y que todavía tiene el valor anterior, de lo contrario tendrás muchos problemas...
Bueno creo que no queda nada más, o mejor dicho sí, como hacer para conectar los relés, en otras palabras... el circuito...!!!
Hablaremos de él en la siguiente página...
R-Luis...
<-- Anterior
Introducción
Siguiente -->
Tabla de Referencias
|