微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > stm32 滴答时钟实现较准时延时功能

stm32 滴答时钟实现较准时延时功能

时间:10-02 整理:3721RD 点击:

前记:

  以前自己在编写延时函数的时候,经常是for()结构或者while()结构以及do while{}结构。但这3种方法是非常的粗糙,在我现在的工作中是不能满足其精度的。由于stm32中有个滴答时钟,于是以后stm32相关的延时程序,打算拿它作挡箭牌了。

  首先是,stm32 的数据手册上并没有滴答时钟的东西,只说了其会产生中断,具体如何,没说。谷歌了几遍,又查询了些许资料,发现来源于<<xxx权威指南>>和<<xxx技术手册>>。

  然后在网上发现使用其作为延迟功能有两个方法,一个是使用中断方式,一个是使用查询方式<非中断>。


延时程序的头文件Delay.h

  1. #ifndef _DELAY_H_
  2. #define _DELAY_H_

  3. void delay_init(u8 SYSCLK);
  4. void delay_ms(u16 nms);
  5. void delay_us(u32 Nus);


  6. #endif

复制代码

[size=12.7272720336914px]延时程序实现文件Delay.c

  1. /**********************************************************
  2. 文件:Delay.c
  3. 函数:void delay_init(u8 SYSCLK);
  4.       void delay_ms(u16 nms);
  5.       void delay_us(u32 Nus);
  6. 说明:三个函数实现的功能是不采用中断方式,并且用stm32系统滴答时钟来实现延时功能。
  7.      出自 正点原子<<stm32不完全手册>> -- 该程序设计的理念在该书中已经讲解。      
  8. ***********************************************************/


  9. #include <stm32f10x.h>
  10. #include "Delay.h"


  11. static u8  fac_us=0;//us延时倍乘数
  12. static u16 fac_ms=0;//ms

  13. /**************************************************
  14. Name: delay_init
  15. 功能:应用程序延时函数初始化,包括为滴答时钟准备相关数值
  16. 参数:u8 SYSCLK
  17. 返回:None
  18. ***************************************************/
  19. void delay_init(u8 SYSCLK)
  20. {
  21.     SysTick->CTRL&=0xfffffffb;//设置滴答时钟的时钟源:bit 2清空,选择外部时钟HCLK/8
  22.     fac_us = SYSCLK / 8;
  23.     fac_ms = (u16)fac_us*1000;   
  24. }
  25. /**************************************************
  26. 名字:delay_ms
  27. 共能:应用程序ms级别的延时实现
  28. 参数:u16 nms
  29. 返回:None
  30. ***************************************************/
  31. void delay_ms(u16 nms)
  32. {        
  33. u32 temp;   
  34. SysTick->LOAD=(u32)nms*fac_ms;//时间加载
  35. SysTick->VAL =0x00;           //清空计数器
  36. SysTick->CTRL=0x01 ;          //开始倒数
  37. do
  38. {
  39.   temp=SysTick->CTRL;
  40. }
  41. while(temp&0x01&&!(temp&(1<<16)));//等待时间到达  
  42. SysTick->CTRL=0x00;       //关闭计数器
  43. SysTick->VAL =0X00;       //清空计数器      
  44. }  

  45. /***********************************************************
  46. 名字:delay_us
  47. 功能:应用程序us级别的延时实现
  48. 参数:u32 Nus
  49. 返回:None
  50. ************************************************************/         
  51. void delay_us(u32 Nus)
  52. {  
  53. u32 temp;      
  54. SysTick->LOAD=Nus*fac_us; //时间加载     
  55. SysTick->VAL=0x00;        //清空计数器
  56. SysTick->CTRL=0x01 ;      //开始倒数  
  57. do
  58. {
  59.   temp=SysTick->CTRL;
  60. }
  61. while(temp&0x01&&!(temp&(1<<16)));//等待时间到达  
  62. SysTick->CTRL=0x00;       //关闭计数器
  63. SysTick->VAL =0X00;       //清空计数器   
  64. }

复制代码

  1. 调用该延时函数的例程 test.c

复制代码

  1. #include <stm32f10x.h>
  2. #include "Hardware/led.h"
  3. #include "Delay.h"

  4. /*LED 灯闪灭函数*/
  5. void loop(void)
  6. {
  7.     while(1){   
  8.         GPIO_ResetBits(GPIOD, GPIO_Pin_2);
  9.         delay_ms(1000); //ms级别延时函数的调用
  10.         GPIO_SetBits(GPIOD, GPIO_Pin_2);
  11.         delay_ms(1000);
  12.         }
  13. }

  14. int main()
  15. {
  16.     SystemInit();
  17.     delay_init(72);//延时函数初始化,并传参数
  18.     led_init();//led初始化
  19.     loop();//调用led闪灭函数
  20. }

复制代码



Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top