Stellaris Launchpad + Energia (pt. 2 – Timers)

En el post anterior, pudimos comprobar lo facil que nos va a resultar usar al Stellaris Launchpad con el IDE Energía, como reemplazo del Arduino.

En este post vamos a revisar como usar las interrupciones del timer, para poder ejecutar eventos periódicamente. El Launchpad que estamos usando (LM4F120XL) tiene 27 timers que pueden ser activados independientemente.

Para poder utilizar el timer, en este caso el Timer 0 del Launchpad, necesitamos implementar 2 rutinas: 1 de inicialización y otra de interrupción. Para nuestro ejemplo, las rutinas son las siguientes:

Inicialización:

void initTimer(unsigned Hz)
{
  SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
  TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
  unsigned long ulPeriod = (SysCtlClockGet() / Hz) / 2;
  TimerLoadSet(TIMER0_BASE, TIMER_A, ulPeriod -1);
  IntEnable(INT_TIMER0A);
  TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
  TimerIntRegister(TIMER0_BASE, TIMER_A, Timer0IntHandler);
  TimerEnable(TIMER0_BASE, TIMER_A);
  
}

Interrupción:

void Timer0IntHandler()
{
  
  TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
  digitalWrite(RED_LED, j&0x01);  
  j++;

}

Como podemos observar, la rutina de inicialización recibe como parámetro la frecuencia de activación del timer en Hz. Y la rutina de interrupción, simplemente activa o desactiva el led Rojo, para comprobar la funcionalidad del timer.

El sketch completo sería el siguiente:

#include "Energia.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_ints.h"
#include "driverlib/debug.h"
#include "driverlib/interrupt.h"
#include "driverlib/sysctl.h"
#include "driverlib/timer.h"

int j=0;

void setup()
{
  pinMode(RED_LED, OUTPUT);
  initTimer(1); // timer a 1 hz
  
}

void loop()
{
  // put your main code here, to run repeatedly:
  while(1) {} 
}

void initTimer(unsigned Hz)
{
  SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
  //TimerConfigure(TIMER0_BASE, TIMER_CFG_32_BIT_PER);
  TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
  unsigned long ulPeriod = (SysCtlClockGet() / Hz) / 2;
  TimerLoadSet(TIMER0_BASE, TIMER_A, ulPeriod -1);
  IntEnable(INT_TIMER0A);
  TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
  TimerIntRegister(TIMER0_BASE, TIMER_A, Timer0IntHandler);
  TimerEnable(TIMER0_BASE, TIMER_A);
  
}

void Timer0IntHandler()
{
  
  TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
  digitalWrite(RED_LED, j&0x01);  
  j++;

}