LPCXpresso es un IDE de la compañia NXP (antiguamente Philips Semiconductors) basado en Eclipse y que nos permite programar placas de desarrollo de una manera muy sencilla. En la web no hay demasiada información pero sí son muy útiles los ejemplos que hay en las librerías. En mi caso utilizo la placa de desarrolo LPC11U68 con un ARM M0+ (el ARM con menor consumo de los que existen).

M-07710

ARM tiene por defecto un contador llamado SysTick, muy fácil de configurar pero que ofrece poca flexibilidad a la hora de programar. Además el M0+ (desconozco si el resto también) solo cuenta con un contador SysTick. Por este motivo si necesitamos de más de 1 timer en nuestra aplicación deberemos recurrir a los contadores internos del microprocesador. En nuestra caso contamos con 2 contadores de 16 bits y otros dos contandores de 32 bits. El código está comentado y es muy fácil de entender. En caso contrario siempre puedes acudir al datasheet del procesador para entender cómo funciona internamente.

/**
 * @brief	Initialize 32 bits timer for 5 Hz
 * @param	void
 * @return	nothing
 */
void initialize_timers(void){
	uint32_t timerFreq;
        //Inicia el CLK en IOCON para poder modificar las funciones de los pines y en CT32B0 (timer de 32 bits)
        LPC_SYSCTL->SYSAHBCLKCTRL |= (1<<9);
	timerFreq = Chip_Clock_GetSystemClockRate();
	Chip_TIMER_Init(LPC_TIMER32_0);	               //Inicializa el timer CT320 para los 5 Hz
	Chip_TIMER_Init(LPC_TIMER16_0);		       //Inicializa el timer CT160 para los 10 ms
	Chip_TIMER_Reset(LPC_TIMER32_0); 	       //Hace un reset para eliminar configuraciones anteriores
	Chip_TIMER_Reset(LPC_TIMER16_0);	       //Hace un reset para eliminar configuraciones anteriores
	Chip_TIMER_MatchEnableInt(LPC_TIMER32_0, 1);   //Configura el valor al que salta la interrupción
	Chip_TIMER_MatchEnableInt(LPC_TIMER16_0, 1);   //Configura el valor al que salta la interrupción
	//Chip_TIMER_PrescaleSet(LPC_TIMER16_0, PRESCALE_HZ2);  //Preescalado para el timer de 16 bits
        Chip_TIMER_SetMatch(LPC_TIMER32_0, 1, (timerFreq / (TICKRATE_HZ5*2)));	//Configura la duración del timer (0.2 s)
	Chip_TIMER_SetMatch(LPC_TIMER16_0, 1, (timerFreq / (TICKRATE_HZ100*2)));//Configura la duración del timer (10 ms)
	Chip_TIMER_ResetOnMatchEnable(LPC_TIMER32_0, 1);//Configura para que el timer sea cíclico
	Chip_TIMER_StopOnMatchEnable(LPC_TIMER16_0, 1);	//Configura para que el timer no sea cíclico
        Chip_TIMER_Enable(LPC_TIMER32_0);		//Activa el timer
	NVIC_ClearPendingIRQ(TIMER_32_0_IRQn);		//Borra interrupciones pendientes del timer
	NVIC_ClearPendingIRQ(TIMER_16_0_IRQn);		//Borra interrupciones pendientes del timer
	NVIC_EnableIRQ(TIMER_32_0_IRQn);		//Activa la interrupción del timer
	NVIC_EnableIRQ(TIMER_16_0_IRQn);		//Activa la interrupción del timer
}

Un timer, el de 32 bits, saltaría cada 0.2 s (5 Hz) y el otro acabaría a los 100 ms una vez se inicie.

Por razones de mi aplicación el timer de 16 bits no lo activo inmediatamente ni lo configuro para que sea cíclico, si no que es el propio timer de 32 bits el que inicia el de 16.

Para desactivar y activar un timer lo podemos hacer mediante la funcion

Chip_TIMER_Enable(LPC_TIMER16_0);

Por último, para cazar una interrupción deberemos utilizar el siguiente código:

void TIMER32_0_IRQHandler(void){
	if (Chip_TIMER_MatchPending(LPC_TIMER32_0, 1)) {
		Chip_TIMER_ClearMatch(LPC_TIMER32_0, 1);
		//Resto de código...
	}
}
 
void TIMER16_0_IRQHandler(void)
{
	if (Chip_TIMER_MatchPending(LPC_TIMER16_0, 1)) {
		Chip_TIMER_ClearMatch(LPC_TIMER16_0, 1);
                //Resto de código...
	}
}

La precisión para timers de la frecuencia de kHz es muy buena. Como veis, configurar un timer es mucho más complejo que el SysTick, pero con esta receta solo es cuestión de copiar, pegar y editar la frecuencia entre interrupciones.