Hola a todos,
Cuando ejecuto el siguiente código, sin interrumpir por RB0, el programa principal funciona con total normalidad.
El código debe abrir y cerrar una persiana dependiendo de la luz exterior (comparador con LDR) y controlar la intensidad lumínica interior, segun divisor de tensión con LDR. Todo esto junto con un detector de paso por cero. Controlan 2 relés, así como el disparo del triac. La parte del código principal actúa sobre las persianas, y calcula el tiempo que debe estar encendida la lampara.
Pues bien, la parte de la persiana la hace correctamente si no se activa el RB0. pero en el momento que se activa RB0, ya no vuelve a cambiar de estado, pero tampoco me dispara el triac.
Alguien me puede echar una manita?
A continuación el código y adjunto el diseño.
Cuando ejecuto el siguiente código, sin interrumpir por RB0, el programa principal funciona con total normalidad.
El código debe abrir y cerrar una persiana dependiendo de la luz exterior (comparador con LDR) y controlar la intensidad lumínica interior, segun divisor de tensión con LDR. Todo esto junto con un detector de paso por cero. Controlan 2 relés, así como el disparo del triac. La parte del código principal actúa sobre las persianas, y calcula el tiempo que debe estar encendida la lampara.
Pues bien, la parte de la persiana la hace correctamente si no se activa el RB0. pero en el momento que se activa RB0, ya no vuelve a cambiar de estado, pero tampoco me dispara el triac.
Alguien me puede echar una manita?
A continuación el código y adjunto el diseño.
Código:
PROCESSOR 16F877 ; define tipo de procesador
__CONFIG 0x3731 ; 4Mhz frecuencia de reloj, standard fuse
#include <p16F877.inc> ; Etiquetas de registro estandard
; Registra etiquetas EQU
STATUS EQU 0x03
PORTA EQU 0x05 ; Registro de datos del puerto A
PORTB EQU 0x06 ; Registro de datos del puerto B
PORTC EQU 0x07 ; Registro de datos del puerto C
PORTD EQU 0x08 ; Registro de datos del puerto D
TRISA EQU 0x85 ; Direccion del registro puerto A
TRISB EQU 0x86 ; Direccion del registro puerto B
TRISC EQU 0x87 ; Direccion del registro puerto C
TRISD EQU 0x88 ; Direccion del registro puerto D
ADCON0 EQU 0x1F
ADCON1 EQU 0x9F ;
ADRESH EQU 0x1E
TMR0 EQU 0x01 ; Registro de tiempo hardware
INTCON EQU 0x0B ; Registro de control de interrupcion
OPTREG EQU 0x81 ; Registro de opciones
st_pers EQU 0x20 ; Var para control del estado de la persiana
st_LigH EQU 0x21 ; Var para control del estado de la luz
comp1 EQU 0x22 ; Var resultado comparador 1
comp2 EQU 0x23 ; Var resultado comparador 2
Lampara EQU 0x24 ; Luminosidad de la lampara 0=baja..127=maxima
result EQU 0x25 ; Var para almacenar resultado comparacion.
estado EQU 0x26 ; Var para estados d las var XXXX X pers sint sext
count1 EQU 0x27 ; Var para el contador de delay
count2 EQU 0x28 ; Var para el contador de delay
W_Temp EQU 0x70 ; Guardamos registro W durante interrupcion (0x70 para acceder desde cualquier banco)
St_Temp EQU 0x71 ; Guardamos registro STATUS durante interrupcion(0x71 para acceder desde cualquier banco)
ls_adc EQU 0x29 ; Guardamos el valor despues de la conversion AD
DEMORA EQU 0x2A ; Valor de demora para enceder el TRIAC
PDel0 EQU 0x2B ; Variable para el calculo de 5segundos de retardo
PDel1 EQU 0x2C ; Variable para el calculo de 5segundos de retardo
PDel2 EQU 0x2D ; Variable para el calculo de 5segundos de retardo
Contador EQU 0x2E ; Variable para el retardo de 20us
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ORG 000 ; Comienzo de la memoria del programa
NOP ; Para el modo ICD
GOTO init ; Salta al programa principal
ORG 04
GOTO INT
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Inicializacion del puertos ..................................................
init
BCF STATUS,7 ; Configuro el bit FSR a 0 xa trabajar bank0/1
BCF STATUS,5 ; Seleccion el bank0 de memoria RP0
BCF STATUS,6 ; poniendo 00 en RP0:RP1
BCF estado,2 ; Inicia el estado de la persiana a cerrado
BCF estado,3 ; Ha contado los 5 segundos de accion de persiana?
CLRF PORTA ; Limpia los puertos del A al D
CLRF PORTB
CLRF PORTC
CLRF PORTD
BSF STATUS,5 ; Selecciono el bank 1 poniendo 01 RP0:RP1
MOVLW 0X80 ;
MOVWF ADCON1 ; Todos los pines del puerto A son analogicos
MOVLW 0XCF ;
MOVWF TRISA ; Todos los pines del puerto A son entradas
NOP ; BANKSEL no puede ser etiquetada
BANKSEL TRISB ; Selecciona el bank1
MOVLW b'11111101' ; Configura el RB1 como salida(b'11111101') 253
MOVWF TRISB ; Carga el codigo DDR en F86
NOP ; BANKSEL no puede ser etiquetada
BANKSEL TRISC ; Selecciona el bank1
MOVLW b'01111111' ; Configura RC6 y RC7 como salida(b'01111111') 127
MOVWF TRISC ; Carga el codigo DDR en F87
NOP ; BANKSEL no puede ser etiquetada
BANKSEL TRISD ; Selecciona el bank1
MOVLW b'00000000' ; Configura RD1 a RD4 como salida(b'11111100') 252
MOVWF TRISD ; Carga el codigo DDR en F88
NOP ; BANKSEL no puede ser etiquetada
BANKSEL TRISE ; Selecciona el bank1
MOVLW b'00000000' ; Configura bit4 a 0 xa utilizar portd como puertos gnral
MOVWF TRISE ;
MOVLW B'11000111' ;EL PRESCALER ES ASIGNADO AL TMR0
MOVWF OPTION_REG
MOVLW B'10010000' ;INTERRUPCION POR PIN RB0
MOVWF INTCON
BANKSEL 0
GOTO Ppal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
INT
BTFSS INTCON, INTF
GOTO OTROCASO
BCF INTCON, INTE
MOVF DEMORA, W
MOVWF TMR0
BSF INTCON, INTE
BCF INTCON, T0IF
BACK
RETFIE
OTROCASO
BCF INTCON, INTE
BSF PORTB,1
BSF INTCON, INTE
BCF INTCON, T0IF
GOTO BACK
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Programa principal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Ppal
CALL Capdat ; Llamamos la subrutina de captura de datos
CALL nivluz1 ; Llamamos la subrutina de tratamiento de datos para dimmer
CALL persia ; Ejecutamos la subrutina de actuacion de las persianas
GOTO Ppal
;Subrutina de captura de datos.................................................
; Adquisicion datos de la LDR para intensidad interior habitacion
; Inicializacion de la conversion AD. Reloj de conversion 4MHz/32,AN4 canal seleccionado como
; AN0,AD conversion OFF,AD modulo de conversion encendido
Capdat
banksel ADCON0
movlw b'01000001' ; fosc 8, RA0 analogico
movwf ADCON0
; Incializacion convertidor AD. Justificado a la izquierda, todos los PORTA como entrada analogica
banksel ADCON1
movlw b'00001110' ;Justificado a la izquierda, canal 0, modulo habilitado
movwf ADCON1
call Demora_20us ; Esperamos el tiempo de adquisicion necesario
; Comenzamos la conversion AD
banksel ADCON0
bsf ADCON0,2
; Esperamos que acabe la conversion
espera
btfsc ADCON0,2
goto espera
; Guardamos el valor despues de la conversion en la variable ls_adc.
banksel ADRESH
movf ADRESH,0 ; Despues de finalizar la conversion AD el valor en ADRESH se guarda en el Reg W
; y el valor en ADRESL se omite, esa precision no es necesaria.
banksel ls_adc
movwf ls_adc ; valor en W Reg. se escribe en la variable ls_adc
RETURN
Demora_20us
movlw 0x05
movwf Contador ; iniciamos contador
Repeticion
decfsz Contador,1 ; Decrementa Contador en 1
goto Repeticion ; Si no es cero repetimos el ciclo
RETURN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Tratamiento de los datos, comparativa de niveles de luz.......................
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
nivluz1
MOVLW b'01111111' ; cargo valor a comparar nivel con 2,5V
SUBWF ls_adc,W ; comparamos ambos registros
BTFSC STATUS,Z ; Si son iguales se ejecuta la siguiente, en caso contrario se salta
GOTO dem10ms
BTFSS STATUS, C ; comprobamos el bit de complemento para saber si es mayor o menor
GOTO nivluz2 ; en caso de que sea menor comprobamos siguiente intervalo
dem10ms
MOVLW b'11011001' ; cargamos 217 en DEMORA que corresponde con 10ms para el TMR0
MOVWF DEMORA ; ya que hay luz y no necesitamos que este encendida
RETURN
nivluz2
MOVLW b'01110010' ; cargo valor a comparar nivel con 2.25V
SUBWF ls_adc,W ; comparamos ambos registros
BTFSC STATUS,Z ; Si son iguales se ejecuta la siguiente, en caso contrario se salta
GOTO dem9ms
BTFSS STATUS, C ; comprobamos el bit de complemento para saber si es mayor o menor
GOTO nivluz3 ; en caso de que sea menor comprobamos siguiente intervalo
dem9ms
MOVLW b'11000011' ; cargamos 195 en DEMORA que corresponde con 9ms para el TMR0
MOVWF DEMORA ; ya que hay luz y no necesitamos que este encendida
RETURN
nivluz3
MOVLW b'01100110' ; cargo valor a comparar nivel con 2V
SUBWF ls_adc,W ; comparamos ambos registros
BTFSC STATUS,Z ; Si son iguales se ejecuta la siguiente, en caso contrario se salta
GOTO dem8ms
BTFSS STATUS, C ; comprobamos el bit de complemento para saber si es mayor o menor
GOTO nivluz4 ; en caso de que sea menor comprobamos siguiente intervalo
dem8ms
MOVLW b'10101101' ; cargamos 173 en DEMORA que corresponde con 8ms para el TMR0
MOVWF DEMORA ; ya que hay luz y no necesitamos que este encendida
RETURN
nivluz4
MOVLW b'01011001' ; cargo valor a comparar nivel con 1.75V
SUBWF ls_adc,W ; comparamos ambos registros
BTFSC STATUS,Z ; Si son iguales se ejecuta la siguiente, en caso contrario se salta
GOTO dem7ms
BTFSS STATUS, C ; comprobamos el bit de complemento para saber si es mayor o menor
GOTO nivluz5 ; en caso de que sea menor comprobamos siguiente intervalo
dem7ms
MOVLW b'10010111' ; cargamos 151 en DEMORA que corresponde con 7ms para el TMR0
MOVWF DEMORA ; ya que hay luz y no necesitamos que este encendida
RETURN
nivluz5
MOVLW b'01001100' ; cargo valor a comparar nivel con 1.5V
SUBWF ls_adc,W ; comparamos ambos registros
BTFSC STATUS,Z ; Si son iguales se ejecuta la siguiente, en caso contrario se salta
GOTO dem6ms
BTFSS STATUS, C ; comprobamos el bit de complemento para saber si es mayor o menor
GOTO nivluz6 ; en caso de que sea menor comprobamos siguiente intervalo
dem6ms
MOVLW b'10000010' ; cargamos 130 en DEMORA que corresponde con 6ms para el TMR0
MOVWF DEMORA ; ya que hay luz y no necesitamos que este encendida
RETURN
nivluz6
MOVLW b'00111111' ; cargo valor a comparar nivel con 1.25V
SUBWF ls_adc,W ; comparamos ambos registros
BTFSC STATUS,Z ; Si son iguales se ejecuta la siguiente, en caso contrario se salta
GOTO dem5ms
BTFSS STATUS, C ; comprobamos el bit de complemento para saber si es mayor o menor
GOTO nivluz7 ; en caso de que sea menor comprobamos siguiente intervalo
dem5ms
MOVLW b'01101100' ; cargamos 108 en DEMORA que corresponde con 5ms para el TMR0
MOVWF DEMORA ; ya que hay luz y no necesitamos que este encendida
RETURN
nivluz7
MOVLW b'00110011' ; cargo valor a comparar nivel con 1V
SUBWF ls_adc,W ; comparamos ambos registros
BTFSC STATUS,Z ; Si son iguales se ejecuta la siguiente, en caso contrario se salta
GOTO dem4ms
BTFSS STATUS, C ; comprobamos el bit de complemento para saber si es mayor o menor
GOTO nivluz8 ; en caso de que sea menor comprobamos siguiente intervalo
dem4ms
MOVLW b'01010110' ; cargamos 86 en DEMORA que corresponde con 4ms para el TMR0
MOVWF DEMORA ; ya que hay luz y no necesitamos que este encendida
RETURN
nivluz8
MOVLW b'00100110' ; cargo valor a comparar nivel con 0.75V
SUBWF ls_adc,W ; comparamos ambos registros
BTFSC STATUS,Z ; Si son iguales se ejecuta la siguiente, en caso contrario se salta
GOTO dem3ms
BTFSS STATUS, C ; comprobamos el bit de complemento para saber si es mayor o menor
GOTO nivluz9 ; en caso de que sea menor comprobamos siguiente intervalo
dem3ms
MOVLW b'01000001' ; cargamos 65 en DEMORA que corresponde con 3ms para el TMR0
MOVWF DEMORA ; ya que hay luz y no necesitamos que este encendida
RETURN
nivluz9
MOVLW b'00011001' ; cargo valor a comparar nivel con 0.5V
SUBWF ls_adc,W ; comparamos ambos registros
BTFSC STATUS,Z ; Si son iguales se ejecuta la siguiente, en caso contrario se salta
GOTO dem2ms
BTFSS STATUS, C ; comprobamos el bit de complemento para saber si es mayor o menor
GOTO no_dem ; en caso de que sea menor no aplicamos ninguna demora
dem2ms
MOVLW b'00101011' ; cargamos 65 en DEMORA que corresponde con 2ms para el TMR0
MOVWF DEMORA ; ya que hay luz y no necesitamos que este encendida
RETURN
no_dem
MOVLW b'00000000' ;no aplicamos ninguna demora, al estar en completa oscuridad
MOVWF DEMORA
RETURN
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Tratamiento de los datos, accion de persiana..................................
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
persia
BTFSC estado,2 ;testeo del bit persiana
GOTO abierta ; Si 1 voy a comprobar el bit de estado de la luz
GOTO cerrada ; Si 0 voy a comprobar el bit de estado de la luz
abierta
BTFSS PORTB, 4 ; testeo si hay luz exterior
GOTO cerrar ; Si no hay luz, entonces cerramos la persiana
RETURN ; Si hay luz, no hacemos nada
cerrada
BTFSS PORTB, 4 ; testeo si hay luz exterior
RETURN ; si no hay luz ext, no hacemos nada
GOTO abrir ; Si hay luz exterior, lo abrimos
abrir
BSF PORTD,0 ; mandamos un 1 por RD0 para abrir
CALL espera5s ; Esperamos 5 segundos (tiempo a regular) para dejar terminar la apertura
BCF PORTD,0 ; Apagamos la señal del puerto D0
NOP
BSF estado,2 ; Actualizamos la bandera del bit de estado a abierto
RETURN
cerrar
BSF PORTD,1 ; mandamos un 1 por RD1 para cerrar
CALL espera5s ; Esperamos 5 segundos (tiempo a regular) para dejar terminar la apertura
BCF PORTD,1 ; Apagamos la señal del puerto D1
NOP
BCF estado,2 ; Actualizamos la bandera del bit de estado a cerrado
RETURN
;-------------------------------------------------------------
espera5s
movlw .165 ; 1 set numero de repeticion (C)
movwf PDel0 ; 1 |
PLoop0
movlw .41 ; 1 set numero de repeticion (B)
movwf PDel1 ; 1 |
PLoop1
movlw .147 ; 1 set numero de repeticion (A)
movwf PDel2 ; 1 |
PLoop2
clrwdt ; 1 clear watchdog
clrwdt ; 1 ciclo delay
decfsz PDel2, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop2 ; 2 no, loop
decfsz PDel1, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop1 ; 2 no, loop
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ? (C)
goto PLoop0 ; 2 no, loop
return ; 2+2 Fin.
;-------------------------------------------------------------
END