This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

EK-TM4C1294XL: Trouble Creating Periodic Signal using Timers and Interrupts

Part Number: EK-TM4C1294XL

I'm trying to create a periodic signal using 2 timers since the pin I need is not connected as a CCP.  One timer is periodic at 400 us, and the other timer waits to be triggered before counting up 10 us.  The pin goes high on the 400us timer interrupt, and goes low after 10us on the other timer's interrupt.

The problem is that the high time of the signal will be 10us most of the time, but will vary ~ +/- 4us every once in a while. (According to the oscilloscope)  It does not always stay at 10 us.  What could be the reason for this happening?

I have attached the project for easy testing, and posted a snippet of the code below:

	TimerConfigure(TIMER4_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODIC_UP | TIMER_CFG_B_ONE_SHOT_UP);
	TimerLoadSet(TIMER4_BASE, TIMER_A, (BOARD_CLOCK / TIM5_FREQ) - 1);
	TimerIntDisable(TIMER4_BASE, TIMER_TIMA_TIMEOUT);
	TimerIntClear(TIMER4_BASE, TIMER_TIMA_TIMEOUT);
	TimerIntEnable(TIMER4_BASE, TIMER_TIMA_TIMEOUT);

	TimerLoadSet(TIMER4_BASE, TIMER_B, TIM5B_10US);
	TimerIntDisable(TIMER4_BASE, TIMER_TIMB_TIMEOUT);
	TimerIntClear(TIMER4_BASE, TIMER_TIMB_TIMEOUT);
	TimerIntEnable(TIMER4_BASE, TIMER_TIMB_TIMEOUT);
	TimerControlWaitOnTrigger(TIMER4_BASE, TIMER_B, true);

	TimerEnable(TIMER4_BASE, TIMER_A);
	TimerEnable(TIMER4_BASE, TIMER_B);

void Timer5A_HWI_Fxn(UArg arg)
{
	HWREG(0x40061040) = 0x10; // K4

	// Clear Interrupt
	TimerIntClear(TIMER4_BASE, TIMER_TIMA_TIMEOUT);
}
void Timer5B_HWI_Fxn(UArg arg)
{
	HWREG(0x40061040) = 0; // K4

	// Clear Interrupt
	TimerIntClear(TIMER4_BASE, TIMER_TIMB_TIMEOUT);

	TimerEnable(TIMER4_BASE, TIMER_B);
}

pwmled_TivaTM4C1294NCPDT.zip

  • Hi Petar,
    First of all, why wouldn't you consider using the Timer's PWM mode to generate the PWM with the duty cycle you want? The way you use the interrupt to set and clear the pin is very dependent on what tasks the CPU is doing at the time when the timer interrupt is generated. For example, if the CPU is servicing other higher (non Timer4) interrupts or exceptions. This will have impact on when the Timer4 ISR is entered. In your Timer5A_HWI_Fxn you clear the interrupt right before you exit the ISR. It takes some cycles to actually clear the flag with respect to the time the ISR is exited. It can lead to re-entry of the ISR again. So I will suggest that you place the TimeIntClear in the beginning of the ISR or even better by reading the flag before you exit the ISR. This will guarantee the flag is truly cleared. One last thing is that we discourage people from performing direct register write when the API is available to perform the same function, i.e. GPIOPinWrite().
  • I tried the interrupt clearing fail-safe, and that's not an issue. The attached project is a simple one containing no other interrupts.  I want to try this without PWM.

    I'm just curious why this swing happens.

  • Hi Petar,

    When I imported your project I saw that it is running TI-RTOS. The RTOS itself uses interrupts to switch between tasks. When the time is too short, the 400uS timer happened during an RTOS interrupts and was delayed 4uS. When the time is too long, the 10uS interrupt happened during the RTOS interrupt and was delayed 4us. You can either use the PWM as Charles suggested, or start a project that does not use an RTOS.