了解定时器和中断周期

发布于 2024-11-28 22:51:38 字数 1855 浏览 1 评论 0原文

我很难理解一些在我拥有的 ARM 板上使用定时器和中断的代码。定时器基本上在每次中断时都会在打开和关闭之间切换 LED,使其闪烁。

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<<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;
    };
}

现在,LED 每秒闪烁的速度我无法确定。我希望它每秒闪烁一次。但是,我不明白整个比较和重新加载。

有人可以更好地解释这段代码吗?

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<<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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦在深巷 2024-12-05 22:51:38

由于计时器是特定于供应商和部件的功能(不是 ARM 架构的一部分),因此我只能提供一般指导,除非您提到您正在处理哪个 CPU 或微控制器。

定时器有几个特性:

  1. 大小,例如 16 位,这意味着它们可以从 65535 向上或向下计数。
  2. 时钟输入,以时钟频率给出(可能来自 CPU 时钟或外部晶体),以及预分频器它将时钟频率除以另一个值(或除以 1)。
  3. 溢出中断 - 当定时器回绕到 0 时,通常可以选择触发中断。
  4. 比较中断 - 当定时器达到设定值时,它将发出中断。

就您而言,我可以看到您正在使用计时器的比较功能。通过确定定时器时钟输入并计算预分频器和比较寄存器的新值,您应该能够实现 1 Hz 的速率。

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.

顾忌 2024-12-05 22:51:38

在尝试理解您找到的代码之前,请先了解定时器外围单元的工作原理,然后了解如何配置其寄存器以获得所需的输出。

定时器外围单元如何工作?
这是与CPU和其他外设一起嵌入到微控制器中的硬件模块。微控制器内部的各个外围模块均与公共时钟源同步。参考代码,定时器外设时钟为 24 MHz,然后预缩放 128,这意味着它将工作在 187500 Hz。现在该频率将取决于时钟配置和振荡器。

现在定时器单元有一个计数器寄存器,它可以计数到它的位大小,通常可以是 8,16 或 32。一旦启用计数,该计数器就会在上升沿、下降沿或双沿开始向上计数或向下计数。现在您可以选择是要向上计数(从 0 到 255,对于 8 位)还是向下计数(从 255 到 0),并且您想要在哪个时钟沿进行计数。

现在,在 187500 Hz 下,1 个周期 = 5.333333 us,如果您在 1 个周期中在上升沿或下降沿计数一次,例如,如果计数器值 = 100(向上计数),则经过的总时间为 5.33333*100=533us。现在您必须为计数器设置一个比较值来设置此周期,这取决于您的闪光速率。该比较值将通过定时器的比较器与您的计数器值进行比较,一旦匹配,如果您在比较匹配时启用了中断生成,它将发送一个中断信号,您可以在其中切换 LED。

我希望您已经了解计时器的工作原理。
在您的示例代码中,定时器配置为以 10Hz 的速率获取比较匹配事件。所以比较值是187500/10 = 18750。,1秒你可以保持它187500/1。
你有定时器控制寄存器TMR0_CTRL,你可以在其中配置是否要向上计数或向下计数,在下降沿/上升沿/双边沿上计数,仅计数一次/连续,计数到比较值然后重置或继续计数直到极限。各位字段的详细信息请参阅微控制器手册。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文