Paso 5: Breve introducción sobre PIC y temporizadores
Los temporizadores se pueden utilizar para bastantes tareas: creación de bases de tiempo, desencadenar eventos periódicos, medir el tiempo entre dos eventos (medida de frecuencia) y mucho más. En mi pequeño firmware usé un temporizador para hacerme una base de tiempo de 10 milisegundos. Cuenta que de cien veces me dio una bandera que tiene cada vez un segundo pasado. Esto era necesario, porque yo sabía que quería el dispositivo a cargar durante 10 minutos y a medida para 5 segundos – una base de tiempo estándar tuvo que ser involucrados en el proyecto de alguna manera.
Sobre los temporizadores PIC
Un procesador puede ejecutar miles de instrucciones en fracciones de segundo, bases de tiempo más grandes se construyen generalmente contando milisegundos a varios cientos de veces. Para poder calcular un tiempo pequeño, como uno de 1ms, necesitamos saber qué tan rápido el PIC funciona realmente en. El PIC12F683 tiene un oscilador interno de 8MHz máximo, esto es lo el dispositivo del reloj. Sabiendo que el PIC necesita cuatro relojes para ejecutar una sola instrucción, el ciclo de instrucción es 2 MHz. basado en eso, el tiempo que necesita el PIC para ejecutar una instrucción es 1/2.000.000 = 500ns. Esta será la base de tiempo de con que los temporizadores internos avanzará. Cada temporizador tiene un asociado 8 interna o registro de 16 bits, que aumenta su valor cada vez que pasa este 500ns. Este registro puede ser leído y escrito en cualquier momento. Cuando los 8 o 16 bits registrar desbordamientos, se coloca una bandera para indicar este evento.
Prescalers y postscalers pueden asignarse a los contadores de tiempo, para lograr temporizations más. Un prescaler o postscaler es un contador propio, configurable en una variedad de maneras. En pocas palabras, estos dividen el reloj en su entrada con un valor que puede cambiarse mediante software. Un prescaler de 1:8 da una señal de reloj en su salida después de cada reloj 8-th en su entrada. Esto significa que añadiendo un prescaler de 1:8 en una entrada de contador de tiempo se ralentizará la velocidad de este reloj avanza por 8. Postscalers exactamente el mismo trabajo, generalmente es la posición de estos circuitos (en relación con el registro de contador de tiempo), que determina si estamos hablando de un prescaler o un postscaler. Prescalers ralentizar la tasa de avance del registro temporizador, postscaler demora el momento cuando se desencadena un evento de desbordamiento. Usando estos circuitos podemos crear marcas de tiempo de periodos más largos. El evento que se produce en cada desbordamiento se describe a menudo como el "ajuste de la bandera de interrupción".
Vamos a ver la configuración del temporizador en nuestro ejemplo particular!
Configurar el temporizador 0
En nuestro procesador se dispone de tres temporizadores, utilizaremos sólo uno: número de temporizador 0. Los registros que necesitan ser configurado para que este módulo a trabajar son: OPTION_REG, INTCON.
Configuración de OPTION_REG
El nibble superior de este registro no tiene ningún efecto en el timer0, pondré a ceros. El nibble inferior consiste en el bit PSA (bit 3) que determina que el prescaler se asigna, temporizador 0 o el temporizador de vigilante. Quiero dividir la tasa de avance del registro temporizador timer 0, así que tenemos que ponerlo a 0. A continuación, quiero configurarlo para dividir el reloj tanto como puede 1:256. Para lograr esto, debo configurar los bits de PS2:PS0 111. El resultado se establece en 0b00000111 OPTION_REG = 0x07.
Configuración de INTCON
Este registro tiene poco que ver con el timer 0 es un registro de configuración de la interrupción, pero – ya que estamos utilizando interrupción del temporizador 0 – tengo que mencionarlo. Los tres bits que se relacionan con temporizador 0 son los siguientes: GIE, T0IF, T0IE.
GIE es el bit que habilita interrupciones a nivel mundial, si este está establecido a 0, no se activarán ninguna interrupción. Por supuesto, tenemos que poner este a 1.
T0IE es una interrupción habilitar bits demasiado, pero esto es estrictamente allí para habilitar o deshabilitar la interrupción del temporizador 0. Tenemos que poner este a 1 también.
T0IF es el bit de bandera de interrupción de timer 0 que se establece cada vez que el temporizador 0 registrar desbordamientos, tenemos que borrar este bit en el arranque, se establecerá por hardware, una vez que el registro del temporizador alcanza el valor máximo y se desborda. Por lo tanto, T0IF debe ser fijado a 0.
Tenemos que configurar INTCON para 0b11100000 = 0xE0 para hacer este temporizador funcionan de la manera que queremos.
Otras cosas que hay que hacer
Para crear el calendario exacto de milisegundos una, vamos a tener que cargar previamente el registro del temporizador. El número de pasos divididos por 256 (debido al prescaler que elegí) agregan a este valor de precarga del timer debe dar el valor de desbordamiento del registro de contador de tiempo. En nuestro caso este valor es 256, ya que estamos utilizando un temporizador de 8 bits.
Lo que sabemos:
- oscilador de reloj = 8 MHz
- reloj de instrucción = 2 MHz
- período de instrucción = 500 ns
- prescaler usado = 1:256
- momento queremos = 10 ms
Las cosas que queremos saber:
- valor del temporizador de carga previo registro.
Sabemos que queremos un 10 ms tiempo, y sabemos que nuestro contador de tiempo camina a una velocidad de 256 * 500 ns. Problemas que multiplicación nos dice que el registro del temporizador 0 avanzará cuando pasa de 128 μs. 10 ms / 128 μs = 78, este número es importante porque expresa nuestras ms 10 en número de pasos de temporizador. Sabemos que queremos que el temporizador registro desbordamiento después de 10 ms, y sabemos que esto ocurre después del valor máximo de 8 bits, 255. Bastante simple, solo tenemos que poner 256 – 78 = 178 en el registro del temporizador y espere a que el indicador del sistema. Esto sucederá después de 10 ms.
Esto no es suficiente, que también tenemos que actualizar el registro de contador de tiempo con este valor después de cada derrame. Si somos capaces de hacerlo, el registro de contador de tiempo cuenta a partir de cero y los tiempos serán totalmente apagados (128 μs * 256 es no 10 ms).
He mencionado cómo estos indicadores de desbordamiento pueden provocar interrupciones (puede y voluntad, ya que hemos habilitado esta característica en el registro INTCON). Las interrupciones son manejadas en una parte especial del programa llamada una rutina de servicio de interrupción. Cuando se activa una interrupción, el programa Salta a esta parte especial del programa y ejecuta. Después se ejecuta esa parte del código (a menudo denominado la interrupción manipulada), el programa continúa donde se quedó antes de la interrupción fue señalizada. Esto permite que un programador reaccionar rápidamente a este tipo de eventos, de hecho, esta es la razón por qué interrupciones fueron "inventadas". Las rutinas de servicio de interrupción deben hacerse cortas, por lo que su ejecución es bastante rápida. Escribí el registro de contador de tiempo de recarga en la rutina de servicio de interrupción, esto garantiza que el temporizador 0 desbordamientos ocurrirá una y otra vez después de 10 ms. La bandera de interrupción debe ser limpiada demasiado, o bien el procesador "pensará" que está siendo señalizada una interrupción, se atranca en la rutina de servicio y no puede llegar otra vez el código principal. Esto es un error clásico y puede retener durante mucho tiempo.