Mostrando entradas con la etiqueta temporizadores. Mostrar todas las entradas
Mostrando entradas con la etiqueta temporizadores. Mostrar todas las entradas

11 de abril de 2011

Temporizadores · Contar desbordamientos

Cuando el tiempo que deseamos temporizar es mayor que un desbordamiento, entonces necesitamos una variable externa (por ejemplo un entero) donde ir "acumulando" los desbordamientos.

Suponiendo que usamos 16bits@12Mhz...
- 1 desbordamiento --> 65.536µs...variable desbordes=1..
- 2 desbordamientos -->  131.072µs...variable desbordes=2..
- 3 desbordamientos -->  196.608µs...variable desbordes=3..

Es la manera que tenemos de temporizar cantidades grandes. En estos casos, seguimos necesitando controlar cuando se produce el desbordamiento (mirando TF0) para ir incrementando la variable "desbordes".

Pero sucede que necesitaremos comprobar cuando la variable "desbordes" alcance un valor determinado. Supongamos que deseamos temporizar 1s..

- 1s = 1000000µs => dividimos entre un desborde completo 65536 = 15 (parte entera).
Por lo tanto para el caso de temporizar 1 segundo, en el bucle de control, tendré que controlar cuando la variable "desbordes" alcanza el valor de 15. Aquí puedes ver un ejemplo:


Observa que en el bucle "while" hemos añadido la condición "desbordes<15" para controlar cuando se alcanza el tiempo acumulado correspondiente. Dentro del mismo, debe seguir comprobándose "TF0" para detectar el debordamiento e incrementar la variable. 

* Puedes descargar el código aquí.

Temporización de 10 ms

En el ejemplo, se pedía temporizar 10ms usando el micro visto en clase. Como en todos los ejercicios de temporizadores, hay que seguir unos pasos sencillos:

1. Definir todos los registros necesarios con "sfr" y "sbit".
Necesitamos: "TMOD", "TCON", "TL0" y "TH0", además de algunos bits como: "TR0" y "TF0".

2. Escribir el bloque principal de tu programa.
Todo programa debe tener un bloque "void main(void) { }"donde se escriben las instrucciones.

3. Calcular la cuenta inicial.
Nos piden 10ms=10000microsegundos --> 65.536-10.000=55536=0xD8F0.

3. Asignar los valores a los registros.
Configurar el modo de funcionamiento del temporizador y fijar la cuenta inicial (10ms=0xD8F0).

4. Empezar la temporización y esperar el desborde.
El temporizador se pone en marcha con "TR0" y se espera el desborde mirando "TF0". Se puede hacer cómodamente con una instrucción while.



La instrucción "while" funciona del siguiente modo:

- Si "TF0" es "0" entonces la condición del bucle es "1" (está negada) y se queda en el bucle..
- Si "TF0" es "1" entonces la condición del bucle es "0" (está negada) y sale del bucle, ejecutando las instrucciones que tengamos más adelante. Por lo tanto dichas instrucciones se ejecutarán cuando finalice la temporización. Como puedes ver, es una de las muchas maneras que puedes usar para controlar los debordamientos.

* Puedes descargar el ejercicio aquí.

10 de abril de 2011

Temporizadores y condiciones de carrera

Un alumno me ha preguntado sobre las condiciones de carrera en los temporizadores. Por ejemplo cuando un temporizador está en modo "contador" para contar piezas, va almacenando el valor en dos registros, que como ya sabéis, son "TH0" y "TL0" para el temporizador "T0".

Para conocer el valor de la cuenta en un momento dado, el micro mira primero la parte baja del temporizador "TL0" (para ello consume un poco de tiempo). Instantes después mira la para alta del temporizador "TH0" y entonces es cuando ya se tiene el valor real de la cuenta que se almacena en una variable de tu programa.

Pero, ¿qué ocurre si entre las dos instrucciones de lectura, se produce una interrupción y el programa debe saltar a otra zona de código? Para cuando la ejecución prosiga y si el temporizador no se ha detenido, el valor del temporizador puede haber cambiado, habrá seguido incrementándose y la cuenta podría ser incoherente.

Un caso típico sería cuando tenemos: "TH0=11111111" y "TL0=11111111". Si se lee primero "TL0" tendremos "11111111". Imagina que en ese momento el programa salta a otra zona de código. El temporizador no se detiene y se producirá un desbordamiento (la cuenta empezará de cero).

Cuando a la vuelta de la interrupción (pasado un tiempo desconocido) se lea "TH0", se podría tener "00000000" y el valor de "TL0" que habíamos guardado tampoco seria el real (que ha vuelto a empezar de cero incrementándose).

Para evitar estas "condiciones de carrera", antes de realizar una lectura del valor del temporizador, siempre se detendrá con la instrucción "TR0=0" y se leerá entonces los registros. De este modo se evitarán las condiciones de carrera (resultados incoherentes), poniéndose en marcha inmediatamente con "TR0=1". En la figura puedes ver como se aplica en este ejemplo de contador de vehículos:



Condiciones de carrera por Wikipedia

Uso de máscaras en los temporizadores

En este ejemplo que vimos en clase, se configuraba el temporizador "T0" con un valor determinado. Nos fijaremos en las instrucciones: "TMOD |= 0x01 y TMOD &= 0xF1". En realidad fijan el modo de funcionamiento del temporizador (si es contador/temporizador, el número de bits, etc..) modificando las posiciones de bit del registro.

La cuestión es ¿por qué para ello hemos utilizado dos operaciones?


Cuando aplicamos la primera operación "TMOD |= 0x01" hacemos una "OR" al registro "TMOD" y ponemos a "1" sólo el primer bit --> 0x01 = 00000001.

Lo importante es que al utilizar una "OR", sólo tocamos el bit donde hemos puesto "1s", por lo tanto los demás bits se quedan como estaban. La operación "OR" nos permite poner a "1" los bits que necesitemos manteniendo su estado anterior (sin tocar otros bits).

No hemos terminado de configurar el registro "TMOD", sólo hemos puesto los "1s". Ahora nos falta poner "0s" en otras posiciones de bit y para ello usaremo la operación "AND". De hecho la línea "TMOD &= 0xF1" pone a cero tres posiciones del registro --> 0xF1 = 11110001, dejando los demás bits sin tocar.

Como resumen, cuando queramos poner "1s" y "0s" en un registro, manteniendo los valores anteriores, debemos usar las máscaras y además hacerlo en dos pasos (OR para poner a "1" y AND para poner a "0").

Y queda la pregunta del millón, ¿por qué querríamos hacerlo de esta manera? pues porque quizá otro programa podría estar usando el temporizador "T1" y los bits que controlan su funcionamiento están también en el mismo registro "TMOD". Si no usáramos máscaras y lo hiciéramos en una sóla operación, estaríamos "machacando" los valores en los bits que controlan el otro temporizador y si se estuviera usando, podríamos alterar su funcionamiento. Sencillo ¿no?

Temporizadores y frecuencia de reloj (2)

Otro caso, veamos el microcontrolador EM6580 de la empresa EM Microelectronic. Echemos un vistazo a su arquitectura en la hoja de características. Indica que tiene un reloj interno, que no necesita componentes externo y que puede funcionar entre 30khz y 800khz. También puede verse que tiene un temporizador de 10 bits, por lo tanto un desbordamiento completo se producirá en 2^10=1024 cuentas.

Ahora miramos, en la hoja de características del micro, el esquema del temporizador para saber a qué frecuencia trabaja y que relación tiene con el reloj del sistema. Se puede ver en la figura siguiente:


Lo que podemos ver aquí es que la señal que incrementa el temporizador "Out-ck", no depende de la señal de reloj del sistema. No podemos ver algo como en el caso del PIC, donde la señal de reloj se divide para alimentar el temporizador. Lo que vemos es que hay una serie de frecuencias que pueden seleccionarse, desde 1hz (la mínima) hasta 16khz (la máxima). Se podrá elegir entre ellas.

Supongamos que tomamos la frecuencia mínima: 1hz. Su periodo T=1/1hz=1s.
Esto quiere decir que a cada tic (1segundo), el temporizador se incrementa.
Si utilizamos 10bits, un desbordamiento completo será 2^10=1024s= 17,07minutos.

Si miramos un poco más adelante en la hoja de características, veremos que coincide este valor (texto señalado en color rojo). También puedes ver que utilizando una frecuencia mayor, el tiempo de desbordamiento será mucho menor.

Como has podido comprobar en este ejemplo, la frecuencia de reloj utilizada para el temporizador, no está relacionada con la frecuencia de reloj del sistema en un factor proporcional como en otros micros. Aquí hay disponibles las frecuencias de 1hz, 8hz, 128hz, 512hz, 2khz y 16khz y para cada una de ellas, el tiempo de desbordamiento será diferente.

9 de abril de 2011

Temporizadores y frecuencia de reloj

Cuando trabajamos con temporizadores, lo primero que debemos tener en cuenta en su frecuencia de trabajo, que está relacionada directamente con el reloj del sistema. Sólo tienes que mirar las tablas y localizar el esquema del temporizador: Por ejemplo, en la figura de abajo, puedes ver el esquema del temporizador de un PIC16F84. Observa que está alimentado por 1/4 de la frecuencia del reloj. Este dato es importante, porque así puedes saber a cuanto tiempo corresponde un desbordamiento completo.


Supongamos que este micro funciona con un reloj a 4Mhz. El periodo T=0,25µs.
Según este esquema, el temporizador funcionaría a 4Mhz/4=1Mhz. El periodo T=1µs.

Esto quiere decir que la cuenta del temporizador para este micro se incrementa cada 1µs.
Para un temporizador de 16bit@4Mhz, una cuenta completa temporizará 65536µs.

Temporizador en el micro AT89S8253

Aquí puedes ver la estructura interna de un microcontrolador. Algunos tienen el oscilador interno, otros necesitan algunos componentes externos como en este caso. Observa el rectángulo remarcado en verde. Es el oscilador encargado de generar la señal de reloj que sincroniza todas las operaciones y que también es utilizada como base de tiempos para los temporizadores.

En este caso, que corresponde al micro visto en clase, puedes ver que hay que añadir dos condensadores y un cristal de cuarzo que determina la frecuencia del reloj. Nosotros usamos un cristal de 12Mhz pero en función del micro, podrás utilizar otros cristales. En la web de Rubén Loredo puedes ver un esquema de un programador para este micro. Puedes descargar el esquemático y fabricarte tu placa. En el diagrama, señalado en color rojo, puedes ver el espacio para los dos condensadores y el cristal de cuarzo que configuran el reloj del sistema:




Este micro necesita elementos externos para activar el reloj, en otros micros se hacen innecesarios.

8 de abril de 2011

¿De qué depende la cuenta máxima de un temporizador?

Cuando usamos temporizadores, la cuenta se almacena en un registro que puede tener ser de 8, 13 ó 16 bits. Cada vez que el reloj del sistema hace "clic", el temporizador incrementa la cuenta. En el micro visto en clase, sabemos que el temporizador se incrementa cada microsegundo, por lo tanto su máxima cuenta será la que pueda alcanzar hasta que desborde. Recuerda que cuando llega a la máxima cuenta, vuelve a empezar desde cero.

5 de abril de 2011

Más temporizadores

Hoy terminaremos el tema de temporizadores. Veremos como se usan las interrupciones y haremos ejercicios que grabaremos en Keil para comprobar la temporización.

Realizar el cuestionario.

Práctica 1 · Escribe este programa en Keil. Corrige los errores y comprueba que realiza la temporización, definiendo una salida 0 del puerto "P0". ¿Cuánto tiempo está temporizando?


Práctica 2 · Reescribe el programa anterior para conseguir una temporización de 5 segundos. Añade la opción de ponerlo en marcha sólo cuando el pin "P0.4" esté activo.

1 de junio de 2010

Ejemplo de temporizadores sin usar calculadora

Temporiza 6 segundos con el timer T0 (v.1.1)
Se desea supervisar un sensor (S0) con un microcontrolador compatible 8051. El sensor “S0” está conectado al bit 4 del puerto “P1”. Cuando se detecta un nivel bajo en el sensor “S0”, el bit 7 del puerto “P0” deberá ponerse a nivel alto e iniciarse una temporización de 6 segundos. Cuando finalice este tiempo, el bit 7 del puerto “P0” deberá ponerse a nivel bajo.








Se pide:

Realizar un programa en C que implemente la especificación anterior. Para ello, se deberá contemplar la programación de los registros involucrados (“sfr”), los bits necesarios y la utilización de las variables. La temporización se realizará por encuestas (sin utilizar interrupciones). Considérese que el reloj del sistema funciona a 12 Mhz.

Solución:

Como nos piden una temporización grande, usaremos el modo 1 (16 bits).
desbordamientos_enteros: 6000000/65536=91
resto: 6000000-(91*65536)=36224 (un desborde parcial).

Por lo tanto debemos realizar:

- 91 desbordamientos completos (timer empieza en cero) y
- 1 desbordamiento parcial (timer no empieza en cero).






















* Sin calculadora, se deja indicado:
desbordamientos_enteros: 6000000/65536 (91)
resto: 6000000 % 65536 (36224)


El desbordamiento parcial debe temporizar resto (36224 microsegundos).
Para cargar “TH0” y “TL0” con esta cuenta inicial, debemos, como siempre, restar del valor total del temporizador:

cuenta_inicial=65536-36224 = 29312 = 0x7280
TH0 = 0x72;
TL0 = 0x80;

* Sin calculadora, se deja indicado:
cuenta_inicial=65536-resto
TH = cuenta_inicial/256;

TL= cuenta_inicial % 256;

Esta operación anterior “separa” un valor de 16 bits en dos registros de 8 bits. Se hace así porque este micro no permite la asignación de un registro de 16 bits en una operación única.

Ejemplo del programa:

void main (void){

TR1=0;
P0=0x01; // configura línea 0 del puerto P0 como entrada
TMOD=0x01; // modo temporizador, gate=0, modo 16 bits

while (1){
desbordes=92;
if (s0 == 0) {
salida = 1;
TH0 = 29312/256; // carga parcial

TL0= 29312 % 256; // carga parcial
TR0=1;
// puesta en marcha del timer

…terminarlo y probarlo…

5 de mayo de 2009

Ejercicios de temporizadores

Trabajo para hoy:
1. Revisar el cuestionario corregido de la semana pasada aquí
2. Leer las cuestiones relativas a los temporizadores en el blog, podéis hacerlo seleccionando aquellas entradas con los tags 'temporizadores' y 'vuestras dudas'.
3. Realizar los ejercicios de repaso para la clase de hoy descargar

21 de junio de 2008

A vueltas con el modo Autorrecarga...

Óscar preguntaba lo siguiente:

"Tengo una duda bastante específica sobre los Timers que no he podido aclarar en el libro. Se que el modo autorrecarga de un timer sirve para cargarlo a un valor predefinido tras el desborde del mismo, vale , ok. Pero si no lo cargase, ¿qué pasaría con el valor de los registros (en este caso registro) TL0 tras eldesbordamiento? ¿Se pondría a 0? o ¿seguiría en el valor máximo 'contando'? De lo que he podido leer en el libro, me queda claro que sigue funcionando, osea contando tras ocurrir el desborde. Quiere decir esto que: llega al valor máximo (supongamos 256)--> se pone a 0 yluego vuelve a seguir aumentando hasta que se desborde de nuevo?Entonces, esto quiere decir que, en el caso de que me interesase tener como cuenta inicial un 0(para los modos de 13bits y 16), no necesitaría hacer recarga software del contador al desbordar éste? (puesto que se pondría por defecto a 0)..."

Respuesta del profesor: A ver...dejad que mire las tablas y os copie la figura del modo...


Como puedes ver en la figura, en el modo autorrecarga, el registro que lleva la 'cuenta' es TLx (es el que genera el 'Overflow') y por lo tanto cuando finaliza dicha cuenta, se recarga con el valor de THx (mira el sentido de la flecha). Por lo tanto NO hace falta cargarlo cada vez que desborda, ya que THx tiene el valor que hayas definido (actuando como una memoria). En este caso, debes cargar inicialmente THx, que determinará la temporización elegida.

Cuando acaba la cuenta, TLx NO necesariamente empieza de nuevo desde cero, leerá el valor de THx. Si le has puesto en THx, el valor 23, será éste el inicio de la cuenta en TLx, ¿entendido?

También es cierto que si cargas inicialmente THx a cero, la cuenta empezará desde cero, pero utilizar este modo en este caso es desaprovechar la funcionalidad de la autorrecarga.

Ten en cuenta que el modo autorrecarga se utiliza para temporizaciones repetitivas y está pensado precisamente para que no tengas que recargar el mismo valor continuamente en el contador...

Si tienes más dudas, escribe!

1 de junio de 2008

Cuestionario de Temporizadores/Contadores

Estimados alumnos, aquí publico la solución al cuestionario sobre Temporizadores/Contadores. Se explica de manera sencilla los conceptos, no obstante, si alguna respuesta no quedase clara, os invito a participar enviándome un correo a fin de poder ampliar la explicación.

También he incluido archivos de audio (mp3) con las respuestas. ¿Pensáis que el audio ayuda a entender mejor los conceptos del documento de texto en pdf? (espero vuestros correos o comentarios en este blog).

Cuestionario resuelto en PDF:

Audio: Los archivos mp3 son un complemento al documento de texto, te recomiendo que leas primero el documento pdf y después escuches los archivos mp3.

Archivos para escuchar directamente desde la web:
(puede tardar un poco en iniciar la reproducción, ten paciencia)

Pregunta 1, haz clic en 'Play':

Pregunta 2:

Pregunta 3:

Preguntas 4-8:

Pregunta 9:

Preguntas 10-13:

Pregunta 14:

Pregunta 15:

Preguntas 16-17:


Archivos en mp3 para descargar:
Audio pregunta 1
Audio pregunta 2
Audio pregunta 3
Audio preguntas 4-8
Audio pregunta 9
Audio preguntas 10-13
Audio pregunta 14
Audio pregunta 15
audio preguntas 16-17