初始化CH32V317的systick定时器
Systick中断是一个轻量级的Timer,专用于产生周期性系统中断。印象中,由ARM公司在Cortex-M3内核中首次引入。设计的初衷是为RTOS的任务调试使用,其集成于内核,而非外设,故不占用MCU外设资源,便于移植。
沁恒CH32V317的RISC-V内核也保留这个特性功能,这也特别方便我将Cortex-M3的程序移植到CH32V317之上,不过,青稞V4内核的Systick与Cortex-M3还是有区别的,以CH32V317为例简单说说:
它们俩的时钟源是一致的:可以是系统时钟,也可以是系统时钟的 8 分频 。不一样的是,Cortex-M3内核设计的Systick为24位计数器,而CH32V317的Systick的内部设计了64位加减计数器。这样CH32V317的系统计数器与计数比较值均为64位,即需要2个32bit的寄存器来保存STK_CNTL,STK_CNTH,STK_CMPLR,STK_CMPHR。

我们再来看看实现!沁恒的官方参考示例并没有将Systick的两个64位寄存器实现为2个32bit的寄存器,而是直接实现的64bit。
/* memory mapped structure for SysTick */
typedef struct
{
__IO uint32_t CTLR;
__IO uint32_t SR;
__IO uint64_t CNT;
__IO uint64_t CMP;
}SysTick_Type;
这样做数据结构也非常方便了实现,如下方的配置systick:
void SysTick_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
/*********************************************************************
* @fn SYSTICK_Init_Config
*
* [@brief](home.php?mod=space&uid=247401) SYSTICK_Init_Config.
*
* [@return](home.php?mod=space&uid=266161) none
*/
void SYSTICK_Init_Config(u_int64_t ticks)
{
SysTick->SR &= ~(1 << 0);//clear State flag
SysTick->CMP = ticks;
SysTick->CNT = 0;
SysTick->CTLR = 0xF;
NVIC_SetPriority(SysTicK_IRQn, 15);
NVIC_EnableIRQ(SysTicK_IRQn);
}
和Cortex-M3的配置方式几乎一样了。 |