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: TM4C1294 TIVA C Series Run timer every ms

Part Number: EK-TM4C1294XL
Other Parts Discussed in Thread: TM4C1294NCPDT

Hello everyone,

I'm new in MCU and I'm trying to run the timer every millisecond, but I can not find the setting or the calculation. I'm attaching the code I use now for testing just before I get it.

 

Any ideas how to set the timer to run every millisecond?

 

Thank you all. :)

#include <stdint.h>
#include <stdbool.h>
#include "inc/tm4c1294ncpdt.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "driverlib/interrupt.h"
#include "driverlib/gpio.h"
#include "driverlib/timer.h"

uint32_t ui32Period, pom = 0;
uint32_t ui32SysClkFreq;

int main(void)
{
    ui32SysClkFreq = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);

    GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_1);
    TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);

    ui32Period = (ui32SysClkFreq / 50);
    TimerLoadSet(TIMER0_BASE, TIMER_A, ui32Period);

    IntEnable(INT_TIMER0A);
    TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    IntMasterEnable();

    TimerEnable(TIMER0_BASE, TIMER_A);

    while(1)
    {

        if (pom == 1000) {//if 1000ms == 1 sec
            if(GPIOPinRead(GPIO_PORTN_BASE, GPIO_PIN_1))
            {
                GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, 0);
                pom = 0;
            }
            else
            {
                GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, 2);
                pom = 0;
            }
        }

    }
}

void Timer0IntHandler(void)
{
    TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    pom++;

}

  • Hello Petr,

    It looks like you have a good chunk of the setup right. There is one definite flaw, and one other possible issue you may not have addressed.

    The definite flaw concerns the period calculation, you don't have that quite right.

    What you have is

      ui32Period = (ui32SysClkFreq / 50);

    To get 1ms time, that should instead be:

      ui32Period = (ui32SysClkFreq / 1000);

    The other issue could be that you don't have your Timer0IntHandler added to your startup_ccs.c file correctly. If you run the code and then pause it in debug, if you land in IntDefaultHandler then you will need to ensure that the Timer0IntHandler ISR is correctly added to the ISR table in the startup_ccs.c file.

  • Hello Ralph,

    it helped a lot. I have Timer0IntHandler () setup correctly.

    Is it chance to used analogously to other time units such as the second or microsecond ?

    ui32Period = (ui32SysClkFreq / 1 000); --> 120 000 000 / 1000 = 1ms

    If i use divide by 1 000 000, is it a second?


    If you had an idea how to check and verify the time of the timer, other than the stopwatch?

    I would greatly appreciate it. :-)

    Thank you very much.
  • 1. Not clear what you meant by "run a timer"

    2. Your isr gets called every 20ms.

    3. Your pom is reset in both branches of the if statement.

  • Hello,

    1) I want to made timer interrupt every millisecond and then stack up for 1000 (to one second)

    2) This was a problem... Please, can you tell me how exactly may I count a right number for period as 1 ms, 5 ms, 100ms etc...

    1000 is 1 ms, i know it now but others?

    count for period
    ui32Period = (ui32SysClkFreq / 1000);

    3) This is i was rebuilded now

    Thank you
  • Petr Tichota said:
    If you had an idea how to check and verify the time of the timer, other than the stopwatch?

    If it proves,  "Acceptable" -  you may  "Toggle" (flip/reverse the state) a GPIO upon each entry into your  "1mS"  Timer's ISR.     This GPIO then is monitored via an oscilloscope - set to properly 'frame' such a signal.

    It proves also possible - once you've "Mastered Timer Operation" - to employ (another) MCU Timer - commanded into,  'EDGE TIME MODE' - to achieve the identical measurement - yet (minus) the burden of oscilloscope deployment...     In this case - you would, "Feed the GPIO Output" (as described above) into the 2nd Timer's (GPIO) pin - which is programmed to measure the 'Edge Time.'

    Thus - provided here - 'TWO SOLUTiONS'  (discounted ONLY today) for the price of ONE!     (Neat Verify would reduce the price - even further...)

  • Hello Petr,

    The formula is essentially boiled down to Timer Count = Clock Frequency / Period. I think you have caused some self confusion in that you labeled the variable ui32Period. It would be more accurate to label it as ui32TimerLoadValue or something similar.

    The TimerLoadSet API requires the Timer info and then a Value to be loaded into the timer. This value is what is used for counting based on clock cycles. The clock cycle speed of the MCU is determined by SysClk, so that is where the ui32SysClkFreq comes into place which gives you the frequency of the system as a measure of Hz, which unit wise is 1/seconds.

    What you want to then do is multiply the Frequency with your desired Period (unit in seconds) which will get the units cancel out and leave you the raw number needed to be loaded into the timer.

    So for example, to get one millisecond, the calculation from a mathematical standpoint is 120 000 000 * 0.001 seconds. But 0.001 seconds can also be displayed as 1/1000 seconds. And it is that style of display that you see in the code as that is easier to read/understand for most.

    Therefore to get a one second period, you would load the clock frequency itself. What you described with loading 1 000 000 would actually be for a microsecond as you'd be inputting a period of 1/1 000 000 seconds, i.e. 10^-6, i.e. a microsecond!

    I hope my explain is written clear enough.
  • "how exactly may I count a right number for period as 1 ms, 5 ms, 100ms etc..."

    it depends on your skills and your application.

    in general, you want to set up the timer to interrupt every 1ms. In that ISR, you want to increment a counter.

    in your application you take a snap shot of that timer, and then test to see if enough time has passed since the last invocation. If yes, update it.

    here is one example:

    volatile uint32_t millies=0; //counter for ms. it gets incremented in the timer isr

    //test if enough has passed: returns 1 if 5ms has passed
    char passed_5ms(void) {
    static uint32_t millis_prev=0; //time stamp for previous invocation
    if (millis - millis_prev > 5) {millis_prev+=5; return 1;}
    else return 0;
    }

    again, without knowing what you are trying to do, it is hard to help any better.
  • Danny F said:
    again, without knowing what you are trying to do, it is hard to help any better.

    Even  a (single) CAP would help...