Sunteți pe pagina 1din 8

; ZONA DE DATOS ********************************************************************** LIST INCLUDE __CONFIG P=16F877A <P16F877A.

INC> _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC ; Guarda las horas. ; Guarda los minutos. ; Guarda los segundos. ; Incrementa cada medio segundo. ; Incrementa cada 50 ms ; Para lograr la intermitencia. ; Guarda los flags para ; ajustes de hora y minuto. PORTB,7 PORTB,6 FlagsAjuste,1 ; Los pulsadores se ; pines del Puerto B. ; Flags utilizados en la

CBLOCK 0x0C Hora Minuto Segundo MedioSegundo Registro50ms Intermitencia FlagsAjuste establecer los ENDC ; #DEFINE ModoPulsador conectan a estos #DEFINE IncrementarPulsador #DEFINE F_AjusteHora puesta en hora. #DEFINE F_AjusteMinuto #DEFINE F_Intermitencia intermitencia. TMR0_Carga50ms EQU interrupcin del

FlagsAjuste,0 Intermitencia,0 ; Si es 0, apaga en d'256'-d'195' ; Para conseguir la

; Timer 0 cada 50 ms. ; ZONA DE CDIGOS ******************************************************************** ORG goto ORG goto 0 Inicio 4 ServicioInterrupcion

Mensajes addwf PCL,F MensajePublicitario DT " Shopper fish.", 0x00 Inicio call movlw call bsf movlw habilita movwf Puerto B. bsf entrada. LCD_Inicializa MensajePublicitario LCD_Mensaje STATUS,RP0 b'00000111' OPTION_REG ModoPulsador

; Acceso al Banco 1. ; Prescaler de 256 para el TMR0 y ; resistencias de Pull-Up del ; Configurados como

bsf IncrementarPulsador bcf STATUS,RP0 ; Acceso al Banco 0. clrf FlagsAjuste ; Inicializa todos los flags de la puesta en hora. clrf Hora ; Inicializa todos los datos del reloj. clrf Minuto clrf Segundo clrf MedioSegundo clrf Registro50ms movlw TMR0_Carga50ms ; Carga el TMR0. movwf TMR0 movlw b'10101000' ; Activa interrupcin del TMR0 (TOIE), por cambio movwf INTCON ; lneas del Puerto B (RBIE) y la general (GIE). call PuestaEnHoraReset ; Puesta en hora por primera vez. ; La seccin "Principal" es mantenimiento. Slo espera las interrupciones. ; No se puede poner en modo de bajo consumo porque la instruccin "sleep" detiene el Timer 0. Principal goto Principal

; Subrutina "ServicioInterrupcion" -----------------------------------------------------; ; Detecta qu ha producido la interrupcin y ejecuta la subrutina de atencin correspondiente. ServicioInterrupcion btfsc INTCON,T0IF procedente del call Reloj actualiza el reloj. btfss INTCON,RBIF los pulsadores. goto FinInterrupcion btfss ModoPulsador "MODO"? call PuestaEnHora btfss IncrementarPulsador call Incrementar registro de tiempo FinInterrupcion bcf INTCON,RBIF bcf INTCON,T0IF retfie ; Si es una interrupcin ; desbordamiento del Timer 0, ; Si es una interrupcin RBI, lee ; Est presionado el pulsador de ; S, pasa a poner en hora. ; Pulsado "INCREMENTAR"?. ; S, pasa a incrementar el ; correspondiente.

; Subrutina "Reloj" --------------------------------------------------------------------;

; Esta subrutina actualiza los contadores Horas, Minutos, Segundos y Registro50ms. ; Se ejecuta debido a la peticin de interrupcin del Timer 0 cada 50 ms. ; ; Como el PIC trabaja a una frecuencia de 4 MHz, el TMR0 evoluciona cada s y se desborda cada ; 195 x 256 = 49920 s. Sumdole el retardo de 71 s y el pequeo tiempo de los saltos ; iniciales y de carga del contador, resulta un total de 50000 s exactos. Es decir, el ; TMR0 producir una interrupcin cada 50 ms exactos, comprobado experimentalmente con la ; ventana Stopwatch del simulador del MPLAB. Reloj call Retardo_50micros ; Retardo de 71 microsegundos para call Retardo_20micros ; ajustar a 50 milisegundos exactos. nop movlw TMR0_Carga50ms ; Carga el Timer 0. movwf TMR0 call IncrementaRegistro50ms btfss STATUS,C ; Ha contado 10 veces 50 ms = 1/2 segundo? goto FinReloj ; No. Pues sale sin visualizar el reloj. ; Si est en "ModoAjusteHora", o "ModoAjusteMinuto" conmuta el flag de intermitencia y ; salta a visualizar el reloj. ; movf FlagsAjuste,F btfsc STATUS,Z goto IncrementaReloj movlw b'00000001' ; Conmuta el flag F_Intermitencia cada 500 ms. xorwf Intermitencia,F goto ActualizaReloj ; Visualiza el reloj y sale. IncrementaReloj bsf F_Intermitencia ; Se mantendr siempre encendido durante call IncrementaMedioSegundo ; el funcionamiento normal. btfss STATUS,C ; Ha pasado 1 segundo? goto ActualizaReloj ; No. Pues sale visualizando el reloj. call IncrementaSegundos ; S. Incrementa el segundero. btfss STATUS,C ; Han pasado 60 segundos? goto ActualizaReloj ; No. Pues sale visualizando el reloj. call IncrementaMinutos ; S. Incrementa el minutero. btfss STATUS,C ; Han pasado 60 minutos? goto ActualizaReloj ; No. Pues sale visualizando el reloj. call IncrementaHoras ; S. Incrementa las horas. ActualizaReloj

call VisualizaReloj FinReloj return

; Visualiza el reloj.

; Subrutina "VisualizaReloj" -----------------------------------------------------------; ; Visualiza el reloj en la segunda lnea en formato: " 8:47:39". ; Cuando se ajusta una variable, sta debe aparecer en intermitencia. Para ello, utiliza ; el flag F_Intermitencia que conmuta cada 500 ms en la subrutina Reloj. ; VisualizaReloj movlw .4 ; Para centrar visualizacin call LCD_PosicionLinea2 ; en la segunda lnea. btfss F_AjusteHora ; Est en la puesta en hora? goto EnciendeHoras ; No. Visualizacin normal. btfss F_Intermitencia ; S. Intermitencia si procede. goto ApagaHoras ; Apaga las horas en la intermitencia. EnciendeHoras movf Hora,W ; Va a visualizar las horas. call BIN_a_BCD ; Lo pasa a BCD. call LCD_Byte ; Visualiza rechazando cero de las decenas. goto VisualizaMinutos ApagaHoras call LCD_DosEspaciosBlancos ; Visualiza dos espacios en blanco. ; VisualizaMinutos movlw ':' ; Enva ":" para separar datos. call LCD_Caracter btfss F_AjusteMinuto ; Est en la puesta en hora?. goto EnciendeMinutos btfss F_Intermitencia goto ApagaMinutos EnciendeMinutos movf Minuto,W ; Visualiza minutos. call BIN_a_BCD ; Lo pasa a BCD. call LCD_ByteCompleto goto VisualizaSegundos ApagaMinutos call LCD_DosEspaciosBlancos ; Visualiza dos espacios en blanco. ; VisualizaSegundos movlw ':' ; Enva ":" para separar datos. call LCD_Caracter movf Segundo,W ; Visualiza segundos. call BIN_a_BCD ; Lo pasa a BCD. call LCD_ByteCompleto

return ; ; Subrutina "Incrementar" --------------------------------------------------------------; ; Subrutina de atencin a la interrupcin por cambio de la lnea RB6 al cual se ha conectado ; el pulsador "INCREMENTAR". Incrementa segn corresponda una sola de las variables. Incrementar call Retardo_20ms de tensin. btfsc IncrementarPulsador goto FinIncrementar bsf F_Intermitencia mientras incrementa. btfsc F_AjusteHora call IncrementaHoras btfsc F_AjusteMinuto call IncrementaMinutos call VisualizaReloj deje call Retardo_200ms btfss IncrementarPulsador goto Incrementar FinIncrementar return ; Espera se estabilicen niveles ; Si es un rebote sale fuera. ; Visualiza siempre

; Visualiza mientras espera que ; de pulsar. ; Mientras permanezca pulsado, ; incrementa el dgito.

; Subrutina "IncrementaRegistro50ms" ---------------------------------------------------; ; Incrementa el valor de la variable Registro50ms. Cuando llega a 10, lo cual supone ; medio segundo (50 ms x 10 = 500 ms), lo resetea y sale con el Carry a "1". ; IncrementaRegistro50ms incf Registro50ms,F movlw .10 subwf Registro50ms,W ; (W)=(Registro50ms)-10. btfsc STATUS,C ; C=0?, (W) negativo?, (Registro50ms)<10? clrf Registro50ms ; Lo inicializa si ha superado su valor mximo. return ; Subrutina "IncrementaMedioSegundo" -------------------------------------------------------; ; Incrementa el valor de la variable MedioSegundo. Su bit de menor peso se pondr a "1" una ; vez por segundo.

IncrementaMedioSegundo incf MedioSegundo,F bsf STATUS,C segundo. btfss MedioSegundo,0 segundo. bcf STATUS,C return

; Incrementa. ; Supone que ha llegado al ; El bit 0 se pondr a uno cada

; Subrutina "IncrementaSegundos" ----------------------------------------------------------; ; Incrementa el valor de la variable Segundo. Si es igual al valor mximo de 60 lo resetea ; y sale con el Carry a "1". IncrementaSegundos incf Segundo,F movlw .60 subwf Segundo,W (W)=(Segundo)-60. btfsc STATUS,C (Segundo)<60? clrf Segundo superado su valor mximo. return ; Incrementa los segundos. ; Ha superado valor mximo?. ; C=0?, (W) negativo?, ; Lo inicializa si ha

; Subrutina "IncrementaMinutos" ----------------------------------------------------------; ; Incrementa el valor de la variable Minuto. Si es igual al valor mximo de 60 lo resetea ; y sale con el Carry a "1". ; IncrementaMinutos incf Minuto,F ; Incrementa los minutos. movlw .60 subwf Minuto,W ; Ha superado su valor mximo?. (W)=(Minuto)-60. btfsc STATUS,C ; C=0?, (W) negativo?, (Minuto)<60? clrf Minuto ; Lo inicializa si ha superado su valor mximo. return ; Subrutina "IncrementaHoras" ----------------------------------------------------------; ; Incrementa el valor de la variable Hora. Si es igual al valor mximo de 24 lo resetea ; y sale con el Carry a "1". ; IncrementaHoras incf Hora,F ; Incrementa las horas.

movlw .24 subwf Hora,W ; Ha superado su valor mximo?. (W)=(Hora)-24. btfsc STATUS,C ; C=0?, (W) negativo?, (Hora)<24? clrf Hora ; Lo inicializa si ha superado su valor mximo. return ; ; Subrutina "PuestaEnHora" -------------------------------------------------------------; ; Subrutina de atencin a la interrupcin producida por el pulsador "MODO" que pone en hora ; el reloj. Cada vez que se pulsa, el "1" es desplazado a travs del registro (FlagsAjuste), ; pasando a ajustar secuencialmente: horas y minutos. ; ; Para comprender el funcionamiento de esta subrutina hay que saber que el registro FlagsModos ; contiene 2 flags que permiten diferenciar cada uno de los ajustes de registros de tiempo. ; - "F_AjusteHora": bit 1 de "FlagsAjuste", para ajustar las horas. ; - "F_AjusteMinuto": bit 0 de "FlagsAjuste", para ajustar los minutos. ; ; As pues el contenido del registro FlagAjuste identifica los siguientes ajustes: ; - (FlagsAjuste)=00000010. Est ajustando el registro Hora. ; - (FlagsAjuste)=00000001. Est ajustando el registro Minuto. ; - (FlagsAjuste)=00000000. Est en visualizacin normal del reloj en tiempo real. ; Pueden ocurrir tres casos: ; Que pulse "MODO" estando en modo de visualizacin normal que se identifica porque ; (FlagsAjuste)=0. En este caso debe activar el flag F_AjusteHora, es decir carga ; (FlagsAjuste)=b'00000010', ya que "F_AjusteHora" es el bit 1 del registro FlagsAjuste. ; Que pulse "MODO" estando ya en la puesta en hora, en cuyo caso debe pasar al ajuste ; del siguiente registro de tiempo (minutos). Esto lo hace mediante un desplazamiento a ; derechas. As, por ejemplo, si antes estaba ajustando las horas (FlagsAjuste)=b'00000010', ; pasar a (FlagsAjuste)=b'00000001' identificado como ajuste de los minutos. ; Que pulse "MODO" estando en el ltimo ajuste correspondiente a los minutos, ; (FlagsAjuste)=b'00000001', pasar a (FlagsAjuste)=b'00000000', indicando que la puesta ; en hora ha terminado y pasa a visualizacin normal del reloj en tiempo real. ;

PuestaEnHora call Retardo_20ms niveles. btfsc ModoPulsador goto FinPuestaEnHora PuestaEnHoraReset variable de bcf F_Intermitencia ajustar. movf FlagsAjuste,F funcionamiento normal, ahora btfss STATUS,Z goto AjustaSiguiente variable de tiempo siguiente. bsf F_AjusteHora clrf Segundo segundos y el resto. clrf MedioSegundo clrf Registro50ms goto FinPuestaEnHora AjustaSiguiente derecha del registro bcf STATUS,C secuencialmente rrf FlagsAjuste,F de tiempo: FinPuestaEnHora call VisualizaReloj btfss ModoPulsador goto FinPuestaEnHora return INCLUDE INCLUDE INCLUDE INCLUDE END <RETARDOS.INC> <LCD_4BIT.INC> <LCD_MENS.INC> <BIN_BCD.INC>

; Espera a que se estabilicen ; Si es un rebote sale fuera. ; Al pulsar "MODO" se apaga la ; tiempo que se va a ; Si antes estaba en ; pasa a ajustar la hora. ; Si no pasa a ajustar la ; Pasa a ajustar la hora. ; Inicializa contador de

; Desplaza un "1" a la ; FlagsAjuste para ajustar ; cada uno de los registros ; hora y minuto. ; Ahora espera deje de pulsar.

S-ar putea să vă placă și