1开发平台
- 山外KEAZ128核心板(使用Jlink解除保护)
- 使用Keil 5.25
2 什么是Systick
1 Systick的描述
SysTick—系统定时器是属于 CM4 内核中的一个外设,内嵌在 NVIC 中。系统定时器
是一个 24bit 的向下递减的计数器,计数器每计数一次的时间为 1/SYSCLK,一般我们设置
系统时钟 SYSCLK 等于 180M。当重装载数值寄存器的值递减到 0 的时候,系统定时器就
产生一次中断,以此循环往复。
因为 SysTick 是属于 CM4 内核的外设,所以所有基于 CM4 内核的单片机都具有这个
系统定时器,使得软件在 CM4 单片机中可以很容易的移植。系统定时器一般用于操作系统,
用于产生时基,维持操作系统的心跳。
2 Systick的寄存器
- CTRL SysTick 控制及状态寄存器
- LOAD SysTick 重装载数值寄存器
- VAL SysTick 当前数值寄存器
- CALIB SysTick 校准数值寄存器
3 Systick的初始化
在初始化Systick的时候,基本上有两种方式,一种当然是直接操作寄存器进行初始化,寄存器的定义在 “core_cm0plus.h” 中有定义。
#define basetime 48000000
uint8_t systick_init(void)
{
if ((basetime - 1UL) > SysTick_LOAD_RELOAD_Msk)
{
return (1UL);
}
SysTick->LOAD = (uint32_t)(basetime - 1UL);
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);
SysTick->VAL = 0UL;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk;
return (0UL);
}
而在core_cm0plus.h其实也有已经写好的了,
Systick_Config(48000000/1000000);
可以直接调用来初始化。
4 用Systick编写的精准延时函数
注:是core_cm0plus.h ,而不是core_cm0.h。因为KEAZ128的内核是cm0+,而不是cm0。曾经我就搞错了,踩到坑了。
初始化代码如下,可直接参考内核手册:
写完之后定义一个全局变量,
uint32_t Timesysitck = 0;
并编写中断函数:
void SysTick_Handler(void)
{
Timesysitck --;
}
即可配置成1us产生一次中断。
则延时函数编写如下:
void sdelay_us(uint32_t time)
{
Timesysitck = time;
while( Timesysitck != 0 );
}
void sdelay_ms(uint32_t time)
{
while(time--)
{
sdelay_us(1000); // 1ms
}
}
最后将函数在头文件声明即可。
注:值得一提的是,KEAZ128的ram和rom都是足够大的,对于这丰富的资源,用来跑RTOS再好不过,并可以超频到80MHz的时钟(其实能达到120MHz,只不过我怕会坏没敢这样做,我看有人这样做了,不怕的大佬可以试试,试过了留言告诉我稳不稳,hhhhh)。在跑RTOS的时候基本上就占用Systick作为RTOS的心跳,即时基。因此需要精准延时的话,可后面使用TIM定时器来实现,实现方式基本一样,不一样的只有寄存器配置。