CH32系列MCU SysTick使用与计算
1、关于SysTick
CH32F103/203:
CH32F103/203为Cortex-M3内核,SysTick是一个24位的向下递减计数器,计数器每计数一次的时间可配置为1/时基。当SysTick重装载数寄存器的值递减到0的时候,产生一次中断。CH32F系列MCU SysTick由4个寄存器控制,具体如下图。具体介绍可参考《CM3权威指南》
CH32V10x_20x_30x:
CH32V系列MCU内核为RISC-V内核,其SysTick为一个64位计数器。与Cortex-M3内核MCU不同,其SysTick可配置为向上计数或向下计数。此外还有一个64位的比较寄存器,当计数器值和比较寄存器值相同时将触发中断服务。
CH32V10x系列MCU SysTick由5个寄存器控制,如下图。具体介绍可参考CH32xRM手册。
https://www.wch.cn/downloads/CH32xRM_PDF.html
CH32V20_30x系列MCU SysTick由6个寄存器控制,如下图。具体介绍可参考CH32FV2x_V3xRM手册。
https://www.wch.cn/downloads/CH32FV2x_V3xRM_PDF.html
2、关于SysTick时基
CH32F10x_20x系列MCU可以配置HCLK或HCLK/8作为时基
CH32V103系列MCU只能配置HCLK/8作为时基
CH32V20x_30x系列MCU可以配置HCLK或HCLK/8作为时基
3、关于SysTick配置
在对SysTick进行初始化配置的时候,需要先对计数模式(即位4)进行配置,再配置计数器初始值更新(位5)和系统计数器使能控制位(位0),否则第一次延时函数可能不生效。
程序配置方式如下:
void Delay_Us(uint32_t n) { uint32_t i; SysTick->SR &= ~(1 << 0); i = (uint32_t)n * p_us; SysTick->CMP = i; SysTick->CTLR |= (1 << 4); SysTick->CTLR |= (1 << 5) | (1 << 0); while((SysTick->SR & (1 << 0)) != (1 << 0)); SysTick->CTLR &= ~(1 << 0); }
4、关于STK_CTLR寄存器位31(SWIE)的作用及用法
作用:用于触发软件中断,具体用法见下图
/* Global Variable */ #define SysTick_CTLR_SWIE (1 << 31) /********************************************************************* * @fn main * * @brief Main program. * * @return none */ int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); Delay_Init(); USART_Printf_Init(115200); printf("SystemClk:%d\r\n", SystemCoreClock); printf("This is printf example\r\n"); NVIC_EnableIRQ(Software_IRQn); // NVIC_SetPendingIRQ(Software_IRQn); while(1) { SysTick->CTLR |= SysTick_CTLR_SWIE ; Delay_Ms(500); printf("SWIE example\r\n"); } } void SW_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast"))); void SW_Handler() { SysTick->CTLR &= ~SysTick_CTLR_SWIE; printf("test\r\n"); }
5、关于SysTick延时函数时间的计算,以CH32V20x为例
关于SysTick的计数时基,可参考系统计数控制寄存器(STK_CTLR)的位2,默认时基是HCLK/8作为时基,当系统主频为72MHz时,时基为72MHz/8=9000000。当系统主频为144MHz时,时基为144MHz/8=18MHz。
sysTick默认的时基是HCLK/8,HCLK通常就是指系统主频。即时基就是SystemCoreClock/8。那么计数器计数一次的时间就是1/(SystemCoreClock/8)。当系统主频为72MHz时,计数一次的时间为1/9MHz,即1/9us。我们在延时函数初始化中配置p_us = SystemCoreClock/8000000,SystemCoreClock 为72MHz,除以8就是9,9乘以(1/9)正好就是1,同理可得144MHz下结果也是1,因此延时函数不会随着主频改变而改变。