'****************************************************************
'* Name : lluvia_LED.BAS *
'* Author : prof.martintorres@educ.ar *
'* Notice : Copyright (c) 2018 ETI (EducacionTecnicaInformal) *
'* : All Rights Reserved *
'* Date : 19/12/2018 *
'* Version : 1.B (microMASTER&SLAVE+HPWM ALLinONE) *
'* Notes : segunda version de la cortina de gotas con control*
'* : de velocidad de desplazamiento CARRYOUT-IN y fade*
'****************************************************************
INCLUDE "MODEDEFS.BAS"
@ DEVICE xt_OSC
DEFINE OSC 4
'****************************************************************
'CONFIGURACION I/O DE PUERTOS
DEFINE CCP1_REG PORTC
DEFINE CCP1_BIT 2
Define ADC_BITS 8 ' Establece el número de bits en el resultado
Define ADC_CLOCK 2 ' Ajuste el reloj de origen (rc=2)
Define ADC_SAMPLEUS 50 ' Establezca el tiempo de muestreo en uS
INTCON=%10100001
TMR0=0
T2CON = %00000110
PR2=124
CMCON=7
ADCON1 = 4 ;PortA 0, 1, 4 entradas A/D
TRISB=%00000011
TRISC=%00000000
TRISD=%11000000
'PIN HARDWARE PIC16F877A
J_MODE VAR PORTD.7
CARRY_IN VAR PORTD.6 'ENTRADA CARRY
CARRY_OUT VAR PORTC.1 'SALIDA CARRY
B_MAS VAR PORTB.0 'PULSADOR QUE INCREMENTA VELOCIDAD
B_MENOS VAR PORTB.1 'PULSADOR QUE DECREMENTA VELOCIDAD
'CI2_71LS164-PIC16F877A
CLEAR_2 VAR PORTB.2 'RESET_CI2
CLOCK_2 VAR PORTB.3 'CLOCK_CI2
DATA_2 VAR PORTB.4 'DATO_CI2
'CI3_71LS164-PIC16F877A
CLEAR_3 VAR PORTB.5 'RESET_CI3
CLOCK_3 VAR PORTB.6 'CLOCK_CI3
DATA_3 VAR PORTB.7 'DATO_CI3
'CI4_71LS164-PIC16F877A
CLEAR_4 VAR PORTC.0 'RESET_CI4
CLOCK_4 VAR PORTC.3 'CLOCK_CI4
DATA_4 VAR PORTC.4 'DATO_CI4
'CI5_71LS164-PIC16F877A
CLEAR_5 VAR PORTC.5 'RESET_CI5
CLOCK_5 VAR PORTC.6 'CLOCK_CI5
DATA_5 VAR PORTC.7 'DATO_CI5
'CI6_71LS164-PIC16F877A
CLEAR_6 VAR PORTD.0 'RESET_CI6
CLOCK_6 VAR PORTD.1 'CLOCK_CI6
DATA_6 VAR PORTD.2 'DATO_CI6
'CI7_71LS164-PIC16F877A
CLEAR_7 VAR PORTD.3 'RESET_CI7
CLOCK_7 VAR PORTD.4 'CLOCK_CI7
DATA_7 VAR PORTD.5 'DATO_CI7
'variables del PROGRAMA DEL DESPLAZADOR REGISTRO
AUX1 VAR BYTE ;VARIABLE AUXILIAR PARA CONTEO
AUX2 VAR BYTE ;VARIABLE AUXILIAR PARA GENERAR RETARDOS
DATO1 VAR BYTE
DATO2 VAR BYTE
DATO3 VAR BYTE
DATO4 VAR BYTE
DATO5 VAR BYTE
DATO6 VAR BYTE
DATO7 VAR BYTE
'variables del PROGRAMA DEL PWM POR HARDWARE (pwm en segundo plano)
PRVAR var byte
DUTYVAR var byte
AUX4 VAR BYTE
AUX3 VAR BYTE
DUTY VAR BYTE
I VAR WORD
HAM_DUTY VAR WORD
W VAR BYTE
NIVEL_FREC VAR BYTE
FRECUENCIA VAR WORD
PORTA = 0
PORTB = 0
PORTC = 0
PORTD = 0
AUX1 = 0
AUX2 = 500
CLOCK_2=1
CLOCK_3=1
CLOCK_4=1
CLOCK_5=1
CLOCK_6=1
CLOCK_7=1
ON INTERRUPT GoTo ATENCION
'****************************************************************
'****************************************************************
ARRANQUE:
IF J_MODE = 0 THEN ;SI LA ENTRADA DEL JUMPER "MODO DE TRABAJO" ESTA EN "0" ENTONCES...
GOTO INICIO_MASTER ; IR AL PROGRAMA INICIO COMO MAESTRO
ELSE ;SI NO, CASO CONTRARIO...
GOTO INICIO_ESCLAVO ; IR AL PROGRAMA INICIO COMO ESCLAVO
ENDIF ;FIN DE SENTENCIA CONDICIONAL
GOTO ARRANQUE ;IR AL PROGRAMA ARRANQUE
'****************************************************************
'****************************************************************
INICIO_ESCLAVO: ; PROGRAMA EN MODO ESCLAVO
IF CARRY_IN = 0 THEN INICIO_MASTER ; ESPERA TENER LA SEÑAL EN EL PERTO CARRY IN PARA INICIAR
GOTO INICIO_ESCLAVO ;IR AL PROGRAMA MODO ESCLAVO
'****************************************************************
'****************************************************************
INICIO_MASTER:
IF B_MENOS = 0 THEN ;SI EL PULSADOR "MENOS" ESTA CERRADO, ENTONCES...
WHILE B_MENOS = 0 : WEND ;ESTA RUTINA ES PARA TENER UN ANTIREBOTE QUE SOLO SIGUE SI SOLTAS EL PULSADOR
AUX2= AUX2 - 50 ; VARIABLE AUX2 ES IGUAL A VARIABLE AUX2 MENOS 50
IF AUX2 < 50 THEN AUX2 = 50 ; SI EN LA RESTA EL RESULTADO DE AUX2 ES MENOR A 50, PONER EL VALOR DE AUX2 EN 50
endif ;FIN DE SENTENCIA CONDICIONAL
IF B_MAS = 0 THEN ;SI EL PULSADOR "MAS" ESTA CERRADO, ENTONCES...
WHILE B_MAS = 0 : WEND ;ESTA RUTINA ES PARA TENER UN ANTIREBOTE QUE SOLO SIGUE SI SOLTAS EL PULSADOR
AUX2= AUX2 + 50 ; VARIABLE AUX2 ES IGUAL A VARIABLE AUX2 MAS 50
IF AUX2 >1500 THEN AUX2 = 1500 ; SI EN LA SUMA EL RESULTADO DE AUX2 ES MEYOR A 1500, PONER EL VALOR DE AUX2 EN 1500
endif ;FIN DE SENTENCIA CONDICIONAL
AUX1 = AUX1 + 1 ; bucle para incrementar la variable y seleccionar el caso a accionar...o sea,
IF AUX1 > 8 THEN AUX1 = 1 ;cada vez que se cumple el ciclo del programa "inicio_master" la variable AUX1
GOSUB fadeLED ;se incrementa en una unidad y abajo, hay una lista con valores de 1 a 8
Select Case AUX1 ;Seleccionar caso segun el valor de la variable... tambien se establece que si
;el valor de la suma supera 8, la variable se reinicia y le ponemos un valor de 1
Case 1 ; si el resultado del caso es "1", entonces...
GOSUB BUCLE1 ; ir al subprograma bucle1
Case 2 ; si el resultado del caso es "2", entonces...
GOSUB BUCLE2 ; ir al subprograma bucle2
Case 3 ; si el resultado del caso es "3", entonces...
GOSUB BUCLE3 ; ir al subprograma bucle3
Case 4 ; si el resultado del caso es "4", entonces...
GOSUB BUCLE4 ; ir al subprograma bucle4
Case 5 ; si el resultado del caso es "5", entonces...
GOSUB BUCLE5 ; ir al subprograma bucle5
Case 6 ; si el resultado del caso es "6", entonces...
GOSUB BUCLE6 ; ir al subprograma bucle6
Case 7 ; si el resultado del caso es "7", entonces...
GOSUB BUCLE7 ; ir al subprograma bucle7
Case 8 ; si el resultado del caso es "8", entonces...
GOSUB BUCLE8 ; ir al subprograma bucle8
End Select ; fin de seleccion de casos
GOTO INICIO_MASTER ; IR AL PROGRAMA INICIO_MASTER
'****************************************************************
'****************************************************************
' Subprogramas
'****************************************************************
PIN_CLEAR_I:
HIGH CLEAR_2 : HIGH CLEAR_3 : HIGH CLEAR_4 ;EN ESTE SUBPROGRAMA LO QUE HACEMOS ES PONER EN ESTADO ALTO LOS PINES
HIGH CLEAR_5 : HIGH CLEAR_6 : HIGH CLEAR_7 ;QUE ESTAN CONECTADOS A "CLEAR"
RETURN
PIN_CLEAR_O:
low CLEAR_2 : low CLEAR_3 : low CLEAR_4 ;EN ESTE SUBPROGRAMA LO QUE HACEMOS ES PONER EN ESTADO BAJO LOS PINES
Low CLEAR_5 : low CLEAR_6 : low CLEAR_7 ;QUE ESTAN CONECTADOS A "CLEAR"
RETURN
IMPRIMIR:
shiftout DATA_2,CLOCK_2,MSBFIRST,[DATO2] ;EN ESTE SUBPROGRAMA LO QUE HACEMOS ES ENVIAR LA VARIABLE "DATOX" EN FORMA DE UNOS
shiftout DATA_3,CLOCK_3,MSBFIRST,[DATO3] ;Y CEROS O PULSOS,POR LOS PINES "DATA_X" DEL MICROCONTROLADOR A LOS DISTINTOS CI.
shiftout DATA_4,CLOCK_4,MSBFIRST,[DATO4]
shiftout DATA_5,CLOCK_5,MSBFIRST,[DATO5]
shiftout DATA_6,CLOCK_6,MSBFIRST,[DATO6]
shiftout DATA_7,CLOCK_7,MSBFIRST,[DATO7]
PAUSE AUX2
RETURN
BUCLE1:
GOSUB PIN_CLEAR_I ; IR AL SUBPROGRAMA "PIN_CLEAR_I", EJECUTAR Y VOLVER (PONE EN ALTO EL PIN CLEAR DEL IC)
DATO2=%00000001 ; EN ESTA SECCION, CONFIGURAMOS LAS VARIABLES DE 8BITS "DATOSX", CON UN VALOR QUE
DATO3=%00000100 ; LUEGO NOS SERVIRA COMO MAPA O DIRECCION EN EL DESPLAZADOR DE REGISTROS PARA
DATO4=%00000010 ; ENCENDER O APAGAR UNA SALIDA DETERMINADA...UNO SIGNIFICA ACTIVAR, UN CERO APAGAR.
DATO5=%00001000 ; POR EJEMPLO, EL VALOR%00000010, SE INTERPRETA DE LA SIGUIENTE MANERA, DE DERECHA
DATO6=%00000100 ; A IZQUIERDA, O SEA, SALIDA7,SALID6,SAL5,S4,S3,S2,S1,S0...DICHO EN OTRAS PALABRAS
DATO7=%00000001 ; EL VALOR%00000010 SERIA SALIDA1 ACTIVADA, EL RESTO APAGADAS...
GOSUB IMPRIMIR ; IR AL SUBPROGRAMA QUE ENVIA LA VARIABLE POR EL PIN DE COMUNICACION ENTRE PIC e IC
GOSUB PIN_CLEAR_O ; IR AL SUBPROGRAMA "PIN_CLEAR_0", EJECUTAR Y VOLVER (PONE EN BAJO EL PIN CLEAR DEL IC)
RETURN
BUCLE2:
GOSUB PIN_CLEAR_I
DATO2=%00000010
DATO3=%00001000
DATO4=%00000100
DATO5=%00010000
DATO6=%00001000
DATO7=%00000010
GOSUB IMPRIMIR
GOSUB PIN_CLEAR_O
RETURN
BUCLE3:
GOSUB PIN_CLEAR_I
DATO2=%00000100
DATO3=%00010000
DATO4=%00001000
DATO5=%00100000
DATO6=%00010000
DATO7=%00000100
GOSUB IMPRIMIR
GOSUB PIN_CLEAR_O
RETURN
BUCLE4:
GOSUB PIN_CLEAR_I
DATO2=%00001000
DATO3=%00100000
DATO4=%00010000
DATO5=%01000000
DATO6=%00100000
DATO7=%00001000
GOSUB IMPRIMIR
GOSUB PIN_CLEAR_O
RETURN
BUCLE5:
GOSUB PIN_CLEAR_I
DATO2=%00010000
DATO3=%01000000
DATO4=%00100000
DATO5=%10000000
DATO6=%01000000
DATO7=%00010000
GOSUB IMPRIMIR
GOSUB PIN_CLEAR_O
RETURN
BUCLE6:
GOSUB PIN_CLEAR_I
DATO2=%00100000
DATO3=%10000000
DATO4=%01000000
DATO5=%00000001
DATO6=%10000000
DATO7=%00100000
GOSUB IMPRIMIR
GOSUB PIN_CLEAR_O
RETURN
BUCLE7:
GOSUB PIN_CLEAR_I
DATO2=%01000000
DATO3=%00000001
DATO4=%10000000
DATO5=%00000010
DATO6=%00000001
DATO7=%01000000
GOSUB IMPRIMIR
GOSUB PIN_CLEAR_O
RETURN
BUCLE8:
GOSUB PIN_CLEAR_I
DATO2=%10000000
DATO3=%00000010
DATO4=%00000001
DATO5=%00000100
DATO6=%00000010
DATO7=%10000000
GOSUB IMPRIMIR
GOSUB PIN_CLEAR_O
HIGH CARRY_OUT ;COMO ESTE ES EL ULTIMO BUCLE, PARA SINCRONIZAR EL RESTO DE LOS ESCLAVOS
PAUSE 100 ;LE ENVIAMOS UNA SEÑAL QUE ESTARA EN ALTO POR 100 MILISEGUNDOS POR EL CARRI_OUT
LOW CARRY_OUT ;Y LUEGO SE PONDRA EN ESTADO BAJO...
RETURN ;VOLVER DE DONDE VINE
'****************************************************************
'****************************************************************
fadeLED:
GOSUB CALCULO_FRECUENCIA
GOSUB SET_DUTY
if duty > 0 then duty= 0
pr2=124
GOSUB CALCULO_FRECUENCIA
GOSUB PWM_ON
GOSUB DUTY_CONTROL
GOSUB FREC_CONTROL
RETURN
;*********************************************************
;*********************************************************
FREC_CONTROL:
ADCON0 = $41
PAUSEUS 50
ADCON0.2 = 1
WHILE ADCON0.2
WEND
PR2 = ADRESH
GOSUB CALCULO_FRECUENCIA : gosub SET_DUTY
IF PR2<5 THEN PR2=5
IF PR2>255 THEN PR2=255
RETURN
;*********************************************************
DUTY_CONTROL:
IF B_MAS =0 THEN
AUX3=0
DUTY=DUTY+1
IF DUTY=101 THEN DUTY=100
gosub SET_DUTY
;WHILE B_MAS=0
W=1
IF AUX3=>50 THEN
W=0:AUX3=50
DUTY=DUTY+1:GOSUB DELAY
IF DUTY=101 THEN DUTY=100
ENDIF
GOSUB SET_DUTY
;WEND
W=0:AUX3=0
ELSE
W=0:AUX3=0
ENDIF
IF B_MENOS=0 THEN
AUX3=0
DUTY=DUTY-1
IF DUTY=255 THEN DUTY=0
GOSUB SET_DUTY
;WHILE B_MENOS=0
W=1
IF AUX3=>30 THEN
W=0:AUX3=30
DUTY=DUTY-1:GOSUB DELAY
IF DUTY=255 THEN DUTY=0
ENDIF
GOSUB SET_DUTY
;WEND
W=0
ELSE
W=0:AUX3=0
ENDIF
RETURN
;*********************************************************
DUTY_NEG_SET:
DUTY=DUTY-1:GOSUB DELAY
IF DUTY>100 THEN
GOTO DUTY_POS_SET
ENDIF
GOSUB SET_DUTY
GOTO DUTY_NEG_SET
DUTY_POS_SET:
DUTY=DUTY+1:GOSUB DELAY
GOSUB SET_DUTY
IF DUTY=AUX4 THEN
GOTO INICIO_MASTER
ENDIF
GOTO DUTY_POS_SET
SL:
DUTY=DUTY-1:GOSUB DELAY
IF DUTY>100 THEN
GOTO DUTY_POS_SET
ENDIF
GOSUB SET_DUTY
GOTO SL
DELAY:
FOR I=0 TO 255:NEXT
RETURN
DELAY1:
FOR I=0 TO 150:NEXT
RETURN
CALCULO_FRECUENCIA:
FRECUENCIA=62500/(PR2+1) ;FRECUENCIA=62500/(PR2+1) = 500Hz
RETURN
SET_DUTY:
IF PR2<5 THEN PR2=5
IF PR2>255 THEN PR2=255
HAM_DUTY=(PR2+1)*DUTY/25
CCP1CON.4=ham_DUTY.0
CCP1CON.5=HAM_DUTY.1
CCPR1L=HAM_DUTY>>2
return
PWM_ON:
CCP1CON.2=1
CCP1CON.3=1
RETURN
PWM_OFF:
CCP1CON.2=0
CCP1CON.3=0
low PORTC.1 : low PORTC.2
RETURN
;*****************************************************************
;++++++++++++++++++++++++ INTERRUPCION +++++++++++++++++++++++++++
;*****************************************************************
DISABLE
ATENCION:
IF W=1 THEN
AUX3=AUX3+1
IF AUX3=101 THEN AUX3=0
ENDIF
INTCON.2=0
RESUME
ENABLE
END
;*****************************************************************
;*****************************************************************