H:\Archivos de programa\PIC Simulator IDE\Proyectos\Pic12F675 TWC\12F675_TWC_14.bas '******************************* WWW.PICKEY.ES ****************************************** '**************************************************************************************** 'NOMBRE: 12F675_TWC_14 'MICRO: PIC12F675 'LENGUAJE: Basic del PSI 'DESCRIPCION: Automatismo para el control de ventilador WC, detección por entrada digital 'AUTOR: By COS (dogflu66, www.pickey.es, [email protected]) 'FECHA: 09/06, 10/06, 05/08, 11/10 '**************************************************************************************** 'Versión 1.4: Actualizado a la versión actual del PSI 'Versión 1.2: Se añade el calibrado de fabrica del clock mediante el registro osccal 'Versión 1.1: soft, Ver. 1.1: hard, compatible ver. 1.0 de soft con ver. 1.1 de hard 'Cambio del soft para detectar perdida de alimentacion en la lampara por entrada digital 'Simplificación del disparo del rele 'Modificación del sistema de control de las salidas 'Se activa el WDT 'Version 1.0: 'Calibrado oscilador interno 'Relé controlado por dos pin 'Detección de perdida de red por entrada analogica '**************************************************************************************** '/* _CPD_OFF, _CP_OFF, _BODEN_ON, _MCLRE_OFF,_PWRTE_ON, _WDT_ON, _INTRC_OSC_NOCLKOUT Define CONF_WORD = 0x31cc '*/ Define CLOCK_FREQUENCY = 4 'Reloj a 4000000Mhz '**************************************************************************************** '*** Asignación de nombres a pin *** Symbol ledrojo = GP4 'False led On Symbol ledverde = GP5 'False = led On Symbol rele = GP0 'True = rele On Symbol red = GP2 'True = hay red '***Definición de constantes *** Const ledon = 0 'Led a ON Const ledoff = 1 'Led a OFF Const releon = 1 'Rele a ON Const releoff = 0 'Relé a OFF Const redon = 1 'Alimentación ON Const redoff = 0 'Alimentación a OFF '*** Declaracion de variables Globales *** Dim fase As Byte 'Variable que controla la fase en la que se encuentra el programa '*** Asignación de valores a las variables *** fase = 0 'Establece la fase cero del programa main '*** Inicializacion de registros generales y de E/S *** VRCON = 0x00 'Vref off(power off the comparator voltage) CMCON = 0x07 'Comparator off ANSEL = 0x00 'Off ADC 'OSCCAL = 48 'Diferente para cada micro TRISIO = 0x00 'Tri-state pins, are outputs GPIO = 0x00 'Clear port TRISIO.2 = 1 'GP2 pin, is input GPIO.1 = 0 'Compatibilidad con la ver. 1.0 de hard rele = releoff 'Rele a Off ledrojo = ledoff 'Led a Off ledverde = ledoff 'Led a Off Call loadosccal() 'Carga el valor de OSCCAL del fabricante WaitUs 10000 Call Call Call Call Call Call clrwdt(1) _timer(0, _timer(0, _timer(0, _timer(1, _timer(1, Enable 'Pausa para estabilizar 'Se inicializa WDT 0, 0xfc18, %1) 'Inicializa bases de tiempos, recarga tmr1. 0, 0, %0010) 'Reset al timer x, activa timer x 3000, 0, %0100) 'Recarga el timer x con y, 30Seg, pasos de 10mSeg. 0, 0, %0010) 'Reset al timer x, activa timer x 500, 0, %0100) 'Recarga el timer x con y, 0.5Seg, pasos de 1mSeg. 'INTCON.GIE habilita las interrupciones generales Call ctrled(%10010) 'Parpadeo led rojo '*** Rutina del programa *** main: Call clrwdt(0) 'Reset al contador TMR0 asociado al WDT '/* Espera 30Seg: permite fase 1, parpadeo led verde, relé a OFF If fase = 0 Then 'Primera fase del control de tiempos y maniobras If _timer.0 = 1 Then 'Si pasan los primeros 30Seg. fase = 1 'Permite la siguiente fase Call ctrled(%11000) 'Parpadeo led verde rele = releoff 'Relé a OFF EndIf EndIf '*/ Page 1 of 2 (c) www.pickey.es - [email protected] 1 28/11/2010 3:13 H:\Archivos de programa\PIC Simulator IDE\Proyectos\Pic12F675 TWC\12F675_TWC_14.bas '/* Si Red esta a OFF: permite fase 2, timer con 120Seg., led sincronizados, relé ON If fase = 1 Then 'Segunda fase del control de tiempos y maniobras If _timer.0 = 1 Then 'Si la base de tiempos timer.0 termino de contar If GPIO.2 = redoff Then 'Si alimentación fuente es igual a OFF fase = 2 'Permite la siguiente fase Call _timer(0, 12000, 0, %0100) 'Recarga el timer x con y'120Seg 2minutos _timer.0 = 0 'Activa la base de tiempos Call ctrled(%11010) 'Sincronizados rele = releon 'Relé a ON EndIf EndIf EndIf '*/ '/* Carga pausa de 1Seg., permite fase 1, activa led alternos, rele a OFF. If fase = 2 Then 'Fase del control de tiempos y maniobras If _timer.0 = 1 Then 'Cuando pasan los 120seg. fase = 1 'Se cambia de fase Call _timer(0, 100, 0, %0100) 'Recarga el timer x con y, 1Seg. _timer.0 = 0 'Reset a la base de tiempos.0 rele = releoff 'Relé a OFF Call ctrled(%11011) 'Parpadeo led alternos EndIf EndIf '*/ If _timer.1 = 1 Then '/*Control parpadeo led 50% de 1Seg. _timer.1 = 0 'Reset al timer.1 Call ctrled(%00000) 'Control led EndIf '*/ GoTo main End '*** Subrutinas *** Include "_ProcLoadOSCCAL.bas" 'Calibra el reloj Include "_ProcClrWdt.bas" 'Controla el WDT Include "_ProcCtrLed.bas" 'Control de los led Include "_FunctionTimer.bas" 'Añade bases de tiempos On Interrupt 'Comienzan las rutinas de las interrupciones, desactiva interrupciones Save SYSTEM 'Guarda los valores del sistema If PIR1.TMR1IF = 1 Then 'Interrupcion activa Call _timer(0, 0, 0, %0) 'Actualización de los timer PIR1.TMR1IF = 0 'Borra el flag de salto del tmr1 EndIf Resume 'Activa las interrupciones y retorna al programa Page 2 of 2 (c) www.pickey.es - [email protected] 2 28/11/2010 3:13 H:\Archivos de programa\PIC Simulator IDE\Proyectos\Pic12F675 TWC\_ProcLoadOSCCAL.bas 'Include "_ProcLoadOSCCAL.bas" 'Carga el registro OSCCAL por el prefijado de fabrica 'Call loadosccal() Proc loadosccal() ASM: bsf status,rp0 ASM: Call 3ffh ASM: movwf osccal ASM: bcf status,rp0 End Proc Page 1 of 1 (c) www.pickey.es - [email protected] 3 28/11/2010 14:10 H:\Archivos de programa\PIC Simulator IDE\Proyectos\Pic12F675 TWC\_ProcClrWdt.bas 'Declaracion de variables control 'Include "_ProcClrWdt.bas" 'Call clrwdt(1) 'Se inicializa 'Call clrwdt (0) 'Se llama 'Si se produce una bajada y de seguida una subida de voltaje, 'este suceso puede que no lo detecten los modulos de proteccion interna. 'Se corrompen los valores en la RAM y el sistema no se bloquea, sigue 'funcionando pero deja de hacer lo que debe correctamente. 'Cuando se corrompan los valoes de la Ram tambien se corromperan los 'valores de las variables de control (v0 a v4) y esto forzará un reset. Proc clrwdt(ini As Byte) 'Declaracion de variables de cotrol Dim v0 As Byte Dim v1 As Byte Dim v2 As Byte 'Dim v3 As Byte 'Dim v4 As Byte Const ctrl = %10101010 'Numero de control 170 If ini = 1 Then 'Configura WDT------------------------------------------------------------ASM: clrwdt 'reinicializa el WDT 'INTCON.TMR0IE = 0 'deshabilito interrupcion por el trm0 INTCON.T0IE = 0 'deshabilito interrupcion por el trm0 OPTION_REG.PSA = 1 'asigna el prescales al WDT (32,768mSeg. a 4Mhz) OPTION_REG.PS0 = 1 'bit de la seleccion del factor de division para el WDT OPTION_REG.PS1 = 1 'bit de la seleccion del factor de division para el WDT OPTION_REG.PS2 = 1 'bit de la seleccion del factor de division para el WDT OPTION_REG.T0CS = 0 'selecciona reloj interno para el WDT 'Inicializa variables control v0 = ctrl v1 = ctrl v2 = ctrl 'v3 = ctrl 'v4 = ctrl EndIf If v0 = ctrl And v1 = ctrl And v2 = ctrl Then ASM: clrwdt 'reinicializa el WDT EndIf End Proc Page 1 of 1 (c) www.pickey.es - [email protected] 4 28/11/2010 14:09 H:\Archivos de programa\PIC Simulator IDE\Proyectos\Pic12F675 TWC\_ProcCtrLed.bas '********************************************** '**** Recordar definir en el programa ********* 'Symbol ledrojo = GP4 'False led On ********** 'Symbol ledverde = GP5 'False = led On ******* '********************************************** '**** Esta rutina necesita ser asociada ******* '**** a una base de tiempos para el control *** '**** del parpadeo de los led ***************** '********************************************** 'Include "_ProcCtrLed.bas" 'Call ctrled(%11010) 'Configura parpadeo led sincronizados 'Call ctrled(%0xxxx) 'Ejecuta la configuración 'Tipo.0 = ON/OFF led rojo 'Tipo.1 = ON/OFF parpadeo led rojo 'Tipo.2 = ON/OFF led verde 'Tipo.3 = ON/OFF parpadeo led verde 'Tipo.4 = Configura estados 'Tipo.0 = Ejecuta la configuración Proc ctrled(tipo As Byte) Dim ctrl As Byte If tipo.4 = 1 Then ctrl = tipo ledrojo = Not tipo.0 'Estado led rojo ledverde = Not tipo.2 'Estado led verde EndIf If ctrl.1 = 1 Then Toggle ledrojo 'Parpadeo led rojo If ctrl.3 = 1 Then Toggle ledverde 'Parpadeo led verde End Proc Page 1 of 1 (c) www.pickey.es - [email protected] 5 28/11/2010 14:09 H:\Archivos de programa\PIC Simulator IDE\Proyectos\Pic12F675 TWC\_FunctionTimer.bas 'Include "_FunctionTimer.bas" 'Rutina bases de tiempos. 'Los timepos en pasos de 1mSeg/4Mhz = 0xFC18 'Los tiempos en pasos de 1mSeg/8Mhz = 0xF830. 'Los tiempos en pasos de 10mSeg/8Mhz = 0xB1E0. 'Los tiempos en pasos de 1mSeg/20Mhz = 0xEC78. 'Los tiempos en pasos de 10mSeg/20Mhz = 0x3CB0. 'Call _timer(0, 0, 0x3cb0, %1), Inicializa bases de tiempos, recarga TMR1. 'Call _timer(0, 0, 0, %0), Llamada normal a la rutina despues incializacion. 'Call _timer(x, 0, 0, %0010), Reset al timer x, activa timer x 'Call _timer(x, y, 0, %0100), Recarga el timer x con y 'Call _timer(0, 0, 0x3cb0, %1000), Recarga la base de tiempos del TMR1 'Los flag de los timer son: _timer.0... _timer.7 'tmr1hl = tiempo desborde timer1, Init = 0 incializa la rutina, no activa los timer. 'Hay que incluir el progra las siguietnes lineas: 'Enable 'INTCON.GIE = 1, Hay que recordar insertarlo en el codigo fuente. 'y rutina interrupciones (On interrupt). Function _timer(tmr_n As Byte, tmr_tp As Word, tmr1hl As Word, init As Byte) As Word Dim tmr_on As Word '/*Declaracion de contadores y variables auxiliares Dim base As Word Dim tmrhb As Byte Dim tmrlb As Byte Dim x As Word Dim x1 As Byte Dim _tmr(3) As Word Dim _tmr_tm(3) As Word '*/ If init > 0 Then Disable If init.0 = 1 Then 'Inicaliza variables y registros del TMR1 _timer = 0 tmr_on = 0 base = 0 For x = 0 To 2 _tmr(x) = 0 _tmr_tm(x) = 0 Next x TMR1H = tmr1hl.HB '0x3c, carga el byte alto del regis. TMR1 (1mSeg) a 8Mhz TMR1L = tmr1hl.LB '0xb0, carga el byte bajo del regis. TMR1 (1mSeg) a 8Mhz T1CON.TMR1CS = 0 'Bit de seleccion de reloj para el TMR1, interno Fosc/4 T1CON.T1CKPS0 = 0 'Bit de seleccion del prescaler para el reloj del TMR1 T1CON.T1CKPS1 = 0 'Bit de seleccion del prescaler para el reloj del TMR1 T1CON.TMR1ON = 1 'Activa el contador del TMR1 PIE1.TMR1IE = 1 'Activa las interrupciones del TMR1 INTCON.PEIE = 1 'Habilitacion de interrupciones de perifericos EndIf If init.3 = 1 Or init.0 = 1 Then tmrhb = tmr1hl.HB tmrlb = tmr1hl.LB EndIf 'Valor de carga contador TMR1 If init.2 = 1 Then 'Recarga tiempo tope timer _tmr_tm(tmr_n) = tmr_tp EndIf If init.1 = 1 Then 'Inicializa los timer 'Activa el timer seleccionado x = %0000000000000001 'Valor de entrada x = ShiftLeft(x, tmr_n) 'Corre el bit, para seleccionar timer tmr_on = tmr_on Or x '=1, Iguala a 1 el bit seleccionado 'Resetea el timer seleccinado x1 = tmr_n 'Numero de bits a desplazar x = %1111111111111110 'Valor de entrada While x1 > 0 'Bucle de seleccion de bit x = ShiftLeft(x, 1) 'Corre el bit, para seleccionar timer x.0 = 1 'Rellena los huecos con 1 x1 = x1 - 1 'Contador, hasta llegar al bit seleccionado Wend _timer = _timer And x '=0, Iguala a cero el bit seleccionado _tmr(tmr_n) = 0 'Borra contador seleccionado EndIf Enable EndIf 'Control de los contadores de los timer If init = 0 Then 'Si se hace la llamada desde las interrupciones TMR1H = tmrhb '0x3c, carga el byte alto del regis. tiemr1 (100mSeg) a 8Mhz TMR1L = tmrlb '0xb0, carga el byte bajo del regis. timer1 (100mSeg) a 8Mhz If _timer.0 = 0 And tmr_on.0 = 1 Then Page 1 of 2 'Control base tiempos timer.0 / 10 (c) www.pickey.es - [email protected] 6 28/11/2010 14:09 H:\Archivos de programa\PIC Simulator IDE\Proyectos\Pic12F675 TWC\_FunctionTimer.bas base = base + 1 If base >= 10 Then base = 0 _tmr(0) = _tmr(0) + 1 'Incrementa el contador If _tmr(0) >= _tmr_tm(0) Then 'Comprueba el tope del contaje _timer.0 = 1 'Para el contador e indica que termino _tmr(0) = 0 'Prepara un nuevo contaje EndIf EndIf EndIf If _timer.1 = 0 And tmr_on.1 = 1 Then 'Control base tiempos timer.1 _tmr(1) = _tmr(1) + 1 'Incrementa el contador If _tmr(1) >= _tmr_tm(1) Then 'Comprueba el tope del contaje _timer.1 = 1 'Para el contador e indica que termino _tmr(1) = 0 'Prepara un nuevo contaje EndIf EndIf EndIf End Function Page 2 of 2 (c) www.pickey.es - [email protected] 7 28/11/2010 14:09