¿Es posible tener varias rutinas ISR para un solo temporizador en el microcontrolador?

Tengo dudas de que el microcontrolador admita múltiples rutinas de interrupción para un solo temporizador.

Por ejemplo, un solo temporizador que interrumpe a los 5 ms, 10 ms, 1 s, etc. En mi diseño, estoy usando 3 temporizadores: un temporizador interrumpe cada 1 ms para verificar el estado, otros dos a los 50 ms y 1 s.

Tengo curiosidad por saber por qué no puedo tener un controlador que tenga más de un ISR y también, en lugar de interrupciones en el desbordamiento del temporizador, por qué no puede interrumpir en su coincidencia de período.

Explique qué es lo que está tratando de hacer, qué ha intentado y cuáles son sus preguntas. En este momento, votaré para cerrar, ya que esta pregunta de dos oraciones no demuestra ninguna de estas cosas y muestra una falta de respeto básica por las personas que intentan ayudarlo.
En mi diseño, estoy usando 3 temporizadores en los que un temporizador interrumpe cada 1 ms para alguna verificación de estado, otros dos a 50 ms y 1 s. Tengo curiosidad por saber por qué no puedo tener un controlador que tenga más de ISR y también, en lugar de interrupciones. en el desbordamiento del temporizador, ¿por qué no puede interrumpir en su período de coincidencia?
Gracias por editar la pregunta y completar algunos detalles más. He votado para reabrir ahora y puedo dar una respuesta una vez que se haya reabierto.

Respuestas (4)

Puede haber algunos que tengan esta capacidad, pero la mayoría no. Deberá mantener un recuento de los ciclos transcurridos y delegar a la rutina adecuada a partir de ahí.

si es posible, ¿podría nombrar algunos controladores, de modo que verifique su hoja de datos?
Nunca he encontrado ninguno con esta capacidad.
El Coldfire que usamos tiene un temporizador de propósito general que tiene un registro de temporizador "maestro" que tiene múltiples interrupciones de comparación/conteo de hardware colgando, que es más o menos la funcionalidad que está buscando. Sin embargo, solo agregaría una verificación matemática de una línea o un contador estático a la interrupción del temporizador, lo que le permitiría hacer algunas cosas cada vez que el contador es un módulo de un número determinado.
Al menos algunos dispositivos MSP430 admiten múltiples registros de captura/comparación dentro de un solo bloque de temporizador. Por ejemplo, consulte la Guía del usuario de MSP430 Series 5 . El registro de captura/comparación 0 genera una interrupción y los otros registros de captura/comparación generan otra interrupción. Dentro de esta otra interrupción, puede determinar qué registro de captura/comparación inició la interrupción y comportarse adecuadamente. Con un solo bloque de temporizador MSP430, puede generar múltiples (hasta siete) interrupciones periódicas con diferentes frecuencias.
@kkrambo: Tal vez diferentes tiempos, pero todos comparten la misma frecuencia ya que el temporizador es en su mayor parte de ejecución libre.

No, pero hay muchos microcontroladores con múltiples temporizadores, cada uno de los cuales puede generar interrupciones en diferentes intervalos.

Por supuesto, cada temporizador necesitará su propia rutina de interrupción. No parece que quiera tratar su interrupción de 5 ms como una interrupción de 1 s, pero si estuviera totalmente decidido a ese tipo de arquitectura, todas las rutinas de interrupción pueden tener el mismo código. Eso, por supuesto, consumiría algo de memoria de programa adicional, incluso si solo tiene todas las interrupciones llamando a la misma subrutina.

Solo puedo hablar por AVR, pero sé que el que usé solo tenía 2-3 temporizadores. Pero no veo la necesidad de usar múltiples temporizadores. Simplemente puede usar uno donde el preescalador del temporizador y el valor de comparación están configurados donde se lanza un ISR de coincidencia de comparación en algún intervalo de tiempo conocido (cada 1 ms, por ejemplo). Luego puede realizar un seguimiento del tiempo y tener una declaración de cambio para controlar qué acción desea realizar.

¿Qué pasa si tienes un bucle lento y un bucle rápido? ¿Qué sucede si necesita realizar un seguimiento de un tiempo de espera? ¿Qué pasa con el uso de un temporizador para un rebote de software? Esos temporizadores múltiples no se han colocado en el paquete porque sobraba espacio.
Nunca dije que un temporizador fuera todo lo que se necesitaba para todos los problemas que ha mencionado. Sus costuras que todo el operador está buscando es una forma de realizar diferentes procedimientos en función del tiempo y esto se puede hacer con un temporizador.

El temporizador ISR con período variable es bastante fácil de lograr.

Variante 1. Los temporizadores suelen tener un registro de cuenta atrás, que puede ser actualizado por el código. El valor inicial de la cuenta regresiva se puede actualizar dentro del propio ISR caso por caso. Se puede usar una máquina de estado para decidir qué valor inicial asignar al contador.

Variante 2. Otra opción es configurar el temporizador para la duración más corta y luego contar las interrupciones si necesita una duración más larga. Por ejemplo, debe hacer 3 cosas diferentes cada 5 ms, 10 ms, 1 s. Establezca el temporizador en 5 ms, dentro del ISR incremente un contador** cada vez que se llame a ISR. En el main()bucle, compare el contador con los umbrales. Para una duración de 10 ms, el umbral sería 2, para 1 s, el umbral sería 200. Una vez que el contador es igual al umbral, hace lo main()que debe hacerse en ese intervalo. Lo bueno de este enfoque es que puede tener un temporizador y un ISR, pero varios umbrales (también varios contadores, si es necesario). El tiempo variable se implementaría en el código, en lugar de en el temporizador de hardware.
Tenga en cuenta que este enfoque requiere unmain()bucle, que siempre se repite más rápido que el intervalo más corto. También se debe considerar la precisión del tiempo. Si eso se convierte en un problema, existen variaciones de este patrón, que pueden funcionar con un main()ciclo más lento.

** el contador y las banderas son variables globales visibles tanto para ISR como paramain()

Desafortunadamente, muchos temporizadores están muy restringidos en cuanto a las circunstancias (si las hay) en las que se pueden escribir sus registros de cuenta regresiva sin agregar una incertidumbre considerable a los tiempos resultantes. Un diseño más agradable, si el hardware lo admite, es usar un contador que simplemente se ejecuta continuamente y nunca se escribe, junto con un registro de "comparación". Es posible que deba verificar después de escribir el registro de comparación para asegurarse de que el contador no haya pasado el valor deseado mientras estaba escribiendo (activar la interrupción lo antes posible si eso sucede), pero esto permite una sincronización más limpia que los temporizadores de cuenta regresiva.