你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】stm32 滴答时钟实现较准时延时功能

[复制链接]
STMCU小助手 发布时间:2022-2-3 18:00
前记:
  以前自己在编写延时函数的时候,经常是for()结构或者while()结构以及do while{}结构。但这3种方法是非常的粗糙,在我现在的工作中是不能满足其精度的。由于stm32中有个滴答时钟,于是以后stm32相关的延时程序,打算拿它作挡箭牌了。
  首先是,stm32 的数据手册上并没有滴答时钟的东西,只说了其会产生中断,具体如何,没说。谷歌了几遍,又查询了些许资料,发现来源于<<xxx权威指南>>和<<xxx技术手册>>。
  然后在网上发现使用其作为延迟功能有两个方法,一个是使用中断方式,一个是使用查询方式<非中断>。由于尚未学习stm32中断配置方法,于是先使用正点原子的 查询方式。在这里感谢正点原子的分享!下附具体代码和调用例程代码。

1 \& W4 x0 I, g" w* m
延时程序的头文件Delay.h
  1. #ifndef _DELAY_H_
    + R- }" f& Y/ l5 r% Y+ |
  2. #define _DELAY_H_. W+ f) ^% L; p0 R- O

  3. / \" U+ k7 o; c6 F1 v/ X
  4. void delay_init(u8 SYSCLK);
    5 J: m) L& {9 ^3 a. H
  5. void delay_ms(u16 nms);3 h! n' e; t$ G
  6. void delay_us(u32 Nus);
    $ z2 d, D" M* H, X' _6 s
  7. ( ~/ [9 H0 O& o

  8. 0 a' l, V6 G  o; [
  9. #endif
复制代码
" D; y, [. `7 b" L+ G/ ~
延时程序实现文件Delay.c
  1. /**********************************************************1 \: a% u2 S+ H, l- \( G
  2. 文件:Delay.c# ^9 l  P$ C6 u! W
  3. 函数:void delay_init(u8 SYSCLK);% b$ C8 K& _4 }3 _! F
  4.       void delay_ms(u16 nms);
    8 I9 m/ U$ B  I3 i: W
  5.       void delay_us(u32 Nus);. ^: X1 V% H' v& Q* W
  6. 说明:三个函数实现的功能是不采用中断方式,并且用stm32系统滴答时钟来实现延时功能。* m2 b! x7 N# M/ r
  7.      出自 正点原子<<stm32不完全手册>> -- 该程序设计的理念在该书中已经讲解。      
    ' w1 f0 u( L. S. F, ^2 \
  8. ***********************************************************/% t4 v6 W5 }3 Z

  9. " m0 V% k: M0 e; G% Q0 c5 z

  10. 3 G  k5 @9 E' N6 ?/ p, e
  11. #include <stm32f10x.h>
    : J( i2 A# N% \7 p/ C
  12. #include "Delay.h"
      l1 C2 @8 T8 _, y8 p$ [

  13. + S/ f  ]& w! p/ Z* @

  14. 9 T1 m! t" U# l/ ^
  15. static u8  fac_us=0;//us延时倍乘数9 _( P( _, k! R
  16. static u16 fac_ms=0;//ms0 ?/ i- b5 r% P; H2 `# i' t
  17. 7 I5 [$ ?5 W6 m7 Z& Q. c' W/ P* n
  18. /**************************************************- A% M) {$ z! O( ^
  19. Name: delay_init
    6 x$ j4 e) n. x' y
  20. 功能:应用程序延时函数初始化,包括为滴答时钟准备相关数值& u" w6 C: u5 L( |
  21. 参数:u8 SYSCLK% `; K/ y" I7 [# l$ Q3 U8 c2 o3 S
  22. 返回:None
    " o- f4 V  D% z% m6 Z3 V
  23. ***************************************************/
    : A" W& L0 ?2 d+ z1 n& t' j. x
  24. void delay_init(u8 SYSCLK)
    2 v' a! P/ H; M  S
  25. {. g7 I3 U$ N( [3 [0 G4 s
  26.     SysTick->CTRL&=0xfffffffb;//设置滴答时钟的时钟源:bit 2清空,选择外部时钟HCLK/8
    , Y' S2 Y$ t2 N; \
  27.     fac_us = SYSCLK / 8;
    7 S1 |+ z" E* Y
  28.     fac_ms = (u16)fac_us*1000;   
    8 N" @' ?1 L9 i6 E2 k! D
  29. }% U  u! e) P) b6 [% B* q, `) X; K
  30. /**************************************************
    # n1 T7 Z5 m( Q( L7 ~# i3 A. l9 F
  31. 名字:delay_ms
    5 q/ s. X; I9 y5 n, B
  32. 共能:应用程序ms级别的延时实现
    ; a1 U; _" t( D7 |- o5 f
  33. 参数:u16 nms
    ) Y* u1 `/ i( |- Z8 ?
  34. 返回:None$ f; N! P; N- g4 w! z6 X2 T. D
  35. ***************************************************/, G3 A  Q; T, o/ x
  36. void delay_ms(u16 nms)
    ' V8 y1 E/ W# p
  37. {        
    ' N! A; g" {4 S# s( K$ ~. c
  38. u32 temp;   
      O5 x) d4 x5 D$ x8 }
  39. SysTick->LOAD=(u32)nms*fac_ms;//时间加载
    3 P' u! z/ S5 d& ^/ w
  40. SysTick->VAL =0x00;           //清空计数器
    & Z& f9 \4 T, Y! v
  41. SysTick->CTRL=0x01 ;          //开始倒数 1 E: [7 B! Z. u) ?8 I0 i, i
  42. do6 A1 q7 ]) o) i( w! Y
  43. {. y6 u! [3 D9 b* t" h. w
  44.   temp=SysTick->CTRL;
    6 `0 M0 u0 x6 A+ f
  45. }
    # \& |4 c) s3 L, {* I$ c3 J7 P$ @
  46. while(temp&0x01&&!(temp&(1<<16)));//等待时间到达  9 f  h; A" D$ e' z3 Z2 Q
  47. SysTick->CTRL=0x00;       //关闭计数器& J3 G) P+ ^. x; p% H4 N. t
  48. SysTick->VAL =0X00;       //清空计数器         m/ G# p) D3 [& D
  49. }  
    7 j- Z" x8 f  m3 \+ c; \

  50.   ~6 r- a% M7 |& N+ S, v
  51. /***********************************************************# k( \/ v* n, O& J. ^2 d
  52. 名字:delay_us
    ) U: f- Y: X  \5 a+ |, Z" f7 Z
  53. 功能:应用程序us级别的延时实现
    / |  r; p  l7 u' @9 M* Q
  54. 参数:u32 Nus" O7 A5 M, @8 T0 [
  55. 返回:None: U, f# N7 ?7 h& e
  56. ************************************************************/         
    ' w2 F' j3 Y7 D. F: l
  57. void delay_us(u32 Nus)# z% A: K8 E9 J+ l6 Q% z2 r" s
  58. {  & N- {' `, U) F* I: q4 F
  59. u32 temp;      9 g( l5 o$ P" c) {3 U$ n
  60. SysTick->LOAD=Nus*fac_us; //时间加载     
    ( U9 L* D  `- h' Z' B( }2 z9 L9 ]. g
  61. SysTick->VAL=0x00;        //清空计数器
    & a$ i' m/ k& G: z
  62. SysTick->CTRL=0x01 ;      //开始倒数  
    " ~6 S+ g7 h9 p. Z$ B
  63. do
    . Y. @( ]" c" {4 X: T
  64. {
    # v- b7 N9 L% n$ R) ]) e. n8 A) b. V+ @
  65.   temp=SysTick->CTRL;6 n! P1 _* i7 J
  66. }% V- ~2 g5 [+ z! ?, M
  67. while(temp&0x01&&!(temp&(1<<16)));//等待时间到达  
    9 s" D0 b2 @* U" I
  68. SysTick->CTRL=0x00;       //关闭计数器
    * C6 N; w( T( E/ B+ N
  69. SysTick->VAL =0X00;       //清空计数器   
    . D" R! l8 U1 a, x" J2 N7 b% u1 A
  70. }
复制代码
, P- |; ?5 x3 R( O3 y
调用该延时函数的例程 test.c
  1. #include <stm32f10x.h>
    + i, i7 K3 I; F6 K& k
  2. #include "Hardware/led.h"! h: E* X; J. f0 j
  3. #include "Delay.h"
    : O9 C2 Y% g1 r6 A/ L
  4. 4 \" j+ s! m$ |7 Z5 w- d
  5. /*LED 灯闪灭函数*/% ?( H; U  ]$ Q; B
  6. void loop(void)% k& j/ Z# W! w
  7. {1 J# v+ B7 q1 A, c+ D$ s, d' V
  8.     while(1){    1 `' N) R' Q: e; g% m% e8 {
  9.         GPIO_ResetBits(GPIOD, GPIO_Pin_2);% O* q% |" x! G. i/ f
  10.         delay_ms(1000); //ms级别延时函数的调用8 Y4 H: O' y" _4 }
  11.         GPIO_SetBits(GPIOD, GPIO_Pin_2);
    # T' F) [; n5 b! T# S( d" n2 ^' k2 ~! k/ j
  12.         delay_ms(1000);: F# v8 I; C  T- M4 K% b: T/ I
  13.         }
    8 S% N6 W- `6 F$ H
  14. }
    8 r+ r; d. t/ s) R- w+ o; x

  15. $ e' E, n9 N3 `$ g
  16. int main()# L6 x3 Z3 i! Z0 @. J5 Z1 n
  17. {+ ^. J1 O, F4 u5 T! l5 S
  18.     SystemInit();
      M" N% N1 P% X# t9 Y9 N2 \
  19.     delay_init(72);//延时函数初始化,并传参数
    $ @/ O5 j: [9 F( j' t
  20.     led_init();//led初始化# A% l! l- K- x$ s( h  q
  21.     loop();//调用led闪灭函数* x" G9 u+ \6 @! x+ w
  22. }
复制代码
/ k5 f1 F  O8 \! S, d! G- L' Q

3 q- `. i9 H7 i& ?
$ A* O( d! P5 @" M
收藏 评论0 发布时间:2022-2-3 18:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版