记忆花园 发表于 2025-7-29 21:23

初始化CH32V317的systick定时器

# 初始化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。

![沁恒CH32V317_systick_01.jpg](data/attachment/forum/202507/29/172452xus1wntmyv7i3iqd.jpg "沁恒CH32V317_systick_01.jpg")


我们再来看看实现!沁恒的官方参考示例并没有将Systick的两个64位寄存器实现为2个32bit的寄存器,而是直接实现的64bit。

```c
/* 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:

```c
void SysTick_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));

/*********************************************************************
* @fn      SYSTICK_Init_Config
*
* @brief   SYSTICK_Init_Config.
*
* @returnnone
*/
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的配置方式几乎一样了。

复古留声机 发表于 2025-8-1 16:54

这个帖子很详细地解释了CH32V317的systick定时器初始化过程,对于我们这些在RISC-V内核上工作的人来说非常有帮助。
页: [1]
查看完整版本: 初始化CH32V317的systick定时器