<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/LearnCH32V307VCT6" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>
说明
系统滴答定时器是系统内核(RISC-V内核)自带的定时器.
有人会问:那后面学到的那些通用定时器,高级定时器呢?
那些都是外设,然后依靠总线(导线)和它通信控制其实现具体功能.
又比如说:单片机有串口功能,实际上就是内核+硬件串口的组合, 内核通过总线控制硬件串口通信.
随便看一个工程
1,官方给了一个不使用中断操作滴答定时器的例子
具体呢不做讨论了,直接使用就可以.
(对于初学者不必深究,即使深究最终也只是配置寄存器而已, 先学会用,然后使用遇到问题时再解决)
现在看中断方式
#include "debug.h" #include "ch32v30x.h" volatile uint16_t SysTickCnt=0; void SysTick_init(void) { /*配置中断优先级*/ NVIC_InitTypeDef NVIC_InitStructure = {0}; NVIC_InitStructure.NVIC_IRQChannel = SysTicK_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占式优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//响应式优先级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能 NVIC_Init(&NVIC_InitStructure); /*配置定时器*/ SysTick->CTLR= 0; SysTick->SR = 0; SysTick->CNT = 0; SysTick->CMP = SystemCoreClock/1000;//后面的1000代表1000HZ(那就是1ms进一次中断) SysTick->CTLR= 0xf; } __attribute__((interrupt("WCH-Interrupt-fast"))) void SysTick_Handler(void) { SysTick->SR=0;//清除中断 SysTickCnt++; } int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置优先级分组为2 USART_Printf_Init(115200); SysTick_init(); while(1) { if (SysTickCnt>=1000) { SysTickCnt=0; printf("1111111111\r\n"); } } }
下载测试会看到串口每隔1S打印一次数据
上面就是说完了, 我说一下我是如何写的上面的程序
其实没有例程....
但是呢,官方提供了一个FreeRTOS(操作系统)的例子,
大家伙要知道,所有的操作系统都要依靠定时器来切换任务, 一般都是使用系统滴答定时器
我就全局搜索 SysTick_Handler, 然后翻了翻就找到了
补充
void delay_uss(int64_t us) { volatile int64_t ticks; ticks = SystemCoreClock / 1000000; ticks = ticks * us / 20; while(ticks>0)ticks = ticks -1; }