[RISC-V MCU 应用开发] 第九十六章、CH32V103应用教程——SysTick中断

[复制链接]
 楼主| RISCVLAR 发表于 2021-5-24 17:24 | 显示全部楼层 |阅读模式
CH32V103应用教程——SysTick中断

本章教程主要进行SysTick中断简单的应用。

1、SysTick简介
CH32V103为RISC-V3A内核,与Cortex-M3内核不同,RISC-V3A内核自带了一个64位自增型计数器(SysTick),支持HCLK/8作为时基,具有较高优先级,校准后可用于时间基准。
SysTick寄存器如下图所示,主要为5个寄存器,关于各个寄存器的具体介绍,可参考CH32V103应用手册。
图片1.png
在此处需要注意的是,关于CH32V103触发STK中断服务,当CNT[63:0]与CMP[63:0]值相等时将触发STK中断服务。
图片2.png

2、硬件设计
本章教程主要讲解如何进入SysTick中断,SysTick属于单片机内部外设,无需进行外部硬件设计。

3软件设计
本章教程具体程序如下:
systick.h文件
  1. #ifndef __SYSTICK_H
  2. #define __SYSTICK_H

  3. #include "ch32v10x_conf.h"

  4. void Systick_Init(void);

  5. #endif
systick.h文件主要进行相关定义和函数声明;
systick.c文件

  1. #include "systick.h"

  2. void SysTick_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));

  3. __IO uint32_t Counter;

  4. //SysTick初始化配置
  5. static uint32_t SysTick_Config(uint32_t ticks)
  6. {
  7.     SysTick->CTLR = 0x0000;                  //关闭系统计数器STK,计数器停止计数

  8.     //设置系统计数器寄存器的值
  9.     //系统计数器低位寄存器
  10.     SysTick->CNTL0 = 0;
  11.     SysTick->CNTL1 = 0;
  12.     SysTick->CNTL2 = 0;
  13.     SysTick->CNTL3 = 0;

  14.     //系统计数器高位寄存器
  15.     SysTick->CNTH0 = 0;
  16.     SysTick->CNTH1 = 0;
  17.     SysTick->CNTH2 = 0;
  18.     SysTick->CNTH3 = 0;

  19.     //设置计数比较寄存器的值,主要用于触发STK中断服务函数。当CNT[63:0]与CMP[63:0]值相等时将触发STK中断服务。
  20.     //设置计数比较低位寄存器的值
  21.     SysTick->CMPLR0 = (u8)(ticks & 0xFF);
  22.     SysTick->CMPLR1 = (u8)(ticks >> 8);
  23.     SysTick->CMPLR2 = (u8)(ticks >> 16);
  24.     SysTick->CMPLR3 = (u8)(ticks >> 24);

  25.     //设置计数比较高位寄存器的值
  26.     SysTick->CMPHR0 = 0;
  27.     SysTick->CMPHR1 = 0;
  28.     SysTick->CMPHR2 = 0;
  29.     SysTick->CMPHR3 = 0;

  30.     NVIC_SetPriority(SysTicK_IRQn, 15);      //设置SysTick中断优先级
  31.     NVIC_EnableIRQ(SysTicK_IRQn);            //使能开启Systick中断

  32.     SysTick->CTLR = 0x0001;                  //启动系统计数器STK(HCLK/8时基) 72000000/8=9000000

  33.     return (0);
  34. }

  35. void Systick_Init(void)
  36. {
  37.     //此处在进行初始化的时候设置比较寄存器的值
  38.     SysTick_Config(SystemCoreClock / 8000);//1ms            72M/8000/9000000 = 1/1000 = 1ms
  39. }

  40. //关于STK中断服务函数,由于STK的时基为HCLK/8,且在SysTick初始化配置中设置比较寄存器的值为SystemCoreClock / 8000 = 9000,由此计算的每隔1ms触发1次中断服务函数
  41. void SysTick_Handler(void)
  42. {
  43.     //设置系统计数器寄存器的值
  44.     //系统计数器低位寄存器
  45.     SysTick->CNTL0 = 0;
  46.     SysTick->CNTL1 = 0;
  47.     SysTick->CNTL2 = 0;
  48.     SysTick->CNTL3 = 0;

  49.     //系统计数器高位寄存器
  50.     SysTick->CNTH0 = 0;
  51.     SysTick->CNTH1 = 0;
  52.     SysTick->CNTH2 = 0;
  53.     SysTick->CNTH3 = 0;

  54.     Counter ++;

  55.     if(Counter >= 1000)
  56.     {
  57.         Counter = 0;
  58.     }
  59. }
tim.c文件主要进行SysTick中断初始化配置以及中断服务函数处理,关于具体讲解见程序注释。
main.c文件
  1. #include "debug.h"
  2. #include "systick.h"

  3. extern __IO uint32_t Counter;

  4. /*******************************************************************************
  5. * Function Name  : main
  6. * Description    : Main program.
  7. * Input          : None
  8. * Return         : None
  9. *******************************************************************************/
  10. int main(void)
  11. {
  12.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  13.         //Delay_Init();
  14.         USART_Printf_Init(115200);
  15.         printf("SystemClk:%d\r\n",SystemCoreClock);
  16.         printf("This is printf example\r\n");

  17.         Systick_Init();

  18.         while(1)
  19.         {
  20.             printf("Counter:%d\r\n", Counter);
  21.         }
  22. }
main.c文件主要进行函数初始化以及打印输出相关值。

4下载验证
将编译好的程序下载到开发版并复位,串口打印如下:
图片3.png

95、SysTick.rar

453.18 KB, 下载次数: 130

两只袜子 发表于 2021-5-28 08:56 | 显示全部楼层
个人认为还是很不错的教程,有空研究一下
jcky001 发表于 2021-5-28 08:57 | 显示全部楼层
版主分享的应用教程非常不错啊
pattywu 发表于 2022-1-22 10:16 | 显示全部楼层
这个SysTick,设计的太差,当OS用时,指令用的太多,时钟周期过多,不适合用来当OS的时基。
xdqfc 发表于 2022-1-22 10:36 | 显示全部楼层
本帖最后由 xdqfc 于 2022-1-22 10:38 编辑

咱就是这么用的,程序的确有点变态,做多任务还是可以的,CH573的就简单多了。
pattywu 发表于 2022-1-22 14:34 | 显示全部楼层
定时器有多的,换个其它的定时器当时基,效果会更好一点。
听说,调试的时候,systick是不停的。
觉醒de狮子 发表于 2022-2-9 23:55 | 显示全部楼层
大家好,我看了这个教程,做了下实验,我有些疑问:
在 SysTick_Handler 中需要手动重置 CNT的寄存器为0,我用的是 CH32V103C8T6 MCU,这个是设计如此吗?不能自动重置寄存器吗?

评论

您好,不会自动重置,会一直计数,因此若需要置0,需要在程序中配置  发表于 2022-2-14 13:54
elsaflower 发表于 2023-4-15 19:46 | 显示全部楼层
systick 延时时间怎么计算的?
fengm 发表于 2023-4-16 22:07 | 显示全部楼层
Systick中断打开之后主程序就跑飞了,这个是因为什么呢
yeates333 发表于 2023-4-16 22:14 | 显示全部楼层
利用systick来延时,这阻塞了单片机吗?
lihuami 发表于 2023-4-16 22:57 | 显示全部楼层
CH32V103延时如何不影响其他程序
iyoum 发表于 2023-5-5 18:35 | 显示全部楼层
SysTick中断是一种基于M0+内核的ARM Cortex芯片中的系统定时器中断。它可以提供高度精确的延时或周期性的中断,并用于实现各种系统计时和同步任务。
janewood 发表于 2023-5-5 19:55 | 显示全部楼层
systick具体延时时间怎么计算的?
deliahouse887 发表于 2023-5-5 21:06 | 显示全部楼层
当SysTick寄存器计数到0时,就会产生SysTick中断,然后处理器会跳转到SysTick中断服务程序中执行特定的操作。
wwppd 发表于 2023-5-5 21:26 | 显示全部楼层
systick中断逻辑包括哪些
pentruman 发表于 2023-5-10 20:11 | 显示全部楼层
如何编程设置systick中断发生频率
phoenixwhite 发表于 2023-5-10 20:20 | 显示全部楼层
在使用SysTick中断时,我们需要先进行初始化设置,包括指定计数器的初始值和重载值、设置中断优先级等。之后,我们可以启动SysTick计数器,并在中断服务程序中编写我们需要执行的操作。
backlugin 发表于 2023-5-10 20:45 | 显示全部楼层
systick中断的优先级怎么设置
youtome 发表于 2023-5-10 21:31 | 显示全部楼层
SysTick中断被广泛应用于嵌入式系统中的各种应用场景
chenci2013 发表于 2023-5-10 21:39 | 显示全部楼层
Systick中断打开之后主程序就跑飞了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

133

主题

296

帖子

45

粉丝
快速回复 在线客服 返回列表 返回顶部