Diferencia entre revisiones de «RTC (Real-timer counter) - MC9S08QE128»

De Wikitronica
Saltar a: navegación, buscar
(#REDIRECT código)
Línea 1: Línea 1:
Un Real Timer Counter es un contador interno que mantiene la información del tiempo en unidades humanas, donde la unidad básica es el segundo. El RTC está presente en la mayoría de los dispositivos electrónicos que necesitan llevar un registro del tiempo exacto. El término Real Timer Counter es para diferenciar de los contadores del hardware que son señales electrónicas para controlar los circuitos digitales.
+
Un Real Timer Counter es un contador interno que mantiene la información del tiempo en unidades humanas, donde la unidad básica es el segundo. El RTC está presente en la mayoría de los dispositivos electrónicos que necesitan llevar un registro del tiempo exacto. El término Real Timer Counter es para diferenciar de los contadores del Hardware que son señales electrónicas para controlar los circuitos digitales.
 +
 
  
 
==Configuración en el MC9S08QE128==
 
==Configuración en el MC9S08QE128==
  
 
El módulo  MC9S08QE128 tiene integrado un Real Timer Counter, que consiste en un comparador uno a uno de 8 bits, un contador uno a uno de 8 bits, diversos divisores pre-escalados de base 2  y de base 10, 3 fuentes de reloj y un vector de interrupción programable.El funcionamiento del RTC se muestra en el diagrama de bloques, presentado en la imagen a continuación:
 
El módulo  MC9S08QE128 tiene integrado un Real Timer Counter, que consiste en un comparador uno a uno de 8 bits, un contador uno a uno de 8 bits, diversos divisores pre-escalados de base 2  y de base 10, 3 fuentes de reloj y un vector de interrupción programable.El funcionamiento del RTC se muestra en el diagrama de bloques, presentado en la imagen a continuación:
[[Archivo:Diagrama.jpg|500px|right|thumb|Diagrama de bloques del RTC]] Se selecciona el reloj correspondiente, mediante el [[RTC (Real-timer counter) - MC9S08QE128#Definición_de_los_Registros|RTCLKS]]. Siendo estos LPO, low power oscillator, el cual es un reloj interno de 1KHz , ERCLK, reloj externo, IRCLK, reloj interno de 32 KHz. Tanto el IRCLK como el ERCLK  pueden ser entradas programadas por el usuario a través  de las salidas ICSIRCLK y ICSERCLK pertenecientes al módulo de configuración de clock interno [[ICS (Configuración Reloj Interno) - MC9S08QE128|ICS]]. Si el [[Modos de operación del MC9S08QE128|BACKGROUND MODE]] esta activado el RTC no entra en funcionamiento, se divide por el divisor pre-escalado seleccionado, mediante el RTCPS y el bit 0 del RTCLKS, y esto es guardado en [[RTC (Real-timer counter) - MC9S08QE128#Definición_de_los_Registros|RTCCNT]], el cual es comparado bit a bit con [[RTC (Real-timer counter) - MC9S08QE128#Definición_de_los_Registros|RTCMOD]], si la comparación es exitosa, se escribe un 1 en [[RTC (Real-timer counter) - MC9S08QE128#Definición_de_los_Registros|RTIF]], el cual es limpiado  escribiendo un 1 en RTIF,y si, por último [[RTC (Real-timer counter) - MC9S08QE128#Definición_de_los_Registros|RTIE]] está activo se realiza la solicitud de interrupción por RTC.
+
 
 +
[[Archivo:Diagrama.jpg|500px|right|thumb|Diagrama de bloques del RTC]] Se selecciona el reloj correspondiente, mediante el [[RTC (Real-timer counter) - MC9S08QE128#Definición_de_los_Registros|RTCLKS]]. Siendo estos LPO, Low Power Oscillator, el cual es un reloj interno de 1KHz , ERCLK, reloj externo, IRCLK, reloj interno de 32 KHz. Tanto el IRCLK como el ERCLK  pueden ser entradas programadas por el usuario a través  de las salidas ICSIRCLK y ICSERCLK pertenecientes al Módulo de configuración de Clock interno [[ICS (Configuración Reloj Interno) - MC9S08QE128|ICS]]. Si el [[Modos de operación del MC9S08QE128|BACKGROUND MODE]] esta activado el RTC no entra en funcionamiento, se divide por el divisor pre-escalado seleccionado, mediante el RTCPS y el bit 0 del RTCLKS, y esto es guardado en [[RTC (Real-timer counter) - MC9S08QE128#Definición_de_los_Registros|RTCCNT]], el cual es comparado bit a bit con [[RTC (Real-timer counter) - MC9S08QE128#Definición_de_los_Registros|RTCMOD]], si la comparación es exitosa, se escribe un 1 en [[RTC (Real-timer counter) - MC9S08QE128#Definición_de_los_Registros|RTIF]], el cual es limpiado  escribiendo un 1 en RTIF,y si, por último [[RTC (Real-timer counter) - MC9S08QE128#Definición_de_los_Registros|RTIE]] está activo se realiza la solicitud de interrupción por RTC.
  
 
Es importante destacar que si se desea usar el ICSIRCLK como fuente para el módulo RTC es necesario habilitar esta salida hacia el bus clock mediante la configuración del bit "RTC" en el registro  de compuertas de control para el sistema de reloj "SCGC2" por sus siglas en ingles (System Clock Gating Control 2 Register). para mayor información  ver la sección 5.8 del manual del microprocesador. [http://www.freescale.com/files/microcontrollers/doc/ref_manual/MC9S08QE128RM.pdf Manual de Referencia]
 
Es importante destacar que si se desea usar el ICSIRCLK como fuente para el módulo RTC es necesario habilitar esta salida hacia el bus clock mediante la configuración del bit "RTC" en el registro  de compuertas de control para el sistema de reloj "SCGC2" por sus siglas en ingles (System Clock Gating Control 2 Register). para mayor información  ver la sección 5.8 del manual del microprocesador. [http://www.freescale.com/files/microcontrollers/doc/ref_manual/MC9S08QE128RM.pdf Manual de Referencia]
Línea 31: Línea 33:
 
===RTC Status and Control Register (RTCSC)===
 
===RTC Status and Control Register (RTCSC)===
  
Este registro contiene: la bandera del status de interrupción (RTIF), el selector del reloj (RTCLKS), el habilitador de la interrupción por RTC (RTIE) y el selector de los divisores pre-escalados (RTCPS). Los bits de estos registros se distribuyen de la siguiente manera:
+
Este registro contiene: la Bandera del status de interrupción (RTIF), el selector del reloj (RTCLKS), el habilitador de la interrupción por RTC (RTIE) y el selector de los divisores pre-escalados (RTCPS). Los bits de estos registros se distribuyen de la siguiente manera:
  
[[Archivo:RTCSC.jpg|700px|center|thumb|Bits del RTCSC]]
+
[[Archivo:RTCSC.jpg|700px|center|thumb|Bits del RTCSC.]]
  
 
{| border="2" style="padding: 0.5em; border: 1px #aaa solid; border-collapse: collapse;background:#F9F9F9" cellpadding="4"  
 
{| border="2" style="padding: 0.5em; border: 1px #aaa solid; border-collapse: collapse;background:#F9F9F9" cellpadding="4"  
Línea 70: Línea 72:
  
 
En la siguiente tabla se muestran los diferentes divisores que ofrece RTC:
 
En la siguiente tabla se muestran los diferentes divisores que ofrece RTC:
[[Archivo:tabla1.jpg|700px|center|thumb|Divisores que ofrece el RTC]]
+
[[Archivo:tabla1.jpg|700px|center|thumb|Divisores que ofrece el RTC.]]
  
 
En la siguiente tabla se muestran los diferentes períodos que puede lograr el RTC:
 
En la siguiente tabla se muestran los diferentes períodos que puede lograr el RTC:
Línea 185: Línea 187:
 
===RTC Counter Register (RTCCNT)===
 
===RTC Counter Register (RTCCNT)===
  
Este registro es de solo lectura, el cual es el contador de 8 bits que tiene el RTC. Está distribuido de la siguiente manera:
+
Este Registro es de solo lectura, el cual, es el contador de 8 bits que tiene el RTC. Está distribuido de la siguiente manera:
[[Archivo:RTCCNT.jpg|700px|center|thumb|Bits del RTCCNT]]
+
 
 +
[[Archivo:RTCCNT.jpg|700px|center|thumb|Bits del RTCCNT.]]
 +
 
 
{| border="2" style="padding: 0.5em; border: 1px #aaa solid; border-collapse: collapse;background:#F9F9F9" cellpadding="4"  
 
{| border="2" style="padding: 0.5em; border: 1px #aaa solid; border-collapse: collapse;background:#F9F9F9" cellpadding="4"  
 
|- valign="bottom" style="background:#F2F2F2"
 
|- valign="bottom" style="background:#F2F2F2"
Línea 194: Línea 198:
 
|align="center"|7:0
 
|align="center"|7:0
 
RTCCNT
 
RTCCNT
|'''RTC COUNT:''' estos ochos bits contienen la información del contador de RTC. Escribir en ellos no produce ningún efecto. Resetear, escribir en RTCMOD, o cambiar los valores de RTCLKS y RTCPS limpian el contador y lo vuelve 0x00.
+
|'''RTC COUNT:''' Estos ochos bits contienen la información del contador de RTC. Escribir en ellos no produce ningún efecto. Resetear, escribir en RTCMOD, o cambiar los valores de RTCLKS y RTCPS limpian el contador y lo vuelve 0x00.
 
|}
 
|}
  
 
===RTC Modulo Register (RTCMOD)===
 
===RTC Modulo Register (RTCMOD)===
[[Archivo:RTCMOD.jpg|700px|center|thumb|Bits del RTCMOD]]
+
 
 +
[[Archivo:RTCMOD.jpg|700px|center|thumb|Bits del RTCMOD.]]
 +
 
 +
 
 +
 
 
{| border="2" style="padding: 0.5em; border: 1px #aaa solid; border-collapse: collapse;background:#F9F9F9" cellpadding="4"  
 
{| border="2" style="padding: 0.5em; border: 1px #aaa solid; border-collapse: collapse;background:#F9F9F9" cellpadding="4"  
 
|- valign="bottom" style="background:#F2F2F2"
 
|- valign="bottom" style="background:#F2F2F2"
Línea 210: Línea 218:
  
 
==Modo de Utilización==
 
==Modo de Utilización==
 +
  
 
===Por interrupción===
 
===Por interrupción===
 +
  
 
Para utilizar la interrupción por RTC se tiene que habilitar el RTIE, como se mostró anteriormente. De esta manera cada vez que el RTIF sea 1 entra en la interrupción y para poder salir se tiene que limpiar esta bandera escribiendole 1.
 
Para utilizar la interrupción por RTC se tiene que habilitar el RTIE, como se mostró anteriormente. De esta manera cada vez que el RTIF sea 1 entra en la interrupción y para poder salir se tiene que limpiar esta bandera escribiendole 1.
Línea 228: Línea 238:
 
  int main(){
 
  int main(){
 
  /*Configuro el RTC para que interrumpa cada 1 seg con el reloj fuente LPO de 1 KHz de frecuencia*/
 
  /*Configuro el RTC para que interrumpa cada 1 seg con el reloj fuente LPO de 1 KHz de frecuencia*/
  RTCMOD = 0x00;          //el modulo será 00 así que cada vez que pase el período  
+
  RTCMOD = 0x00;          // El modulo será 00 así que cada vez que pase el período.
                                   //elegido se hará una interrupción
+
                                   // Elegido se hará una interrupción.
         RTCSC = 0x1F;            //se habilita la interrupción por RTC (RTIE=1), se elige el
+
         RTCSC = 0x1F;            // Se habilita la interrupción por RTC (RTIE=1), se elige el
                                   //LPO como reloj fuente (RTCLKS = 00), el divisor es de 10^3
+
                                   // LPO como reloj fuente (RTCLKS = 00), el divisor es de 10^3 (kilo)
                                   // (RTCPS = 0xF), así que el período es de 1 seg
+
                                   // (RTCPS = 0xF), así que el período es de 1 segundo.
    for(;;){              //ciclo infinito
+
    for(;;){              // Ciclo Infinito.
 
             while(control == 0){
 
             while(control == 0){
             }                    //ciclo infinito mientras no se entre a la interrupción por RTC
+
             }                    // Ciclo Infinito mientras no se entre a la interrupción por RTC.
             control = 0;          //vuelvo a poner el control en su estado inicial para que
+
             control = 0;          // Vuelvo a poner el Control en su Estado Inicial para que
                                   //el ciclo anterior sirva nuevamenta
+
                                   // El ciclo anterior sirva nuevamente.
 
             Seconds++;
 
             Seconds++;
 
             /* 60 segundos es un minuto*/
 
             /* 60 segundos es un minuto*/
Línea 258: Línea 268:
 
   //vector de interrupción por RTC
 
   //vector de interrupción por RTC
 
   void VectorNumber_Vrtc Interrupt(void){
 
   void VectorNumber_Vrtc Interrupt(void){
         RTCSC_RTIF = 1;                          //limpio la bandera para volver a entrar a  
+
         RTCSC_RTIF = 1;                          // Limpio la Bandera para volver a entrar a  
                                                   //la interrupción
+
                                                   // la Interrupción.
         control = 1;                            //cambio el control para salir del ciclo
+
         control = 1;                            // Cambio el Control para salir del Ciclo
                                                   //infinito del main
+
                                                   // Infinito del main
 
   }
 
   }
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Ahora veamos un codigo para utilizar el RTC por interrupción, pero en assembler, donde solo vamos a inicializar el RTC y mostrar el vector de interrupción:
+
Ahora veamos un código para utilizar el RTC por interrupción, pero en assembler, donde solo vamos a inicializar el RTC y mostrar el vector de interrupción:
  
 
Incluyo toda la circuitería del circuitería del [[Freescale Codewarrior 6.3|MC9S08QE128]]
 
Incluyo toda la circuitería del circuitería del [[Freescale Codewarrior 6.3|MC9S08QE128]]
Línea 273: Línea 283:
 
inicializo el RTC
 
inicializo el RTC
 
  LDA #$00       
 
  LDA #$00       
  STA RTCMOD          ;RTCMOD esta en 00, así que cada vez que se cumpla el período elegido se
+
  STA RTCMOD          ; RTCMOD esta en 00, así que cada vez que se cumpla el período elegido se
                       ;hará la interrupción
+
                       ; Hará la interrupción
 
  LDA #$1f
 
  LDA #$1f
  STA RTCSC            ;el reloj escogido es el LPO a 1KHz, y el período de 1 seg,  
+
  STA RTCSC            ; El reloj escogido es el LPO a 1KHz, y el período de 1 segundo,  
                       ;la interrupción está habilitada
+
                       ; La interrupción está habilitada
 
Defino el vector de interrupción en la dirección donde está contenido:
 
Defino el vector de interrupción en la dirección donde está contenido:
 
  ORG  $FFCE
 
  ORG  $FFCE
  DC.W  Interrupción  ;vector de interrupción por RTC, el cual es programable a la conveniencia
+
  DC.W  Interrupción  ; Vector de interrupción por RTC, el cual es programable a la conveniencia
                       ;del usuario
+
                       ; Del usuario
 
Un ejemplo del vector de interrupción, sería:
 
Un ejemplo del vector de interrupción, sería:
 
  Interrupción:  LDA #$80
 
  Interrupción:  LDA #$80
                 ORA RTCSC                  ;limpio la bandera RTIF para volver a entrar a la
+
                 ORA RTCSC                  ; Limpio la bandera RTIF para volver a entrar a la
                                             ;interrupción, con el OR entre 0x80 y RTCSC (donde
+
                                             ; Interrupción, con el OR entre 0x80 y RTCSC (donde
 
                                             ; el octavo bit es RTIF)
 
                                             ; el octavo bit es RTIF)
                 PSHX                      ;instrucción de ejemplo de como se puede programar
+
                 PSHX                      ; Instrucción de ejemplo de como se puede programar
 
                                             ;a conveniencia el vector de interrupción.
 
                                             ;a conveniencia el vector de interrupción.
 
                 RTI                        ;el programa se sale de la interrupción.
 
                 RTI                        ;el programa se sale de la interrupción.
Línea 293: Línea 303:
  
 
===Por Encuesta===
 
===Por Encuesta===
 +
 +
 
Si, por el contrario, no se quiere utilizar la interrupción por RTC no se activa el bit RTIE, y el usuario tiene que codificar de tal manera que el programa verifique el estado de RTIF, para saber que el período elegido se ha cumplido. Con el código anterior se modificará para utilizar el RTC como encuesta.
 
Si, por el contrario, no se quiere utilizar la interrupción por RTC no se activa el bit RTIE, y el usuario tiene que codificar de tal manera que el programa verifique el estado de RTIF, para saber que el período elegido se ha cumplido. Con el código anterior se modificará para utilizar el RTC como encuesta.
 +
  
 
<syntaxhighlight lang="c">
 
<syntaxhighlight lang="c">
Línea 303: Línea 316:
 
  int Days=0;
 
  int Days=0;
 
  int main(){
 
  int main(){
  /* Configuro el RTC para que interrumpa cada 1 seg con el reloj fuente LPO de 1 KHz de frecuencia*/
+
  /* Configuro el RTC para que interrumpa cada 1 segundo con el reloj fuente LPO de 1 KHz de frecuencia*/
  RTCMOD = 0x00;          //el modulo será 00 así que cada vez que pase el perído elegido se hará una interrupción
+
  RTCMOD = 0x00;          // El Módulo será 00 así que cada vez que pase el perído elegido se hará una Interrupción.
         RTCSC = 0x0F;            //se deshabilita la interrupción por RTC (RTIE=0), se elige el LPO como reloj
+
         RTCSC = 0x0F;            // Se deshabilita la interrupción por RTC (RTIE=0), se elige el LPO como Reloj.
  fuente (RTCLKS = 00), el divisor es de 10^3 (RTCPS = 0xF), así que el período es de 1 seg
+
  fuente (RTCLKS = 00), el divisor es de 10^3 (RTCPS = 0xF), así que el período es de 1 segundo.
    for(;;){              //ciclo infinito
+
    for(;;){              // Ciclo Infinito
 
             while(RTIF == 0){
 
             while(RTIF == 0){
             }                    //ciclo infinito mientras no se cumpla el perído elegido
+
             }                    // Ciclo Infinito mientras no se cumpla el perído elegido
             RTIF = 1;          //limpio la bandera
+
             RTIF = 1;          // Limpio la bandera
 
             Seconds++;
 
             Seconds++;
 
             /* 60 segundos es un minuto*/
 
             /* 60 segundos es un minuto*/
Línea 331: Línea 344:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Veamos un ejemplo de assembler por encuesta:
+
Veamos un ejemplo de Assembler por encuesta:
  
 
Incluyo toda la circuitería del circuitería del [[Freescale Codewarrior 6.3|MC9S08QE128]]
 
Incluyo toda la circuitería del circuitería del [[Freescale Codewarrior 6.3|MC9S08QE128]]
Línea 339: Línea 352:
 
inicializo el RTC
 
inicializo el RTC
 
  LDA #$00       
 
  LDA #$00       
  STA RTCMOD          ;RTCMOD esta en 00, así que cada vez que se cumpla el período elegido se hará la interrupción
+
  STA RTCMOD          ; RTCMOD esta en 00, así que cada vez que se cumpla el período elegido se hará la interrupción
 
  LDA #$0f
 
  LDA #$0f
  STA RTCSC            ;el reloj escogido es el LPO a 1KHz, y el período de 1 seg, la interrupción esta deshabilitada
+
  STA RTCSC            ; El reloj escogido es el LPO a 1KHz, y el período de 1 seg, la interrupción esta deshabilitada,
 
Después de que se habilita el RTC, el programador tendrá que adecuar su código para verificar la bandera RTIF,como por ejemplo:
 
Después de que se habilita el RTC, el programador tendrá que adecuar su código para verificar la bandera RTIF,como por ejemplo:
  ciclo: BRSET RTCSC_RTIF,RTCSC, ciclo    ;ciclo infinito mientras no se realiza el período indicado
+
  ciclo: BRSET RTCSC_RTIF,RTCSC, ciclo    ; Ciclo infinito mientras no se realiza el período indicado.
 
  LDA #$80
 
  LDA #$80
  ORA RTCSC              ; limpio la bandera, para verificar en un instante posterior.
+
  ORA RTCSC              ; Limpio la bandera, para verificar en un instante posterior.
  PSHX                  ;codigo de ejemplo
+
  PSHX                  ; Código de ejemplo.
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Si bien utilizar interrupción o no, en estos códigos simples, parece ser lo mismo, en un codigo más complicado es recomendable utilizar siempre interrupciones, porque el mismo módulo verifica si ha ocurrido la condición para la interrupción, mientras que por encuesta el programador tiene que tener mucho cuidado en la verificación de la bandera para que su código trabaje como se desee. Además, los ciclos infinitos, mientras no se haga 1 RTIF, hacen que el código por encuesta sea menos eficientes; porque, por lo general, se necesitan más de uno de esos ciclos para verificar la condición, mientras que por interrupción el programa sigue corriendo, hasta que la interrupción es creada, gracias al prendido de la bandera correspondiente.
+
; Si : bien utilizar interrupción o no, en estos códigos simples, parece ser lo mismo, en un código más complicado es recomendable utilizar siempre interrupciones, porque el mismo módulo verifica si ha ocurrido la condición para la interrupción, mientras que por encuesta el programador tiene que tener mucho cuidado en la verificación de la bandera para que su código trabaje como se desee. Además, los ciclos infinitos, mientras no se haga 1 RTIF, hacen que el código por encuesta sea menos eficientes; porque, por lo general, se necesitan más de uno de esos ciclos para verificar la condición, mientras que por interrupción el programa sigue corriendo, hasta que la interrupción es creada, gracias al prendido de la bandera correspondiente.
  
 
==Referencia==
 
==Referencia==

Revisión del 18:08 1 dic 2012

Un Real Timer Counter es un contador interno que mantiene la información del tiempo en unidades humanas, donde la unidad básica es el segundo. El RTC está presente en la mayoría de los dispositivos electrónicos que necesitan llevar un registro del tiempo exacto. El término Real Timer Counter es para diferenciar de los contadores del Hardware que son señales electrónicas para controlar los circuitos digitales.


Configuración en el MC9S08QE128

El módulo MC9S08QE128 tiene integrado un Real Timer Counter, que consiste en un comparador uno a uno de 8 bits, un contador uno a uno de 8 bits, diversos divisores pre-escalados de base 2 y de base 10, 3 fuentes de reloj y un vector de interrupción programable.El funcionamiento del RTC se muestra en el diagrama de bloques, presentado en la imagen a continuación:

Diagrama de bloques del RTC
Se selecciona el reloj correspondiente, mediante el RTCLKS. Siendo estos LPO, Low Power Oscillator, el cual es un reloj interno de 1KHz , ERCLK, reloj externo, IRCLK, reloj interno de 32 KHz. Tanto el IRCLK como el ERCLK pueden ser entradas programadas por el usuario a través de las salidas ICSIRCLK y ICSERCLK pertenecientes al Módulo de configuración de Clock interno ICS. Si el BACKGROUND MODE esta activado el RTC no entra en funcionamiento, se divide por el divisor pre-escalado seleccionado, mediante el RTCPS y el bit 0 del RTCLKS, y esto es guardado en RTCCNT, el cual es comparado bit a bit con RTCMOD, si la comparación es exitosa, se escribe un 1 en RTIF, el cual es limpiado escribiendo un 1 en RTIF,y si, por último RTIE está activo se realiza la solicitud de interrupción por RTC.

Es importante destacar que si se desea usar el ICSIRCLK como fuente para el módulo RTC es necesario habilitar esta salida hacia el bus clock mediante la configuración del bit "RTC" en el registro de compuertas de control para el sistema de reloj "SCGC2" por sus siglas en ingles (System Clock Gating Control 2 Register). para mayor información ver la sección 5.8 del manual del microprocesador. Manual de Referencia

Modos de funcionamiento

Wait Mode

En el modo de espera, el RTC sigue contando si está activado antes de entrar en este modo. Por lo tanto el RTC puede configurarse para que el MCU salga del modo de espera y volver a su funcionamiento normal, esto es posible cuando la interrupción por RTC está activa. Para el menor consumo de corriente en el modo de espera, posible, y si no es requerida la interrupción, entonces se puede deshabilitar el RTC.

Stop Mode

En el modo de stop2 y stop3, el RTC sigue corriendo si esta activo antes de producirse la instrucción de STOP, así que por esta razón el RTC puede configurarse para devolver al MCU de un modo de stop, si la interrupción por RTC está activa. Entre los relojes fuentes, el LPO se puede seleccionar en los dos modos de stop, mientras que ERCLK y IRCLK solo se pueden seleccionar en el modo de stop3. De igual manera si se desea el menor consumo de corriente mientras ocurre el modo de stop, se tiene que deshabilitar el RTC, sabiendo que la interrupción por RTC no podrá regresar el MCU a su normal funcionamiento.

Active Background Mode

El RTC suspende cualquier conteo mientras el MCU se encuentra en Background Mode. El contador se reanuda en el valor que estaba antes suspender el conteo, esto se cumple mientras no se escriba en RTCMOD y los bits de RTCPS Y RTCLKS no sean alterados.

ADC Hardward Trigger

El RTC se puede configurar para que sea el trigger del Conversor Análogo Digital (ADC) y que se realice la conversión, esto se logra si se activa el ADCSC2[ADTRG]. Cuando esto se produce el ADC realiza la conversión cada vez que el RTCINT coincide con RTCMOD, es importante saber que la interrupción por RTC no es necesaria para que este funcione de esta forma.

Definición de los Registros

RTC Status and Control Register (RTCSC)

Este registro contiene: la Bandera del status de interrupción (RTIF), el selector del reloj (RTCLKS), el habilitador de la interrupción por RTC (RTIE) y el selector de los divisores pre-escalados (RTCPS). Los bits de estos registros se distribuyen de la siguiente manera:

Bits del RTCSC.
Bits Descripción
7

RTIF

Real-TImer Interruption Flag: esta bandera indica que el valor del contador del RTC ha llegado al valor esperado. Escribir un 0 no tiene efecto en este registro, pero si se escribe un 1 la bandera se limpia.

0 = el contador no ha llegado al valor esperado.

1 = el contador llegó al valor esperado.

6:5

RTCLKS

Real-Timer Clock Source Select: estos bits selecciona la fuente del reloj de entrada que utilizará el RTC para dividir entre los divisores pre-escalados. Cambiar la fuente del reloj limpia el divisor pre-escalado en RTCPS y el contador en RTCCNT. Es importante que cuando se selecciona un reloj se verifique si está habilitado, para el buen funcionamiento del RTC. Resetear RTCLKS produce que se vuelva 00.

00 = el reloj seleccionado es LPO, de un 1 KHz de frecuencia.

01 = el reloj seleccionado es el reloj externo (ERCLK).

1x = el reloj seleccionado es el reloj interno (IRCLCK), de 32 KHz de frecuencia.

4

RTIE

Real-Timer Interruption Enable: este bit habilita la interrupción por RTC. Si RTIE está habilitado entonces se realizará una interrupción cuando RTIF se vuelva 1. Resetear el bit produce que éste se vuelva 0.

0 = la interrupción no se habilita, se tiene que proceder por encuesta.

1 = la interrupción está habilitada, así que se realizará cuando RTIF sea 1.

3:0

RTCPS

Real-Timer Clock Prescaler Select: estos cuatros bits sirven para seleccionar el divisor de base 10 o de base 2 que dividirán la frecuencia del reloj seleccionado. Cambiar el divisor produce que RTCCNT se limpie. Si se resetea RTCPS, el valor se vuelve 0.

En la siguiente tabla se muestran los diferentes divisores que ofrece RTC:

Divisores que ofrece el RTC.

En la siguiente tabla se muestran los diferentes períodos que puede lograr el RTC:

RTCPS 1 KHz reloj interno

(RTCLKS = 00)

1 MHz reloj externo

(RTCLKS = 01)

32 KHz reloj interno

(RTCLKS = 10)

32 KHz reloj interno

(RTCLKS = 11)

0000 Off Off Off Off
0001 8 ms 1 024 ms 250 us 32 ms
0010 32 ms 2 048 ms 1 ms 64 ms
0011 64 ms 4 096 ms 2 ms 128 ms
0100 128 ms 8 192 ms 4 ms 256 ms
0101 256 ms 16.4 ms 8 ms 512 ms
0110 512 ms 32.8 ms 16 ms 1.024 s
0111 1.024 s 65.5 ms 32 ms 2.048 s
1000 1 ms 1 ms 31.25 us 31.25 ms
1001 2 ms 2 ms 62.5 us 62.5 ms
1010 4 ms 5 ms 125 us 156.25 ms
1011 10 ms 10 ms 312.5 us 312.5ms
1100 16 s 20 ms 0.5 us 0.625 s
1101 0.1 s 50 ms 3.125 ms 1.5625 s
1110 0.5 s 0.1 ms 15.625 ms 3.125 s
1111 1 s 0.2 ms 31.25 ms 6.25 s

RTC Counter Register (RTCCNT)

Este Registro es de solo lectura, el cual, es el contador de 8 bits que tiene el RTC. Está distribuido de la siguiente manera:

Bits del RTCCNT.
Bits Descripción
7:0

RTCCNT

RTC COUNT: Estos ochos bits contienen la información del contador de RTC. Escribir en ellos no produce ningún efecto. Resetear, escribir en RTCMOD, o cambiar los valores de RTCLKS y RTCPS limpian el contador y lo vuelve 0x00.

RTC Modulo Register (RTCMOD)

Bits del RTCMOD.


Bits Descripcion
7:0

RTCMOD

RTC modulo: estos 8 bits muestran el valor del modulo que servirá para resetear el contador a 0x00 y poner un 1 en RTIF. Un valor de 0x00 permite que RTIF se vuelva 1 cada vez que se alcanza el valor del período escogido. Escribir en estos bits produce que el contador y el RTCCNT se limpien. Resetear el modulo convierte RTCMOD a 0x00.

Modo de Utilización

Por interrupción

Para utilizar la interrupción por RTC se tiene que habilitar el RTIE, como se mostró anteriormente. De esta manera cada vez que el RTIF sea 1 entra en la interrupción y para poder salir se tiene que limpiar esta bandera escribiendole 1. El vector de interrupción de RTC, está contenido en la dirección 0xFFCE:0xFFCF y es nombrado como Vrtc. Este vector se puede configurar a conveniencia del programador. A continuación se mostrará un código simple que configura el RTC en modo de interrupción, y el programa simplemente cuenta el tiempo en segundos,minutos, horas y días.

 #include "derivative.h"  //se incluye la librería con toda la circuitería del [[Freescale Codewarrior 6.3|MC9S08QE128]] 
                          //para más facilidad
 /* Inicializo los contadores del tiempo */
 int Seconds = 0;
 int Minutes = 0;
 int Hours = 0;
 int Days=0;
 int control=0;
 int main(){
 /*Configuro el RTC para que interrumpa cada 1 seg con el reloj fuente LPO de 1 KHz de frecuencia*/
 	 RTCMOD = 0x00;           // El modulo será 00 así que cada vez que pase el período. 
                                  // Elegido se hará una interrupción.
         RTCSC = 0x1F;            // Se habilita la interrupción por RTC (RTIE=1), se elige el
                                  // LPO como reloj fuente (RTCLKS = 00), el divisor es de 10^3 (kilo)
                                  // (RTCPS = 0xF), así que el período es de 1 segundo.
 	  for(;;){               // Ciclo Infinito.
            while(control == 0){
            }                    // Ciclo Infinito mientras no se entre a la interrupción por RTC.
            control = 0;          // Vuelvo a poner el Control en su Estado Inicial para que
                                  // El ciclo anterior sirva nuevamente.
            Seconds++;
            /* 60 segundos es un minuto*/
            if (Seconds > 59){
               Minutes++;
               Seconds = 0;
            }
            /* 60 minutos es una hora*/
            if (Minutes > 59){
               Hours++;
               Minutes = 0;
            }
            /* 24 hours es un dia */
            if (Hours > 23){
               Days ++;
               Hours = 0;
            }
          }
  }
  //vector de interrupción por RTC
  void VectorNumber_Vrtc Interrupt(void){
         RTCSC_RTIF = 1;                          // Limpio la Bandera para volver a entrar a 
                                                  // la Interrupción.
         control = 1;                             // Cambio el Control para salir del Ciclo
                                                  // Infinito del main
  }

Ahora veamos un código para utilizar el RTC por interrupción, pero en assembler, donde solo vamos a inicializar el RTC y mostrar el vector de interrupción:

Incluyo toda la circuitería del circuitería del MC9S08QE128

 INCLUDE 'derivative.inc'
inicializo el RTC
 LDA #$00       
 STA RTCMOD           ; RTCMOD esta en 00, así que cada vez que se cumpla el período elegido se
                      ; Hará la interrupción
 LDA #$1f
 STA RTCSC             ; El reloj escogido es el LPO a 1KHz, y el período de 1 segundo, 
                       ; La interrupción está habilitada
Defino el vector de interrupción en la dirección donde está contenido:
 ORG   $FFCE
 DC.W  Interrupción   ; Vector de interrupción por RTC, el cual es programable a la conveniencia
                      ; Del usuario
Un ejemplo del vector de interrupción, sería:
 Interrupción:   LDA #$80
                 ORA RTCSC                  ; Limpio la bandera RTIF para volver a entrar a la
                                            ; Interrupción, con el OR entre 0x80 y RTCSC (donde
                                            ; el octavo bit es RTIF)
                 PSHX                       ; Instrucción de ejemplo de como se puede programar
                                            ;a conveniencia el vector de interrupción.
                 RTI                        ;el programa se sale de la interrupción.

Por Encuesta

Si, por el contrario, no se quiere utilizar la interrupción por RTC no se activa el bit RTIE, y el usuario tiene que codificar de tal manera que el programa verifique el estado de RTIF, para saber que el período elegido se ha cumplido. Con el código anterior se modificará para utilizar el RTC como encuesta.


 #include "derivative.h"   //se incluye la librería con toda la circuitería del [[Freescale Codewarrior 6.3|MC9S08QE128]] para más facilidad
 /* Inicializo los contadores del tiempo */
 int Seconds = 0;
 int Minutes = 0;
 int Hours = 0;
 int Days=0;
 int main(){
 /* Configuro el RTC para que interrumpa cada 1 segundo con el reloj fuente LPO de 1 KHz de frecuencia*/
 	 RTCMOD = 0x00;           // El Módulo será 00 así que cada vez que pase el perído elegido se hará una Interrupción.
         RTCSC = 0x0F;            // Se deshabilita la interrupción por RTC (RTIE=0), se elige el LPO como Reloj.
 fuente (RTCLKS = 00), el divisor es de 10^3 (RTCPS = 0xF), así que el período es de 1 segundo.
 	  for(;;){               // Ciclo Infinito
            while(RTIF == 0){
            }                    // Ciclo Infinito mientras no se cumpla el perído elegido
            RTIF = 1;           // Limpio la bandera
            Seconds++;
            /* 60 segundos es un minuto*/
            if (Seconds > 59){
               Minutes++;
               Seconds = 0;
            }
            /* 60 minutos es una hora*/
            if (Minutes > 59){
               Hours++;
               Minutes = 0;
            }
            /* 24 hours es un dia */
            if (Hours > 23){
               Days ++;
               Hours = 0;
            }
          }
  }

Veamos un ejemplo de Assembler por encuesta:

Incluyo toda la circuitería del circuitería del MC9S08QE128

 INCLUDE 'derivative.inc'
inicializo el RTC
 LDA #$00       
 STA RTCMOD           ; RTCMOD esta en 00, así que cada vez que se cumpla el período elegido se hará la interrupción
 LDA #$0f
 STA RTCSC             ; El reloj escogido es el LPO a 1KHz, y el período de 1 seg, la interrupción esta deshabilitada,
Después de que se habilita el RTC, el programador tendrá que adecuar su código para verificar la bandera RTIF,como por ejemplo:
 ciclo: BRSET RTCSC_RTIF,RTCSC, ciclo    ; Ciclo infinito mientras no se realiza el período indicado.
 LDA #$80
 ORA RTCSC              ; Limpio la bandera, para verificar en un instante posterior.
 PSHX                   ; Código de ejemplo.
Si 
bien utilizar interrupción o no, en estos códigos simples, parece ser lo mismo, en un código más complicado es recomendable utilizar siempre interrupciones, porque el mismo módulo verifica si ha ocurrido la condición para la interrupción, mientras que por encuesta el programador tiene que tener mucho cuidado en la verificación de la bandera para que su código trabaje como se desee. Además, los ciclos infinitos, mientras no se haga 1 RTIF, hacen que el código por encuesta sea menos eficientes; porque, por lo general, se necesitan más de uno de esos ciclos para verificar la condición, mientras que por interrupción el programa sigue corriendo, hasta que la interrupción es creada, gracias al prendido de la bandera correspondiente.

Referencia