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 0x29 ; Guardamos registro W durante interrupcion
St_Temp EQU 0x30 ; Guardamos registro STATUS durante interrupcion
ls_adc EQU 0x31 ; Guardamos el valor despues de la conversion AD
DEMORA EQU 0x32 ; Valor de demora para enceder el TRIAC
PDel0 EQU 0x33 ; Variable para el calculo de 5segundos de retardo
PDel1 EQU 0x34 ; Variable para el calculo de 5segundos de retardo
PDel2 EQU 0x35 ; Variable para el calculo de 5segundos de retardo
Contador EQU 0x36 ; 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 ; Configure bit FSR a 0 to work with bank0/1
BCF STATUS,5 ; Selecct bank0 RP0
BCF STATUS,6 ; writing 00 en RP0:RP1
BCF estado,2 ; Initial state to shade (blind) as closed
BCF estado,3 ; After 5 seconds running up PORTD, this flag will be active
CLRF PORTA ; cleaning PORTs A al D
CLRF PORTB
CLRF PORTC
CLRF PORTD
BSF STATUS,5 ; Selectbank 1 writing 01 RP0:RP1
MOVLW 0X80 ;
MOVWF ADCON1 ; PORTA as analogic
MOVLW 0XCF ;
MOVWF TRISA ; PORTA as input
NOP ; BANKSEL no puede ser etiquetada
BANKSEL TRISB ; Select bank1
MOVLW b'11111101' ; Configure RB1 as output(b'11111101') 253
MOVWF TRISB ; Load code DDR en F86
NOP ; BANKSEL no puede ser etiquetada
BANKSEL TRISC ; Select bank1
MOVLW b'10111111' ; Configure RC6 as output and RC7 as input(b'01111111') 127
MOVWF TRISC ; Carga el codigo DDR en F87
NOP ; BANKSEL no puede ser etiquetada
BANKSEL TRISD ; Select bank1
MOVLW b'11111111' ; Configure PORTD as output(b'11111100') 252
MOVWF TRISD ; load DDR en F88
NOP ; BANKSEL no puede ser etiquetada
BANKSEL TRISE ; Select bank1
MOVLW b'00000000' ; bit4 a 0 to use portd as general port
MOVWF TRISE ;
MOVLW B'11000111' ; PRESCALER assigned to TMR0
MOVWF OPTION_REG
MOVLW B'10010000' ;INT PIN RB0
MOVWF INTCON
BANKSEL 0
; MOVLW B'00000000'
; MOVF DEMORA
GOTO Ppal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
INT
BTFSS INTCON, INTF
GOTO OTROCASO
BCF INTCON, INTE
MOVF DEMORA, W
MOVWF TMR0
BCF INTCON, T0IF
BSF INTCON, INTE
BACK
RETFIE
OTROCASO
BCF INTCON, INTE
MOVLW B'00000010' ; TRIGGERING TRIACS
MOVF PORTB
BCF INTCON, T0IF
BSF INTCON, INTE
GOTO BACK
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Programa principal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Ppal
CALL Capdat ; Adquiring data subroutine
CALL nivluz1 ; subroutine for managing delay for dimmer
CALL persia ; Acting on shades or blind
GOTO Ppal
;Subrutina de captura de datos.................................................
; getting data from LDR to manage light intensity
; Init conversion AD. Clock conversion 4MHz/32,AN4 Channel ON
; AN0,AD conversion OFF,AD module de conversion ON
Capdat
banksel ADCON0
movlw b'01000001' ; fosc 8, RA0 analogico
movwf ADCON0
; Incializacion convertidor AD. left-aligned, All PORTA as analog input
banksel ADCON1
movlw b'00001110' ;left-aligned, channel 0, module ON
movwf ADCON1
call Demora_20us ; Waiting adq time
; Starting conversion AD
banksel ADCON0
bsf ADCON0,2
; waiting for conversion end
espera
btfsc ADCON0,2
goto espera
; Writing value at reg named ls_adc.
banksel ADRESH
movf ADRESH,0 ; Working with ADRESH only
;
banksel ls_adc
movwf ls_adc ; valor en W Reg. se escribe en la variable ls_adc
RETURN
Demora_20us
movlw 0x05
movwf Contador ; init Contador for delay
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'11100101' ; load value to compare level with stimate 4,5V
SUBWF ls_adc,W ; compare ls_adc with ref value
BTFSC STATUS,Z ; If match run following line, opposite jump next line
GOTO dem10ms
BTFSS STATUS, C ; check bit to know if is greater or lesser
GOTO nivluz2 ; if lesser check following level
dem10ms
MOVLW b'11011001' ; load 217 on DEMORA, corresponding with 10ms forTMR0
MOVWF DEMORA ;
RETURN
nivluz2
MOVLW b'11001100' ; load value to compare level with stimate 4V
SUBWF ls_adc,W ; compare ls_adc with ref value
BTFSC STATUS,Z ; If match run following line, opposite jump next line
GOTO dem9ms
BTFSS STATUS, C ; check bit to know if is greater or lesser
GOTO nivluz3 ; if lesser check following level
dem9ms
MOVLW b'11000011' ; load 195 en DEMORA que corresponding with 9ms para el TMR0
MOVWF DEMORA ;
RETURN
nivluz3
MOVLW b'10110010' ; cargo valor a comparar nivel con 3.5V
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'10011001' ; cargo valor a comparar nivel con 3V
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'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 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'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 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'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 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'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 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 ;testing shade bit
GOTO luz ; If 1 I will check light state bit
GOTO oscuro ; If 0 I will check light state bit
luz
BTFSS estado, 3 ; testing shade bit
GOTO abrir ; If closed, then will open the shade
RETURN ; if it is openen, I do not anything
oscuro
BTFSS estado, 3 ; testeo bit de estado
RETURN ; if closed, nothing to do
GOTO cerrar ; If open, then will close the shade
abrir
BSF PORTD,0 ; writing 1 in RD0 to open
GOTO espera5s ; Waiting 5 seconds (stimate time) to let the shade be totaly opened
BCF PORTD,0 ; deactivate port D0
BSF estado,2 ; Updating flag bit estado to open
RETURN
cerrar
BSF PORTD,1 ; writing 1 por RD1 to close
GOTO espera5s ; Waiting 5 seconds (stimate time) to let the shade be totaly opened
BCF PORTD,1 ; deactivate port D1
BCF estado,2 ; Updating flag bit estado to close
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