滴答时钟与延时
作者:互联网
今天写一个稍微简单一点的(看了看M7内核的滴答时钟和其他M内核的没啥区别。。。。。。。)。
一般在单片机里面,一般用滴答时钟进行延时。今天我们写一个用滴答时钟进行延时的程序。
因为滴答时钟的需要的寄存器比较少(一共只有4个,其中还有1个不常用)就全放出来吧。
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>
可以看到SYST_CSR是配置滴答时钟的关键。
COUNTFLAG 表示计数曾经到0了(延时可以用这个判断,这次的程序没用这个判断)
CLKSOURCE 用来选择时钟源
TICKINT 是否开启中断
ENABLE 使能滴答时钟
SYST_RVR RELOAD 设置重装值(滴答时钟为减定时器)
SYST_CVR CURRENT 读取当前计数,或者清空计数。
SYST_CALIB (不常用,不提了)
而且官方还提供了一个配置的函数(这次就是直接拷贝的这个,改了一下,官方的开启中断了,这里没开启,然后SysTick->LOAD随便给了个值)
<ignore_js_op>
先上代码,delay.c文件
可以看到基本思路就是对比时间,看看是否达到(拷贝的原子的)
CLOCK_GetFreq(kCLOCK_CpuClk)是用来获取CPU的时钟的(因为我们设置了以CPU时钟作为时钟源),该函数使用可以看上个贴子(飞凌RT1052——6.PIT中断与外设时钟配置https://www.nxpic.org.cn/module/foru ... 189&fromuid=3469866(出处: 恩智浦技术社区))
(中断优先级问题本帖暂不讨论)
然后是mian.c文件
打印主频,然后每1S发一个换行。
实验效果(此处开启了时间戳)
<ignore_js_op>
一般在单片机里面,一般用滴答时钟进行延时。今天我们写一个用滴答时钟进行延时的程序。
因为滴答时钟的需要的寄存器比较少(一共只有4个,其中还有1个不常用)就全放出来吧。
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>
<ignore_js_op>
可以看到SYST_CSR是配置滴答时钟的关键。
COUNTFLAG 表示计数曾经到0了(延时可以用这个判断,这次的程序没用这个判断)
CLKSOURCE 用来选择时钟源
TICKINT 是否开启中断
ENABLE 使能滴答时钟
SYST_RVR RELOAD 设置重装值(滴答时钟为减定时器)
SYST_CVR CURRENT 读取当前计数,或者清空计数。
SYST_CALIB (不常用,不提了)
而且官方还提供了一个配置的函数(这次就是直接拷贝的这个,改了一下,官方的开启中断了,这里没开启,然后SysTick->LOAD随便给了个值)
<ignore_js_op>
先上代码,delay.c文件
- #include "delay.h"
- #include "clock_config.h"
- void delay_init(void)
- {
- SysTick->LOAD = 10000; /* set reload register */
- NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
- SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
- SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
- // SysTick_CTRL_TICKINT_Msk |
- SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
- }
- void delay_us(uint32_t us)
- {
- uint32_t ticks;
- uint32_t told,tnow,tcnt=0;
- uint32_t reload=SysTick->LOAD; //LOAD的值
- ticks=us * (CLOCK_GetFreq(kCLOCK_CpuClk) / 1000000); //需要的节拍数
- told=SysTick->VAL; //刚进入时的计数器值
- while(1)
- {
- tnow=SysTick->VAL;
- if(tnow!=told)
- {
- if(tnow<told)tcnt+=told-tnow; //这里注意一下SYSTICK是一个递减的计数器就可以了.
- else tcnt+=reload-tnow+told;
- told=tnow;
- if(tcnt>=ticks)break; //时间超过/等于要延迟的时间,则退出.
- }
- };
- }
- void delay_ms(uint16_t ms)
- {
- uint32_t i;
- for(i=0;i<ms;i++) delay_us(1000);
- }
可以看到基本思路就是对比时间,看看是否达到(拷贝的原子的)
CLOCK_GetFreq(kCLOCK_CpuClk)是用来获取CPU的时钟的(因为我们设置了以CPU时钟作为时钟源),该函数使用可以看上个贴子(飞凌RT1052——6.PIT中断与外设时钟配置https://www.nxpic.org.cn/module/foru ... 189&fromuid=3469866(出处: 恩智浦技术社区))
(中断优先级问题本帖暂不讨论)
然后是mian.c文件
- #include "fsl_device_registers.h"
- #include "fsl_debug_console.h"
- #include "board.h"
- #include "pin_mux.h"
- #include "clock_config.h"
- #include "fsl_lpuart.h"
- #include "delay.h"
- int main(void)
- {
- /* Init board hardware. */
- BOARD_ConfigMPU();
- BOARD_InitPins();
- BOARD_BootClockRUN();
- BOARD_InitDebugConsole();
- // PRINTF("hello world.\r\n");
- PRINTF("RT1052 CPU CLK:%d\n\r",CLOCK_GetFreq(kCLOCK_CpuClk));
- delay_init();
- while (1)
- {
- LPUART_WriteBlocking(LPUART1, "\n\r",2);//阻塞方式发送一串字符
- delay_ms(1000);
- }
- }
打印主频,然后每1S发一个换行。
实验效果(此处开启了时间戳)
<ignore_js_op>
标签:滴答,delay,延时,SysTick,tnow,include,时钟 来源: https://www.cnblogs.com/zhugeanran/p/16379896.html