开发者

Understanding timer and period of interrupts

开发者 https://www.devze.com 2023-03-27 14:08 出处:网络
I am having a hard time understanding some code I found for using a timer and interrupts on an ARM board I have. The timer basically toggles an LED every interrupt between on and off to make it flash.

I am having a hard time understanding some code I found for using a timer and interrupts on an ARM board I have. The timer basically toggles an LED every interrupt between on and off to make it flash.

void main(void) {

    /* Pin direction */
    led_init();

    /* timer setup */
    /* CTRL */

    #define COUNT_MODE 1      /* Use rising edge of primary source */
    #define PRIME_SRC  0xf    /* Peripheral clock with 128 prescale (for 24 MHz = 187500 Hz)*/
    #define SEC_SRC    0      /* Don't need this */
    #define ONCE       0      /* Keep counting */
    #define LEN        1      /* Count until compare then reload with value in LOAD */
    #define DIR        0      /* Count up */
    #define CO_INIT    0      /* Other counters cannot force a re-initialization of this counter */
    #define OUT_MODE   0      /* OFLAG is asserted while counter is active */

    *TMR_ENBL     = 0;                    /* TMRS reset to enabled */
    *TMR0_SCTRL   = 0;
    *TMR0_CSCTRL  = 0x0040;
    *TMR0_LOAD    = 0;                    /* Reload to zero */
    *TMR0_COMP_UP = 18750;                /* Trigger a reload at the end */
    *TMR0_CMPLD1  = 18750;                /* Compare one triggered reload level, 10 Hz maybe? */
    *TMR0_CNTR    = 0;                    /* Reset count register */
    *TMR0_CTRL    = (COUNT_MODE<<13) | 
                    (PRIME_SRC<<9)   | 
                    (SEC_SRC<<7)     | 
                    (ONCE<&l开发者_如何学Got;6)        | 
                    (LEN<<5)         | 
                    (DIR<<4)         | 
                    (CO_INIT<<3)     |
                    (OUT_MODE);
    *TMR_ENBL     = 0xf;                  /* Enable all the timers --- why not? */

    led_on();

    enable_irq(TMR);

    while(1) {
        /* Sit here and let the interrupts do the work */
        continue;
    };
}

Right now, the LED flashes at a rate that I cannot determine per second. I'd like it to flash once per second. However, I do not understand the whole comparison and reloading.

Could somebody better explain this code?


As timers are a vendor- and part-specific feature (not a part of the ARM architecture), I can only give general guidance unless you mention which CPU or microcontroller you are dealing with.

Timers have several features:

  1. A size, for instance 16 bits, which means they can count up or down to/from 65535.
  2. A clock input, given as a clock frequency (perhaps from the CPU clock or an external crystal), and a prescaler which divides this clock frequency to another value (or divide by 1).
  3. An interrupt on overflow - when the timer wraps back to 0, there is usually an option to trigger an interrupt.
  4. A compare interrupt - when the timer meets a set value it will issue an interrupt.

In your case, I can see that you are using the compare feature of your timer. By determining your timer clock input, and calculating new values for the prescalers and compare register, you should be able to achieve a 1 Hz rate.


Before trying to understand the code you found, please do understand how a Timer Peripheral Unit works, then understand how you can configure it's registers to get the desired output.

How a Timer Peripheral Unit works? This is hardware module which is embedded into micro controller along with CPU and other peripherals. Every peripheral modules inside micro controller are synchronized with common clock source. With reference to the code, Timer peripheral clock is 24 MHz which is then pre-scaled by 128 which means it will work at 187500 Hz. Now this frequency will depend upon clock configuration and oscillator.

Now Timer unit has a counter register which can count up to it's bit-size which could be 8,16 or 32 generally. Once you enable counting, this counter starts up-counting or down-counting the rising or falling or on both edges. Now you have choices whether you want to up-count (from 0 towards 255, for 8-bit) or down count (from 255 towards 0) and you want to count on which clock edge.

Now, at 187500 Hz, 1 cycle = 5.333333 us, if you are counting once in 1 cycle either at rising or at falling edge and e.g, if counter value = 100 (Up counting), total time elapsed is 5.33333*100=533us. Now you have to set a compare value value for the counter to set this period which will depend upon your flash rate. This compare value will be compared against your counter value in by comparator of Timer and Once it matches it will send an interrupt signal if you have enabled interrupt generation on compare match, where you can toggle you LED.

I hope you have understood How a Timer works. In your sample code, Timer is configured to obtain a compare match event at the rate of 10Hz. so compare value is 187500/10 = 18750., for 1sec you can keep it 187500/1. you have Timer Control Register TMR0_CTRL, where you can configure whether you want to count up or down, count on falling/rising/both edges, count only once/continuous, count upto compare value and then reset or keep counting till it's limit. Refer to micro controller manual for details of each bit fields.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号