定时器定时时间的计算(SystemCoreClock与OS_TICKS_PER_SEC的关系)
Linux下定时器的实现方式分析

Linux 下定时器的实现方式分析定时器属于基本的基础组件,不管是用户空间的程序开发,还是内核空间的程序开发,很多时候都需要有定时器作为基础组件的支持,但使用场景的不同,对定时器的实现考虑也不尽相同,本文讨论了在Linux环境下,应用层和内核层的定时器的各种实现方法,并分析了各种实现方法的利弊以及适宜的使用环境。
首先,给出一个基本模型,定时器的实现,需要具备以下几个行为,这也是在后面评判各种定时器实现的一个基本模型[1]:StartTimer(Interval,TimerId,ExpiryAction)注册一个时间间隔为Interval后执行ExpiryAction的定时器实例,其中,返回TimerId以区分在定时器系统中的其他定时器实例。
StopTimer(TimerId)根据TimerId找到注册的定时器实例并执行Stop。
PerTickBookkeeping()在一个Tick内,定时器系统需要执行的动作,它最主要的行为,就是检查定时器系统中,是否有定时器实例已经到期。
注意,这里的Tick实际上已经隐含了一个时间粒度(granularity)的概念。
ExpiryProcessing()在定时器实例到期之后,执行预先注册好的ExpiryAction行为。
上面说了基本的定时器模型,但是针对实际的使用情况,又有以下2种基本行为的定时器:Single-Shot Timer这种定时器,从注册到终止,仅仅只执行一次。
Repeating Timer这种定时器,在每次终止之后,会自动重新开始。
本质上,可以认为Repeating Timer是在Single-Shot Timer终止之后,再次注册到定时器系统里的Single-Shot Timer,因此,在支持Single-Shot Timer的基础上支持Repeating Timer并不算特别的复杂。
在2.4的内核中,并没有提供POSIX timer[2]的支持,要在进程环境中支持多个定时器,只能自己来实现,好在Linux提供了setitimer(2)的接口。
SysTick定时器的应用

SysTick定时器的应用通常实现Delay(N)函数的方法为:for(i = 0; i <= x; i ++);x --- 对应于对应于N 毫秒的循环值对于STM32系列微处理器来说,执行一条指令只有几十个ns,进行for循环时,要实现N毫秒的x值非常大,而且由于系统频率的宽广,很难计算出延时N毫秒的精确值。
针对STM32微处理器,需要重新设计一个新的方法去实现该功能,以实现在程序中使用Delay(N)。
Cortex-M3的内核中包含一个SysTick时钟。
SysTick 为一个24位递减计数器,SysTick设定初值并使能后,每经过1个系统时钟周期,计数值就减1。
计数到0时,SysTick计数器自动重装初值并继续计数,同时内部的COUNTFLAG标志会置位,触发中断(如果中断使能)。
在STM32的应用中,使用Cortex-M3 内核的SysTick作为定时时钟,设定每一毫秒产生一次中断,在中断处理函数里对N减一,在Delay(N)函数中循环检测N是否为0,不为0则进行循环等待;若为0则关闭SysTick时钟,退出函数。
注:全局变量TimingDelay 必须定义为volatile延迟时间将不随系统时钟频率改变。
外部晶振为8MHz,9倍频,系统时钟为72MHz,SysTick的最高频率为9MHz(最大为HCLK/8),在这个条件下,把SysTick 效验值设置成9000,将SysTick 时钟设置为9MHz,就能够产生1ms的时间基值,即SysTick产生1ms的中断。
使用ST的函数库使用systick的方法1、调用SysTick_CounterCmd() 失能SysTick计数器2、调用SysTick_ITConfig () 失能SysTick中断3、调用SysTick_CLKSourceConfig() 设置SysTick时钟源。
4、调用SysTick_SetReload() 设置SysTick重装载值。
SysTick定时器介绍,SysTick定时器寄存器

SysTick定时器介绍,SysTick定时器寄存器
SysTick定时器介绍
SysTick定时器也叫SysTick滴答定时器,它是Cortex-M3内核的一个外设,被嵌入在NVIC 中。
它是一个24 位向下递减的定时器,每计数一次所需时间为1/SYSTICK,SYSTICK 是系统定时器时钟,它可以直接取自系统时钟,还可以通过系统时钟8 分频后获取,本套程序中我们采用后者,即每计数一次所需时间为1/(72/8)us,换句话说在1us 的时间内会计数9 次。
当定时器计数到0 时,将从LOAD 寄存器中自动重装定时器初值,重新向下递减计数,如此循环往复。
如果开启SysTick 中断的话,当定时器计数到0,将产生一个中断信号。
因此只要知道计数的次数就可以准确得到它的延时时间。
SysTick 定时器通常应用在操作系统中,为其提供时钟周期。
SysTick定时器操作
在STM32F1 库函数中,并没有提供相应的SysTick 定时器配置函数,。
STM32的定时器定时时间计算(计数时间和中断定时时间)

STM32的定时器定时时间计算(计数时间和中断定时时间)时基单元可编程⾼级控制定时器的主要部分是⼀个16位计数器和与其相关的⾃动装载寄存器。
这个计数器可以向上计数、向下计数或者向上向下双向计数。
此计数器时钟由预分频器分频得到。
计数器、⾃动装载寄存器和预分频器寄存器可以由软件读写,即使计数器还在运⾏读写仍然有效。
时基单元包含:●计数器寄存器(TIMx_CNT)●预分频器寄存器 (TIMx_PSC)●⾃动装载寄存器 (TIMx_ARR)●重复次数寄存器 (TIMx_RCR)⾃动装载寄存器是预先装载的,写或读⾃动重装载寄存器将访问预装载寄存器。
根据在TIMx_CR1寄存器中的⾃动装载预装载使能位(ARPE)的设置,预装载寄存器的内容被⽴即或在每次的更新事件UEV时传送到影⼦寄存器。
当计数器达到溢出条件(向下计数时的下溢条件)并当TIMx_CR1寄存器中的UDIS位等于0时,产⽣更新事件。
更新事件也可以由软件产⽣。
随后会详细描述每⼀种配置下更新事件的产⽣。
计数器由预分频器的时钟输出CK_CNT驱动,仅当设置了计数器TIMx_CR1寄存器中的计数器使能位(CEN)时,CK_CNT才有效。
(更多有关使能计数器的细节,请参见控制器的从模式描述)。
注意,在设置了TIMx_CR寄存器的CEN位的⼀个时钟周期后,计数器开始计数。
预分频器描述预分频器可以将计数器的时钟频率按1到65536之间的任意值分频。
它是基于⼀个(在TIMx_PSC寄存器中的)16位寄存器控制的16位计数器。
因为这个控制寄存器带有缓冲器,它能够在运⾏时被改变。
新的预分频器的参数在下⼀次更新事件到来时被采⽤。
尤其注意的是当发⽣⼀个更新事件时,所有的寄存器都被更新,硬件同时(依据URS位)设置更新标志位(TIMx_SR寄存器中的UIF位)。
●重复计数器被重新加载为TIMx_RCR寄存器的内容。
●⾃动装载影⼦寄存器被重新置⼊预装载寄存器的值(TIMx_ARR)。
STM32系统systick定时器与延迟时间计算

STM32系统systick定时器与延迟时间计算STM32系统systick定时器与延迟时间计算系统嘀嗒(SysTick)校准值寄存器1.(SysTick) 系统嘀嗒时钟是由HCLK 分频出来的。
HCLK=SYSCLK=72MHz/* Select HCLK/8 as SysTick clock source */SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);当系统嘀嗒时钟设定为9 兆赫或是:SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);当系统嘀嗒时钟设定为72 兆赫2.系统嘀嗒校准值固定到9000,当系统嘀嗒时钟设定为9 兆赫,产生1ms 时基。
/* SysTick interrupt each 9ms with counter clock equal to 1MHz */SysTick_SetReload(9000);该参数取值必须在1和0x00FFFFFF之间3.使能一下:/* Enable the SysTick Counter */SysTick_CounterCmd(SysTick_Counter_Enable);/* Enable the SysTick Interrupt */SysTick_ITConfig(ENABLE);这还有另外一种设置方法:经试验验证可行://NVIC_InitTypeDef NVIC_InitStructure;/* Configure HCLK clock as SysTick clock source */SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);/* Configure the SysTick handler priority */NVIC_SystemHandlerPriorityConfig(SystemHandler_SysTick,2, 0);/* Configure one bit for preemption priority */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);/* SysTick interrupt each 100 Hz with HCLK equal to 72MHz 每1ms发生一次SysTick中断*/SysTick_SetReload(72000);/* Enable the SysTick Interrupt */SysTick_ITConfig(ENABLE);/* Enable the SysTick Counter */SysTick_CounterCmd(SysTick_Counter_Enable);关键是:SysTick_CLKSourceConfig,和SysTick_SetReload。
定时器计算方法

STM32定时器时间的计算方法STM32中的定时器有很多用法:(一)系统时钟(SysTick)设置非常简单,以下是产生1ms中断的设置,和产生10ms延时的函数:void RCC_Configuration(void){RCC_ClocksTypeDef RCC_ClockFreq;SystemInit();//源自system_stm32f10x.c文件,只需要调用此函数,则可完成RCC的配置. RCC_GetClocksFreq(&RCC_ClockFreq);//SYSTICK分频--1ms的系统时钟中断if (SysTick_Config(SystemFrequency / 1000)){while (1); // Capture error}}void SysTick_Handler(void)//在中断处理函数中的程序{while(tim){tim--;}}//调用程序:Delay_Ms(10);当然,前提是要设置好,变量tim要设置成volatile类型的。
(二)第二种涉及到定时器计数时间(TIMx)/*TIM3时钟配置*/TIM_TimeBaseStructure.TIM_Prescaler = 2; //预分频(时钟分频)72M/(2+1)=24M TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数TIM_TimeBaseStructure.TIM_Period = 65535; //装载值18k/144=125hzTIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0;TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);定时时间计算:TIM_TimeBaseStructure.TIM_Prescaler = 2;//分频2 72M/(2+1)/2=24MHzTIM_TimeBaseStructure.TIM_Period = 65535; //计数值65535((1+TIM_Prescaler )/72M)*(1+TIM_Period )=((1+2)/72M)*(1+65535)=0.00273秒=366.2Hz */注意两点(来自大虾网,未经检验)(1)TIMx(1-8),在库设置默认的情况下,都是72M的时钟;(2)TIM_TimeBaseStructure.TIM_RepetitionCounter=0;是重复计数,就是重复溢出多少次才给你来一个溢出中断,它对应的寄存器叫TIM1 RCR.如果这个值不配置,上电的时候寄存器值可是随机的,本来1秒中断一次,可能变成N秒中断一次,让你超级头大!假设系统时钟是72Mhz,TIM1是由PCLK2(72MHz)得到,TIM2-7是由PCLK1得到关键是设定时钟预分频数,自动重装载寄存器周期的值/*每1秒发生一次更新事件(进入中断服务程序)。
STM32 定时器 定时时间的计算

STM32 定时器定时时间的计算假设系统时钟是72Mhz,TIM1 是由PCLK2 (72MHz)得到,TIM2-7是由PCLK1 得到关键是设定时钟预分频数,自动重装载寄存器周期的值定时器的基本设置1、TIM_TimeBaseStructure.TIM_Prescaler = 7199;//时钟预分频数例如:时钟频率=72/(时钟预分频+1)2、TIM_TimeBaseStructure.TIM_Period = 9999; // 自动重装载寄存器周期的值(定时时间)累计0xFFFF 个频率后产生个更新或者中断(也是说定时时间到)3、TIM_TimeBaseStructure.TIM_CounterMode =TIM1_CounterMode_Up; //定时器模式向上计数4、TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; //时间分割值5、TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);//初始化定时器26、TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//打开中断溢出中断7、TIM_Cmd(TIM2, ENABLE);//打开定时器或者:TIM_TimeBaseStructure.TIM_Prescaler = 35999;//分频3599972M/(35999+1) /2=1Hz1 秒中断溢出一次TIM_TimeBaseStructure.TIM_Period = 2000; //计数值2000((1+TIM_Prescaler )/72M)*(1+TIM_Period )=((1+35999)/72M)*(1+2000)=1 秒*/tips:感谢大家的阅读,本文由我司收集整编。
仅供参阅!。
STM32中的几个时钟SysTick、FCLK、SYSCLK、HCLK的详解

STM32中的几个时钟SysTick、FCLK、SYSCLK、HCLK的详解在STM32中,有五个时钟源,为HSI、HSE、LSI、LSE、PLL。
①、HSI是高速内部时钟,RC振荡器,频率为8MHz。
②、HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。
③、LSI是低速内部时钟,RC振荡器,频率为40kHz。
④、LSE是低速外部时钟,接频率为32.768kHz的石英晶体。
⑤、PLL为锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE/2。
倍频可选择为2~16倍,但是其输出频率最大不得超过72MHz。
其中40kHz的LSI(低速内部时钟)供独立看门狗IWDG使用,另外它还可以被选择为实时时钟RTC的时钟源。
另外,实时时钟RTC的时钟源还可以选择LSE(低速外部时钟),或者是HSE(高速外部时钟)的128分频。
RTC的时钟源通过RTCSEL[1:0]来选择。
STM32中有一个全速功能的USB模块,其串行接口引擎需要一个频率为48MHz的时钟源。
该时钟源只能从PLL输出端获取,可以选择为1.5分频或者1分频,也就是,当需要使用USB模块时,PLL必须使能,并且时钟频率配置为48MHz 或72MHz。
()另外,STM32还可以选择一个时钟信号输出到MCO脚(PA8)上,可以选择为PLL输出的2分频、HSI、HSE、或者系统时钟。
系统时钟SYSCLK最大频率为72MHz,它是供STM32中绝大部分部件工作的时钟源。
系统时钟可由PLL、HSI或者HSE提供输出,并且它通过AHB分频器分频后送给各模块使用,AHB分频器可选择1、2、4、8、16、64、128、256、512分频。
其中AHB分频器输出的时钟送给5大模块使用:①、送给AHB总线、内核、内存和DMA 使用的HCLK时钟。
②、分频后送给STM32芯片的系统定时器时钟(Systick=Sysclk/8=9Mhz)③、直接送给Cortex的自由运行时钟(free running clock)FCLK。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
定时器定时时间的计算(SystemCoreClock与OS_TICKS_PER_SEC的关系)
定时器定时时间的计算
xcj 2015/06/03 09:23
假设定时器的时钟频率为f,f已知。
那么定时器每计数一次所用时间为1/f。
1/f代表了定时器的定时的时间精度(或最小计时单位)。
往计数器写的初值为Ticks,就是经过Ticks个周期后,定时器值变为0,定时时间到了。
如果我们要定时的时间为T,那么计算公式为:
T = ticks * (1/f) (1)
整理后可得
ticks = f * T (2)
举个例子,假如定时器的时钟为SystemCoreClock,要定时1mS。
那么 ticks = SystemCoreClock * 1mS =SystemCoreClock * 1 * 10^(-3)=SystemCoreClock/1000
换个思路,如果已知定时器的时钟频率为f,要用定时器产生一个频率为f1的定时中断(T=1/f1)。
根据公式(2)有
ticks = f /f1 (3)
上面的式子中 f1<f
如果定时器的时钟频率为SystemCoreClock,要用定时器产生一个频率为1KHz(1000Hz,周期为1ms)的定时中断,
那么ticks = SystemCoreClock /1000
公式(3)比较常用,也好计算。
在ucos ii中,OS_TICKS_PER_SEC代表每秒产生的中断个数,也就是是说OS_TICKS_PER_SEC的单位是Hz。
由于SysTick定时器的时钟频率为SystemCoreClock,那么Ticks就需要设置为
Ticks = SystemCoreClock/OS_TICKS_PER_SEC
这也是函数OS_CPU_SysTickInit()的参数为什么是SystemCoreClock/OS_TICKS_PER_SEC的原因了。