Cortex-M3与M85单片机的SysTick使用上有区别吗?

科技   2024-10-13 08:30   中国香港  

Cortex-M是ARM面向MCU的内核,推出约有20年了,最经典的就是Cortex-M3内核,也是目前市面上广泛使用的内核之一。

而目前(2024-09)最新最强大的单片机内核是Cortex-M85。
https://www.arm.com/zh-TW/product-filter?families=cortex-m

Cortex-M85相比Cortex-M3内核升级了很多功能,也变更强大了。

那么,作为普通用户(开发者),使用Cortex-M85和Cortex-M3内核单片机有什么区别呢?

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

Cortex-M85单片机SysTick

定时器是单片机常用的一个模块,不管是延时,还是RTOS的心跳(系统时钟)都会用到定时器。所以,Arm考虑到这种情况,在每个Cortex-M内核都集成了一个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进行的延时。
进一步分析代码,可以看到更底层调用SysTick和CM0、CM23等也是一样。所以,你会发现,Cortex-M3与M85单片机的SysTick使用上没有多大区别。


面包板社区
分享电子技术干货,工程师福利!EET电子工程专辑、ESM国际电子商情、EDN电子技术设计官方社区。
 最新文章