滴答时钟与延时

今天写一个稍微简单一点的(看了看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文件
  1. #include "delay.h"
  2. #include "clock_config.h"
  3. void delay_init(void)
  4. {
  5.     SysTick->LOAD  = 10000;                         /* set reload register */
  6.         NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
  7.         SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
  8.         SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
  9. //                     SysTick_CTRL_TICKINT_Msk   |
  10.                      SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
  11. }                                                                    
  12. void delay_us(uint32_t us)
  13. {        
  14.         uint32_t ticks;
  15.         uint32_t told,tnow,tcnt=0;
  16.         uint32_t reload=SysTick->LOAD;                                //LOAD的值                     
  17.         ticks=us * (CLOCK_GetFreq(kCLOCK_CpuClk) / 1000000); //需要的节拍数
  18.         told=SysTick->VAL;                                        //刚进入时的计数器值
  19.         while(1)
  20.         {
  21.                 tnow=SysTick->VAL;        
  22.                 if(tnow!=told)
  23.                 {            
  24.                         if(tnow<told)tcnt+=told-tnow;        //这里注意一下SYSTICK是一个递减的计数器就可以了.
  25.                         else tcnt+=reload-tnow+told;            
  26.                         told=tnow;
  27.                         if(tcnt>=ticks)break;                        //时间超过/等于要延迟的时间,则退出.
  28.                 }  
  29.         };
  30. }
  31.   
  32. void delay_ms(uint16_t ms)
  33. {
  34.         uint32_t i;
  35.         for(i=0;i<ms;i++) delay_us(1000);
  36. }
复制代码

可以看到基本思路就是对比时间,看看是否达到(拷贝的原子的)
CLOCK_GetFreq(kCLOCK_CpuClk)是用来获取CPU的时钟的(因为我们设置了以CPU时钟作为时钟源),该函数使用可以看上个贴子(飞凌RT1052——6.PIT中断与外设时钟配置https://www.nxpic.org.cn/module/foru ... 189&fromuid=3469866(出处: 恩智浦技术社区))
(中断优先级问题本帖暂不讨论)

然后是mian.c文件
  1. #include "fsl_device_registers.h"
  2. #include "fsl_debug_console.h"
  3. #include "board.h"
  4. #include "pin_mux.h"
  5. #include "clock_config.h"
  6. #include "fsl_lpuart.h"
  7. #include "delay.h"
  8. int main(void)
  9. {
  10.     /* Init board hardware. */
  11.     BOARD_ConfigMPU();
  12.     BOARD_InitPins();
  13.     BOARD_BootClockRUN();
  14.     BOARD_InitDebugConsole();
  15. //    PRINTF("hello world.\r\n");
  16.         PRINTF("RT1052 CPU CLK:%d\n\r",CLOCK_GetFreq(kCLOCK_CpuClk));
  17.         delay_init();
  18.     while (1)
  19.     {
  20.                 LPUART_WriteBlocking(LPUART1, "\n\r",2);//阻塞方式发送一串字符
  21.                 delay_ms(1000);
  22.     }
  23. }
复制代码

打印主频,然后每1S发一个换行。
实验效果(此处开启了时间戳)

<ignore_js_op>
 

posted on 2022-06-15 21:27  张凌001  阅读(233)  评论(0编辑  收藏  举报

导航