EFM32片内外设 -- Systick

在很多场合下,我们经常会需要一个简单的延时函数。为了不暂用片内的其他资源,往往会想到Cortex-M3自带的Systick这个定时器。但是如何实现这样的功能呢,还得慢慢道来。所谓磨刀不误砍柴工,因此我们先了解一下Systick到底有哪些寄存器,操作哪些寄存器才能达到我们的目的呢?

每个Cortex-M3内核都含有一个称之为系统定时器的定时器,即SysTick,减计数,过零重载等基本功能。它总共含有4个寄存器:分别是控制和状态寄存器,重载值寄存器,当前值寄存器和校正值寄存器。

控制和状态寄存器(Systick Control and Status Register),功能包含定时器使能位,是否使能异常( exception),以及配置Systick的时钟源和是否有计数到零的标志位。其复位之后的默认值为0x00000000;

--ENABLE, BIT0, 决定了是否使能Systick。

0 = 定时器禁止

1 = 定时器使能

-- TICKINT, BIT1, 决定了当Systick计数到零时,MCU是否会去响应该事件。是否需要响应Systick中断就是由这个位控制了。

0 = 计数器向下计到零时,MCU不会响应Systick异常。

1 = 计数器向下计到零时,MCU会响应Systick异常。

-- CLKSOURCE,BIT2,指明了Systick的时钟源。HFCORECLK或则是RTC。

0 = RTC计数器的Bit0

1 = HFCORECLK

-- COUNTFLAG, BIT16,指明了定时器是否有过零事件发生。即当定时器计数器从1变到0时,该标志位置1.

重载值寄存器(Systick Reload Value Register),定义了定时器重载时的初值。当定时器当前计数值减到0时,就会将重载值寄存器里面的值载入到定时器当前值。重载发生在当前计数器为零之后的下一个时钟信号的边沿。

-- RELOAD, BIT0~BIT23,有效位为24Bit。在Systick使能的情况下,当定时器当前值计数到零时,载入到定时器当前值。可以设置为0~0x00FFFFFF中的任意值。由于重载发生在过零时的下一个时钟边沿,因此要配置这个值需要注意:

如果是要做一个多次的时间间隔为N个时钟信号的周期性定时器,则需要将该值配置成需要N-1. 例如如果想做一个时间间隔为100个时钟的周期性定时器,则需要将这个值配置为99.因为需要额外一个时钟周期用来重载。

如果只是想做一次性的时间间隔为N个时钟周期的定时器,则可以将该值直接设置成N。

当前值寄存器(Systick Current Value Register), 是定时器计数值的当前值。

-- CURRENT,BIT0~BIT23。有效位为24bit。该寄存器也支持读写操作。读的话,则返回当前值,写如任何值,都会将该寄存器清零,并且将COUNTFLAG清零。

校正值寄存器(Systick Calibration Value Register),校正值寄存器。该寄存器是一个只读寄存器。目前对该寄存器还不是很了解。

-- TENMS,BIT0~BIT23。校正值。读回值应为0x000036B0,  即14MHz时钟下面,1ms的时钟周期数。0x000036B0即14000。

-- SKEW,BIT30。 该值是为了表明TENMS中的校正值是否精准。1为不精准,0为精准。

-- NOREF,BIT31。该值表明Systick是否是将RTC作为参考源。

通过以上寄存器的介绍,我们大致上应该知道如何用Systick做一个简答的Delay函数了吧。

1. 初始化Systick,停止Systick,配置Systick的时钟源,清除COUNTFLAG。由于不使用中断,因此清除TICKINT。

2. 将延时的值带入重载值寄存器,清除当前值寄存器,然后使能定时器,并且等待COUNTFLAG标志位置1.

3. 停止Systick,并且返回。

附上代码,请参考。由于涉及到函数调用及处理,因此如果延时很短,进度很高的情况下,需要额外考虑这些。

#include "em_device.h"
#include "em_chip.h"
#include "em_cmu.h"

__no_init unsigned long usDelay;
__no_init unsigned long msDelay;

void Systick_Delay_Init(void)
{
    SystemCoreClockUpdate();
   
    usDelay = SystemCoreClock / 1000000;
    msDelay = SystemCoreClock / 1000;
   
    SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
    SysTick->CTRL &= ~(SysTick_CTRL_COUNTFLAG_Msk | SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk);
}

void Systick_Delay_Cycle(unsigned long ulCycle)
{
    SysTick->LOAD = ulCycle;
    SysTick->VAL = 0;
    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
   
    while(!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk));
    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}

void Systick_Delay_uS(unsigned long uluS)
{
    uluS = usDelay * uluS;
   
    SysTick->LOAD = uluS;
    SysTick->VAL = 0;
    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
   
    while(!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk));
    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}

void Systick_Delay_mS(unsigned long ulmS)
{
    ulmS = msDelay * ulmS;
   
    SysTick->LOAD = ulmS;
    SysTick->VAL = 0;
    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
   
    while(!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk));
    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: EFM32开发套件(Energy Micro Family 32-bit)是一款由索菲亚半导体(Silicon Labs)推出的集成化开发工具,旨在帮助开发者更轻松地设计和开发低功耗嵌入式系统。 其例程是一系列编写好的示例代码,旨在展示EFM32开发套件的各种功能和特性,可以帮助开发者快速入门和学习如何在EFM32芯片上开发代码。这些例程涵盖了许多常见的应用领域,如无线通信、传感器数据采集、电源管理等。 通过使用EFM32开发套件例程,开发者可以快速了解和学习EFM32芯片的特性和功能,避免从零开始编写代码。这些例程包含了完整的源代码和详细的文档,使得开发者能够快速上手并进行自己的应用开发。 除了提供例程代码,EFM32开发套件还提供了一套完整的开发环境,包括集成开发环境(IDE)、调试器等工具。开发者可以使用这些工具来编写、调试和测试他们的应用程序,并且与EFM32开发套件实现无缝的集成。 总之,EFM32开发套件例程提供了一种简便的学习和开发方式,通过使用它们,开发者可以更快地上手和掌握EFM32芯片,从而加速低功耗嵌入式系统的开发过程。 ### 回答2: EFM32开发套件例程是用来演示和说明EFM32微控制器的各种功能和特性的代码示例集合。它们被设计用作新用户学习和评估EFM32系列微控制器的工具。 EFM32开发套件例程提供了丰富的代码实现,包括了各种外设,如GPIO、USART、SPI、I2C等。这些例程覆盖了从基本的IO控制到高级的通信和数据处理功能的各个方面。 通过运行这些例程,用户可以学习如何初始化和配置各个外设,并使用它们完成各种任务。这些例程还包含了详细的代码注释和使用说明,使用户能够轻松理解和修改代码以适应自己的需求。 除了提供例程代码外,EFM32开发套件还提供了开发工具和文档,以帮助用户更好地使用例程。用户可以使用官方的开发工具和配套的IDE进行代码编译、调试和下载,同时,官方的技术文档也提供了对开发套件和例程的详细介绍和解释。 总之,EFM32开发套件例程是一套非常有价值的资源,可帮助用户快速上手和了解EFM32系列微控制器的各种功能和特性。无论是初学者还是有经验的开发人员,都可以通过使用这些例程来加快自己的开发速度并提高自己的技术水平。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值