Ir al contenido principal

Timers en MSP430

El MSP430 está provisto de temporizadores (el número de ellos depende de la versión del microcontrolador) que permiten medir intervalos de tiempo y generar eventos basados en tiempo.

MSP430 Launchpad

No hay que confundir los timers con los relojes de tiempo real que también equipa el MSP430.

Timers MSP430

Hay dos tipos de timers, Los Timers_A y los Timers_B. Ambos son muy similares, y aunque los de tipo B poseen alguna característica más que los A, aquí no vamos a profundizar en ello.

Alguna de las características de los timers son:

  • Utilizan un contador de 16 bits con cuatro modos de operación.
  • Pueden seleccionar y usar diferentes fuentes de reloj.
  • Utilizan registros de captura/comparación para su configuración.
  • Permiten salidas PWM (Power Width Modulation).
  • Pueden usar interrupciones.
Nos apoyaremos en el siguiente esquema de un Timer_A para ver cómo se utiliza.

Timer A

Hay dos tipos de bloques bien diferenciados. Rodeado de verde está el bloque contador, y de azul el bloque de captura/comparación, de los que puede haber hasta siete en cada timer.

Bloque contador

El bloque contador dispone de un contador de 16 bits llamado TAxR (donde x será 0 para el timer TA0 y así sucesivamente). Para controlar este bloque se utiliza el registro TAxCTL.

Registro TAxCTL
  • El campo TASSEL nos permite seleccionar la fuente de reloj.
  • El campo ID permite dividir la frecuencia del reloj.
  • El campo MC permite seleccionar el modo de funcionamiento del contador.
  • El campo TACLR pone a cero el contador TAxR.
  • El campo TAIE habilita las interrupciones generadas por el timer.
  • El campo TAIFG indica si se ha producido una interrupción. Generalmente es un campo para consulta.
Como se puede observar en el campo MC, disponemos de cuatro modos de cuenta:
  • Stop mode (00b): El timer está parado.
  • Up mode (01b): El timer cuenta hasta el valor almacenado en el registro TAxCCR0 y vuelve a empezar desde 0.
  • Continuous mode (10b): El timer cuenta hasta el valor fijo 0xFFFF y vuelve a contar desde 0.
  • Up/Down Mode (11b): El timer cuenta ascendentemente hasta el valor almacenado en el registro TAxCCR0 y después descendentemente hasta 0.
En el esquema vemos que, además del divisor de frecuencia controlado por el campo ID, hay otro más. Este se controla a través del registro TAxEX0.

Registro TAxEX0

Bloque de captura/comparación

Este bloque se controla mediante el registro TAxCCTLn.

TAxCCTLn_1
TAxCCTLn_2
TAxCCTLn_3

Vamos a analizar el uso básico de los contadores, así que nos centraremos en el modo comparación. Así pues, el modo captura no lo analizaremos en este artículo.

El campo CAP nos permitirá seleccionar el modo captura o el modo comparación. Por otro lado, el campo CCIFG del registro TAxCCTLn se activa cuando el valor de la cuenta del registro TAxR alcanza el valor del registro TAxCCRn.

El timer puede generar dos tipos de interrupciones. Por un lado, mediante el bit TAIE del registro TAxCTL podemos generar una interrupción cada vez que el contador alcance el valor 0. El segundo tipo de interrupciones se desencadenan cuando el valor de la cuenta del registro TAxR ha alcanzado el valor almacenado en el registro TAxCCRn (TAxCCRn CCIFG), se habilitan mediante el bit CCIE del registro TAxCCTLn.

Código de ejemplo

Para aclarar conceptos los mejor es analizar un código de ejemplo en el que vamos a poner en práctica lo que se ha visto hasta ahora.

 

#include <msp430.h>
void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;    // Detiene Watchdog
  P1DIR |= BIT0;               // P1.0 salida
  P1OUT |= BIT0;               // Enciende LED  
  // Configuración TIMER_A:
  // TimerA1, ACLK/1,modo up, reinicia TACLR
  TA1CTL = TASSEL_1 | TACLR | MC_1; 
  // ACLK tiene una frecuencia de 32768 Hz
  // Carga cuenta en TA1CCR0 0.1seg TA1CCR=(0,1*32768)-1
  TA1CCR0 = 3276;  
  TA1CCTL0 = CCIE; // Habilita interrupción (bit CCIE)
  // LPM0, habilitación general de interrupciones
  __low_power_mode_0(); 
  __no_operation();
}

// Rutina de interrupción de TIMER1_A0  
#pragma vector=TIMER1_A0_VECTOR
__interrupt void TIMER1_A0_ISR(void){
  P1OUT ^= 0x01;       // conmuta LED en P1.0
}
Este código hace cambiar de estado, cada 0,1 segundos, el LED conectado al puerto P1.0. Para ello se ha programado la interrupción asociada al timer A1. Mediante la siguiente línea se configura el timer  A1 para que utilice el reloj ACLK y configuración en modo UP. También se inicializa el contador poniéndolo a cero.
TA1CTL = TASSEL_1 | TACLR | MC_1;
La interrupción se produce cuando el contador llega al valor almacenado en el registro TACCR0, así que sabiendo que, en este caso, ACLK funciona a una frecuencia de 32768Hz podemos calcular qué valor hay que almacenar en dicho registro. Si quisiéramos que el LED cambiara de estado cada segundo lo tendríamos fácil. Simplemente haríamos TACCR0=32768-1 (siempre restaremos uno al valor deseado). Esto es así porque ACLK cambia de estado 32768 veces en un segundo. Para que el LED cambie un valor arbitrario de veces n usamos la formula TACCR0=(tiempo en segundos * freq. de reloj en Hz)-1.

Así pues, para que cambie de estado cada 0,1 segundos hacemos TA1CCR0=(0,1*32768)-1=3276.

TA1CCR0 = 3276;
Finalmente habilitamos la interrupción del timer mediante el bit CCIE.
TA1CCTL0 = CCIE;
Al entrar en modo LPM0 también estamos activando las interrupciones.

En el siguiente vídeo podemos ver el resultado de la ejecución del anterior código.

Comentarios

Entradas populares de este blog

Creando firmas de virus para ClamAV

ClamAv es un antivirus opensource y multiplataforma creado por Tomasz Kojm muy utilizado en los servidores de correo Linux. Este antivirus es desarrollado por la comunidad, y su utilidad práctica depende de que su base de datos de firmas sea lo suficientemente grande y actualizado. Para ello es necesario que voluntarios contribuyan activamente aportando firmas. El presente artículo pretende describir de manera sencilla cómo crear firmas de virus para ClamAV y contribuir con ellas a la comunidad.

Ingeniería inversa de un parche de Microsoft Windows

A estas alturas ya hemos asumido que la seguridad total en Internet es, cuanto menos, un mito. Ningún software está libre de vulnerabilidades, y por mucha auditoría, test de intrusión o pruebas de fuzzing que nos empeñemos en hacer, ninguna metodología puede demostrar sin lugar a dudas que un software es 100% seguro. Ante este panorama, hay dos tendencias mayoritarias a la hora de hacer públicas las vulnerabilidades. Por un lado, están los que piensan que cuando se descubre un fallo ha de hacerse público de forma inmediata. En este escenario, la publicación de una vulnerabilidad es el pistoletazo de salida para una carrera entre el desarrollador para sacar el parche y los "malos" para lograr explotarla. Esta política es conocida como full disclosure . Por otro lado, tenemos a los siguen una política responsible disclosure , que abogan por mantener la vulnerabilidad en secreto hasta la salida del parche por parte del desarrollador. Sin entrar en cuestiones filosóficas que no...

Manejo de grafos con NetworkX en Python

El aprendizaje computacional es un área de investigación que en los últimos años ha tenido un auge importante, sobre todo gracias al aprendizaje profundo (Deep Learning). Pero no todo son redes neuronales. Paralelamente a estas técnicas, más bien basadas en el aprendizaje de patrones, también hay un auge de otras técnicas, digamos, más basadas en el aprendizaje simbólico. Si echamos la vista algunos años atrás, podemos considerar que quizá, la promesa de la web semántica como gran base de conocimiento ha fracasado, pero no es tan así. Ha ido transmutándose y evolucionando hacia bases de conocimiento basadas en ontologías a partir de las cuales es posible obtener nuevo conocimiento. Es lo que llamamos razonamiento automático y empresas como Google ya lo utilizan para ofrecerte información adicional sobre tus búsquedas. Ellos lo llaman Grafos de Conocimiento o Knowledge Graphs . Gracias a estos grafos de conocimiento, Google puede ofrecerte información adicional sobre tu búsqueda, ad...