2025 / 03 / 27
瑞萨RA8系列教程 | RA8单片机SysTick使用描述

作者 | strongerHuang


每个Cortex-M内核都集成了一个SysTick模块,那是因为这个模块几乎是单片机项目必备的一个(定时器)功能。

不管是最新的Cortex-M85内核,还是经典的Cortex-M3内核单片机,都集成了SysTick模块。

cm3.h与cm85.h

单片机开发者,接触最多的就是core_cm3.h(core_cm85.h)文件,这里定义了与内核相关的大部分内容,平时我们调用最多也是这里的接口。

我们对比一下这两个源文件:


通过对比源代码,你会直观地发现,cm85比cm3代码行数明显大多了,1943行和4672行。当然,行数多了这么多,左侧红色(差异)部分也比较多。


虽然,左侧“红色”比较多,但大部分都是多出来的行数以及宏定义。仔细对比,其实很多都是一样的,比如我们常用的系统复位函数:

__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void)
{
    __DSB();                                                          /* Ensure all outstanding memory accesses included
                                                                              buffered write are completed before reset */
    SCB->AIRCR  = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos)    |
                                         (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
                                          SCB_AIRCR_SYSRESETREQ_Msk    );         /* Keep priority group unchanged */
    __DSB();                                                          /* Ensure completion of memory access */

    for(;;)                                                           /* wait until reset */  
    {    
        __NOP();  
    }
}


再比如系统Tick配置函数:



__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
    if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
    {
        return (1UL);                                                   /* Reload value impossible */
    }

    SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */
    NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
    SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
    SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
                                 SysTick_CTRL_TICKINT_Msk   |
                                 SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
  return (0UL);                                                     /* Function successful */
}


其实,你会发现,在Cortext-M3单片机上常用的这些函数接口,基本和CM85一样,这也说明
CM85大部分接口向下兼容CM3

RA8单片机SysTick使用描述

这里结合瑞萨RA8D1(Cortex-M85内核)单片机给大家讲述一下SysTick的用法以及描述其源码。


使用e2 studio以及fsp软件包

工具自带的软件包其实是最实用的,这里以IO翻转,SysTick延时为例,手把手教大家创建一个工程,并演示效果。


1
打开e2 studio创建单片机项目


我们命名项目名称为:RA8D1_SysTick


选择对应芯片型号:R7FA8D1BEC


基本上只需要动动鼠标“点一点”,一个完整的工程就创建好了。


2
配置工程

这里配置一些基础的信息,我们使用一个IO(PA01)来测试一下SysTick延时时间。


配置时钟树:


配置输出
Hex文件


3
演示

这里只是简单演示Demo,我们添加一个IO翻转来测试SysTick延时时间。

while(1)
{    
  R_PORT10->PODR ^= 1<<(BSP_IO_PORT_10_PIN_01 & 0xFF);     //PA01亮灭翻转    
  R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MILLISECONDS);    //SysTick延时
}



这个是1ms翻转,SysTick延时误差还是比较小,相对1ms来说误差可以忽略(采样频率100KHz看不出来误差)。


采样频率为100MHz,其实还是看得出来有点误差。当然,这个误差是晶振、软件等多种因素影响的。还有,
us级别的误差,相对ms可以忽略。


如果改为1us翻转,通过IO翻转来测试,误差就相对明显一点。


4
源码描述

有经验的工程师应该都能看懂,这里针对初学者简单说下。

R_PORT10->PODR ^= 1<<(BSP_IO_PORT_10_PIN_01 & 0xFF);

为了减少软件带来误差,这里直接操作寄存器进行IO翻转。

R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MILLISECONDS);

R_BSP_SoftwareDelay:阻塞延时函数,是FSP软件包自带函数接口。

BSP_DELAY_UNITS_MILLISECONDS:宏定义,延时单位(毫秒)。
系统定义了三个宏:
typedef enum
{    
  BSP_DELAY_UNITS_SECONDS      = 1000000, ///< Requested delay amount is in seconds    
  BSP_DELAY_UNITS_MILLISECONDS = 1000,    ///< Requested delay amount is in milliseconds    
  BSP_DELAY_UNITS_MICROSECONDS = 1        ///< Requested delay amount is in microseconds
} 
bsp_delay_units_t;


R_BSP_SoftwareDelay:其实就是利用SysTick进行的延时。


通过分析源码,你会发现Cortex-M85内核的SysTick和Cortex-M3的向下兼容,常用的接口也一样。

最后,单片机内核的SysTick是不是很简单,希望通过本文的描述,对你了解SysTick有所帮助。

隐私条款

一、接受条款 使用者(也称"您")在访问或使用本网站及其服务时,即已经表示同意并不加修改地接受本《用户协议》、本网站的《隐私声明》、《法律声明》以及其关或相链接的网页和网站的条件和条款的规定。我们强烈建议:在您阅读和接受本《用户协议》时,也应阅读并接受本《用户协议》中所提到《隐私声明》、《法律声明》及其相关或相链接网页或网站所包含的资料,因为《隐私声明》、《法律声明》及其它相关网页或网站可能包含对您适用的进一步规定。(请注意:点击划有底线的词句即可链接到上述《隐私声明》、《法律声明》及其它相关或相链接的网页和网站。

 

二、使用者的资格要求 在本网站中"使用者"指的是浏览、阅读、使用本网站信息或服务的任何个人或组织。本网站的服务仅适用于根据相关法律的规定具有签订有约束力的合同的个人或组织并仅由其使用。本网站的服务不向18周岁以下的个人使用者提供,也不向临时被本网站中止或取消使用者资格的使用者提供。如果使用者不符合本条规定,请停止使用本网站或本网站的服务。