当前位置:首页 > 单片机 > 单片机
[导读]上图是LPC1114系统滴答定时器(SysTick)的结构图。系统滴答定时器位于Cortex-M0内核中,也就是说,不论是LPC1114,还是其他的Cortex-M0内核单片机,都有这个系统定时器。其存在的主要目的是为嵌入式操作系统提供100

上图是LPC1114系统滴答定时器(SysTick)的结构图。系统滴答定时器位于Cortex-M0内核中,也就是说,不论是LPC1114,还是其他的Cortex-M0内核单片机,都有这个系统定时器。其存在的主要目的是为嵌入式操作系统提供100Hz(即10ms)的定时节拍。当然,也可以做为其它的普通定时等其他用途。下面是LPC1114用户手册上列举出的一些用途,你可以了解了解。

可编程设置频率的RTOS 定时器(例如100 Hz),调用一个SysTick 服务程序。

用于核时钟的高速报警定时器。

简单计数器。软件可使用它测量时间 (如:完成任务所需时间、已使用时间)。

基于丢失 / 命中期限控制的内部时钟源。控制和状态寄存器中的COUNTFLAG 位域,
可用于决定一个动作是否在设定的期限内完成,作为动态时钟管理控制环的一部分。

一、寄存器

系统定时器使用起来非常简单。它一共有4个寄存器:SYST_CSR、SYST_RVR、SYST_CVR、SYST_CALIB。定义如下所示:

4个寄存器中,校准寄存器SYST_CALIB不用我们考虑,出厂前就配置好了。这时,就剩下3个寄存器了。一共需要配置3个寄存器就可以完成工作的模块,你想想会很难使用吗?英文不好的同学,请看下面的寄存器翻译:

SYST_CSR寄存器,就是系统定时器控制和状态寄存器

SYST_RVR寄存器,就是系统定时器重载值寄存器

SYST_CVR寄存器,就是系统定时器当前值寄存器

1.SYST_CSR寄存器

翻译成中文的:

CSR寄存器用到的位有4个,bit0用于是否开启定时器,bit1用于是否产生中断,bit2用于选择定时器的时钟源是等于主时钟还是等于主时钟的一半,bit16是定时器的状态。

2.SYST_RVR寄存器

翻译成中文的:

RVR寄存器用到bit0~23,即24位数,这个值是定时器倒计时的初值,打开定时器以后,值会从此值倒计时到0,因为倒计时到0以后,又会从此值开始倒计时,所以定义里面叫这个寄存器位重载值。

3.SYST_CVR寄存器

翻译成中文:

CVR寄存器用到bit0~23,即24位数,这是一个状态寄存器,当定时器开始运作,这个值在不断地变化,从RVR寄存器获取初值以后,倒计时到0.

二、如何调用Keil自带的系统定时器函数

系统自带的Systick函数,由CMSIS(关于什么是CMSIS,去百度搜吧)提供,位于core_cm0.h文件,你可以在LPC1114工程中,如下地方找到:

双击上图红色框内的文件名称,打开对应文件。在core_cm0.h文件的最底部,有一个函数,如下所示:

__STATIC_INLINEuint32_tSysTick_Config(uint32_tticks){if((ticks-1)>SysTick_LOAD_RELOAD_Msk)return(1);/*Reloadvalueimpossible*/SysTick->LOAD=ticks-1;/*setreloadregister*/NVIC_SetPriority(SysTick_IRQn,(1<<__NVIC_PRIO_BITS)-1);/*setPriorityforSystickInterrupt*/SysTick->VAL=0;/*LoadtheSysTickCounterValue*/SysTick->CTRL=SysTick_CTRL_CLKSOURCE_Msk|SysTick_CTRL_TICKINT_Msk|SysTick_CTRL_ENABLE_Msk;/*EnableSysTickIRQandSysTickTimer*/return(0);/*Functionsuccessful*/}

此函数就是CMSIS提供的系统定时器控制函数SysTick_Config()。在使用的时候,可以直接调用,函数有一个参数ticks。由函数内部的语句
“SysTick->LOAD = ticks – 1;”知道,ticks就是LOAD值,即重载值,表示两次中断的计数。

例如,要产生10ms的中断,可以在程序中如下调用函数:

Systick_Config(SystemCoreClock/100);

函数参数中的SystemCoreClock是当前主频的值,假如现在的主频是50MHz,SystemCoreClock就是50 000 000 ,50 000 000 /100=500 000。我们把参数带进去以后,LOAD=499 999,也就是说,定时器开始运行后,定时器的值会从499 999递减到0,进入中断函数,然后再次从499 999 递减到0,如此循环。

这时候,你心中会有一个大大的问号:“为什么从499 999递减到0就是10ms?”接下来,瑞生给你解答,其实很简单,不信听我说。

定时器运行,要知道“为什么从499 999递减到0就是10ms”,只要知道定时器每递减一个值需要多长时间就可以了。知道每递减一个值需要多长时间,那么递减500 000下,需要多长时间,就知道了。

要知道每递减一个值需要多长时间,就需要知道当前定时器运行的时钟是多少。由寄存器CSR知道,定时器的时钟有两种,一种是等于主频,一种是等于主频的二分之一,由CSR寄存器中的bit2决定。

函数中用到的寄存器名称和我们手册上给出的名称不太一样,但是你要知道,名称就是个代号,实际调用的其实是名称背后的寄存器地址。函数中LOAD就是我们之前说的RSR,VAL就是我们之前说的CVR,CTRL就是我们之前说的CSR。

函数中,对控制寄存器的bit0 bit1 bit2都置1,对照前面的寄存器定义可知,时钟设置为等于主频,打开系统定时器中断,允许定时器运行。

我们知道了时钟,就知道定时器每递减一个值需要的时间了,即:1/SystemCoreClock 秒,换算成毫秒即:(1/SystemCoreClock)*1000=1000/SystemCoreClock毫秒,即每递减一个值,耗时1000/SystemCoreClock毫秒。所以如果要使得10ms定时,即10/(1000/SystemCoreClock)=SystemCoreClock/100,回头看看前面定时10ms的参数,是不是这个值呢。以此类推,需要定时多长时间,你可以自己算一个参数带进去了,需要注意的是,LOAD值是个24位数,带进去的数不要超过24位数的最大值。还有一个需要注意的地方,就是LOAD值最小255,当你给LOAD值带进去小于255值,LOAD会自动变成255。

三、系统定时器中断函数怎么写

系统定时器的中断函数名称如下所示:

voidSysTick_Handler(void){}

有的童鞋会问,函数名称可以自己改吗?答案是不可以改,非要自己改一个,需要一定的步骤。接下来瑞生给你解答。

打开一个工程,双击startup_LPC11xx.h文件打开

在第74行,你可以看到系统定时器中断函数的名称,如下所示:

你不仅可以看到系统定时器中断函数的名称,所有的中断函数的名称,都已经写好了,在用其它模块的中断时,到这个地方找就对了。还有前面那个是否可以自己改的问题,你把这个地方的名称改了,就可以在.c文件中使用你修改后的名称了,不过为了程序的移植性统一性阅读性,瑞生建议大家不要修改。

四、写一个毫秒延时函数delay_ms()

1.自己配置寄存器(假设当前主频为50MHz)

staticvolatileuint32_tTimeTick=0;voidSysTick_Handler(void)//中断函数{TimeTick++;}voiddelay_ms(uint32_tms)//参数最大带入671{SysTick->LOAD=25000*ms-1;SysTick->VAL=0;SysTick->CTRL|=((1<<1)|(1<<0));//开定时器,开中断while(!TimeTick);TimeTick=0;SysTick->CTRL=0;//关定时器}

为什么主频为50MHz时,上面函数中与ms乘的数是25000?我在上面已经讲过了,这里我再讲一次,非常简单哦。CTRL寄存器bit2默认是0,也就是说默认的系统定

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭