Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
关于嵌入式C中的定时器_C_Timer_Embedded_Avr - Fatal编程技术网

关于嵌入式C中的定时器

关于嵌入式C中的定时器,c,timer,embedded,avr,C,Timer,Embedded,Avr,所以我明天要考试。我错过了一次讲座,但我有教授的讲座录音。在讲座中,教授提到我们需要知道计时器在嵌入式处理器中是如何工作的 我有一个基本的理解,但我对数学部分感到困惑。教授说,例如,他将给我们一个以某个速率X运行的12位计时器。我们必须先设置计时器值,然后等待它溢出。如果我们想让计时器等待3毫秒,我们应该将计时器设置为什么 此外,教授说,“这是一个简单的数学,给我们时钟等于1000000,时间将是1000,所以我们可以很容易地进行除法。” 谁能解释一下定时器是如何工作的,我需要做些什么才能正确地

所以我明天要考试。我错过了一次讲座,但我有教授的讲座录音。在讲座中,教授提到我们需要知道计时器在嵌入式处理器中是如何工作的


我有一个基本的理解,但我对数学部分感到困惑。教授说,例如,他将给我们一个以某个速率X运行的12位计时器。我们必须先设置计时器值,然后等待它溢出。如果我们想让计时器等待3毫秒,我们应该将计时器设置为什么

此外,教授说,“这是一个简单的数学,给我们时钟等于1000000,时间将是1000,所以我们可以很容易地进行除法。”


谁能解释一下定时器是如何工作的,我需要做些什么才能正确地得到数学部分。

大多数嵌入式定时器的工作原理如下:

  • 将计时器设置为某个初始值T
  • 启动计时器
  • 定时器每时钟递减一次
  • 当定时器达到0(或下溢超过0)时,产生中断
因此,经过的时间将只是
T/timer\u clock\u rate
,其中T是初始计时器值,
timer\u clock\u rate
将取决于您如何配置计时器

因此,例如,如果您想要3毫秒的延迟,并且您的计时器时钟频率为1 MHz(即计时器每1µs递减一次),那么您需要3000(3000 x 1µs=3毫秒)的初始计时器值


编辑:另请参见@Rev1.0的答案-显然AVR定时器是向上计数而不是向下计数-请注意,其他一些微控制器系列使用倒计时定时器。然而,同样的一般原则也适用于这两种情况,但根据你是向上计数还是向下计数,你将加载的初始常数将有所不同。

虽然保罗的例子可能足以让你了解它是如何工作的,但它解决的问题与你的问题有所不同

当计时器达到最大值时,会发生上述溢出。对于12位计时器(2^12),这将是4096。如果给定的时钟频率为1MHz(每滴答1us),你必须数到3000才能得到3ms,就像保罗已经指出的那样


因此,您可以将计时器的初始值设置为4096-3000=1096,以在3ms后获得溢出。

只需按照尺寸进行操作即可。X是每秒的周期数,假设一个刻度是一个周期(如果有一个预分频器,那么这里还有另一个调整,计时器以刻度计)。一秒钟是1000毫秒。所以,只要把所有这些维度都安排好,这样它们就可以相互抵消,只留下你想要的一个维度

1 tick     X cycles   1 second            3 milliseconds
-------- * -------- * ----------------- * -------------- 
1 cycles   1 second   1000 milliseconds
把所有的单位都除掉。从小学数学(几乎)来说,任何除以它本身的东西都是一,只要把它应用到单位上就行了。离开:

1 tick    X     1       3 
------ * --- * ----- * --- 
1         1    1000 
所以无论你的定时器时钟源频率是多少,以每秒周期数(Hz)为单位,乘以3,再除以1000。如果该时钟频率为1000000,则(1000000*3)/1000=3000

这就是为什么你可以很容易地计算出什么是乘什么是除,对每一种风格的转换都有效。英里/小时到公里/秒,随便什么

然后按照Rev1.0的答案或Paul R

有时,您必须注意一件N-1的事情,这件事情要么记录在案,要么您可以进行测试。例如,如果您有一个向下计数器,文档会/应该说如果计时器在达到零或之后滚动或中断,通常是在之后,当实际滚动发生时,因此3000到0(包括3000到0)是3001计数,您会稍微关闭一点,因此对于这样的系统,您需要使用2999编程计时器以获得3000个刻度。对于递增计数器,它通常是两种方式之一,从0计数到编程值,相同的交易计数从0到2999,以获得3000计数,因此您可能会在寄存器中编程2999,而不是3000。或者,您编程的值是Rev1.0显示的开始计数,滚动是在所有1的值之后,不管寄存器大小是什么,在这种情况下,他们告诉您12位是0xFFF,不要犯0xFFF-3000错误,得到1095,很容易做到,就像Rev1.0显示的那样(0xFFF+1)-3000=4096-3000=1096,这是您的开始计数

对于预分频器也是一样,你必须非常仔细地阅读他们说的话,你是将2除以2还是将1除以2?如果编程为0,则会发生什么情况?被1除或无效,或被最大值除,或除数设置无效?这与量纲分析有什么关系?滴答声/周期。一个除以8的预分频器意味着每8个周期你会得到一个刻度,这就是1刻度/8个周期

现在,有时你会有一个系统时钟,为外围时钟分频,外围时钟为计时器供电,那么你可能会有一个预分频器,所以n个系统时钟/1个外围时钟,然后1个外围时钟/1个计时器时钟,然后1个刻度是M个计时器时钟。把所有的东西都排好,这样除了一个就可以取消了

你也可以反过来做,你会也应该这样做。从现在的数字来看,3000个计时器滴答声是3ms或0.003秒。3000/0.003为每秒滴答数或每秒1000000个周期

但是如果我们有一个不同的控制器或者一个不知道时钟的控制器(或者我们知道一个水晶,但我们怀疑在文档中找不到一个预分频器),那么让计时器滚动4096个滴答声,例如,我们用秒表或示波器或其他东西测量它,在这两种情况下都不太准确,但可能会给我们一个足够粗略的想法,以确定是否有预分频器,或者如果有一个pll乘以时钟,我们实际运行的是什么时钟,等等。假设每4096个计时器滴答声为0.0005秒,4096/0.0005=8192000 hz。现在,如果示意图中的晶体/振荡器或者我们可以读出零件上的16Mhz,那么8000000/4096=0.000512是有意义的,8Mhz是16Mhz的一半,
while(1)
{
while((read_timer()&0x1000)==0) continue;
turn_gpio_on();
while((read_timer()&0x1000)!=0) continue;
turn_gpio_off();
}