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

物联网之STM32开发五(时钟系统)

[复制链接]
STMCU-管管 发布时间:2020-9-27 14:48
STM32-时钟系统内容概要:

STM32时钟系统概述

SysTick定时器讲解

HAL_Delay()函数的实现

STM32通用定时器介绍

STM32通用定时器实例

- y7 b3 p3 d" n0 p, S

STM32时钟系统概述
7 U8 J4 m6 D3 }

内容概要:

时钟系统的概念及意义

常见振荡器介绍

时钟树分析

时钟配置

时钟系统的概念及意义:


" x: ?7 E6 R0 Q  h0 ^

概念:时钟系统是由振荡器(信号源)、定时唤醒器、分频器等组成的电路。常用的信号源有晶体振荡器和RC振荡器。

意义:时钟是嵌入式系统的脉搏,处理器内核在时钟驱动下完成指令执行,状态变换等动作,外设部件在时钟的驱动下完成各种工作,比如串口数据的发送、A/D转换、定时器计数等等。因此时钟对于计算机系统是至关重要的,通常时钟系统出现问题也是致命的,比如振荡器不起振、振荡不稳、停振等。


7 i( L) Z( T& a" L" }; p8 X

1_meitu_1.jpg

4 J  Z# C2 Z, V! D9 @5 w4 U

常见振荡器简介:

概念:振荡器是用来产生重复电子讯号的电子元件。其构成的电路叫振荡电路,能将直流电转换为具有一定频率交流信号输出的电子电路或装置。

分类:振荡器主要分为RC,LC振荡器和晶体振荡器。RC振荡器是采用RC网络作为选频移相网络的振荡器。LC振荡器是采用LC振荡回路作为移相和选频网络的正反馈振荡器。晶体振荡器的振荡频率受石英晶体控制。

RC振荡器:

RC振荡器是又电阻电容构成的振荡电路,能将直流电转换为具有一定频率交流信号输出的电子电路或装置。

优点:实现的成本比较低,毕竟就是一个电阻电容

缺点:由于电阻电容的精度问题所以RC振荡器的震荡频率会有误差,同时受到温度、湿度的影响

- r- D+ H) R: c; P4 }5 z$ c

2_meitu_2.jpg

$ V. I/ a! V, t" g

晶体振荡器:

石英晶体振荡器是高精度和高稳定度的振荡器,被广泛应用于彩电、计算机、遥控器等各类振荡电路中,以及通信系统中用于频率发生器、为数据处理设备产生时钟信号和为特定系统提供基准信号。

优点:相对来说震荡频率一般都比较稳定,同时精度也较高

缺点:就是价格要稍微高点了,还有用晶体振荡器一般还需要接两个15-33pF起振电容


- h5 X. U/ ^" o: s. h/ s2 z

3_meitu_3.jpg


4 h  ~, ]& m& E$ H6 h

STM32F0时钟源介绍:

STM32 中有四个时钟源:

    HSI:高速内部时钟,RC振荡器,频率为8MHz;

    HSE:高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz

    LSI:低速内部时钟,RC振荡器,频率为40KHz。独立看门狗时钟源只能是这个,还可做RTC时钟源

    LSE:低速外部时钟,接32.768KHz的石英晶体。这个主要是RTC的时钟源


& r6 U2 q& {! c% |5 m

STM32 时钟树的分析:

( o/ Q* V' x+ y8 U* G' v: M1 w  u, H: Y

4_meitu_4.jpg

5 e0 N- ^. c0 ~% N8 q8 U

8 _( g1 o, U4 s( P% p! y

复位和时钟控制 (RCC):

5_meitu_5.jpg


6 \9 q; j% J1 U4 o: I9 E0 b4 }- k* N' I& H# |% ^+ y

STM32Cubemx配置时钟:

6_meitu_6.jpg

: t+ y" Y9 n- ]7 {0 t) |+ s8 o

# x6 }  d! Z& }6 Y" V

SystemInit () 系统时钟初始化:

void SystemInit(void)

System_stm32f0xx.c中定义,在系统启动之后,程序会先执行 HAL 库定义的 SystemInit 函数,进行系统一些初始化配置,复位 RCC 时钟配置为默认复位值(默认开启 HSI)

void SystemClock_Config(void)

在main.c中定义,实现时钟的具体配置,配置PLL, 配置AHB和HPB的时钟

! R" ^1 a2 W, @+ |1 M/ g


( O: S1 x) |/ b! J1 r

SysTick定时器讲解
& f# t! K4 P0 \" T0 A: c

内容概要:

SysTick定时器简介

SysTick定时器工作原理分析

SysTick寄存器

SysTick定时器使用实例

SysTick定时器简介:

: ~: A! N& K, b

概念:

    定时器,能够定时、计数的器件称为定时器。

    SysTick,  称作系统滴答定时器,简称滴答定时器。是一个定时设备,位于Cortex-M0内核中,可以对输入的时钟进行计数,当然,如果时钟信号是周期性的,计数也就是计时。

    系统定时器一般用于操作系统,用于产生时基,维持操作系统的心跳。根据这个中断,系统就可以实现时间片的计算从而切换进程。

2 J2 ^$ a$ K2 f

工作原理:滴答定时器是一个24位定时器,也就是最多能计数2^24。在使用的时候,我们一般给计数器送一个初始的计数值,计数器向下计数,每来一个时钟信号,计数初值就减一,计数值减到0的时候,就会发出一次中断。然后重新从计数初值再减一计数,循环不断。

SysTick定时器工作原理图:

( n* D5 f) R! ]- Q2 F

7_meitu_7.jpg


! x; b& s+ L2 m: H0 ]
( o4 e6 k2 y; g: F' N

SysTick寄存器:

8_meitu_8.jpg


4 A0 W2 Q/ Q- t/ |3 |  ~$ m2 \. I- P" f  m2 p

9_meitu_9.jpg


; K& i( q) @( J: u7 e5 a
+ M  i0 y8 a; R4 r, k6 }

SysTick定时器初始化:

Main中已经实现对SysTick定时器的初始化


. z( l, \: }) U


  1. 2 w& e# s( v* z% B
  2. void SystemClock_Config(void);
    - I9 ~0 `+ y0 `  J
  3. HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);//HAL_RCC_GetHCLKFreq()函数得到的就是HCLK的频率,除以1000表示1/(HCLK/1000)秒钟计数一次
    4 F5 `4 g1 Z, T4 w; m% ^7 [3 z
  4. SysTick_Config(TicksNumb);
复制代码

5 i5 ~( ^3 G$ v6 s: p1 A
- w: x( Z- ~( T, m" O1 w) f

在core_cm0.h定义了SysTick_Config(uint32_t ticks)


6 d+ P0 `% y) W

10_meitu_10.jpg


+ n6 n) C. h6 f9 k/ T6 ^8 X1 c% `* Y1 ^6 S

SysTick中断相关:


6 \' @/ @3 _$ s! e4 k3 a


3 ]+ a- l. f* b8 F

11_meitu_11.jpg


1 \3 N/ z6 W: |
5 @0 P5 @% }4 i2 b

SysTick定时器使用实例:

, r; T6 e2 {' P: k5 O4 n

实例: 利用SysTick定时器实现0.5秒钟打印一个字符串


# P6 U9 I1 e: t# f0 q$ T! q3 Z0 Z

8 d5 E0 t. Z3 `0 d# U6 L$ }

12_meitu_12.jpg


8 K+ P3 U% `# n/ n8 b) y, ?  g& Y
* b) g/ d5 t& Z- O2 c) V/ ]% `( ~( p

设置串口:


! Y: ^! E& U5 T, j! K0 D0 t

13_meitu_13.jpg

  G4 }9 E3 r. z4 H  w1 V
# z; Y/ i8 `( S3 |/ E" J4 T

设置系统时钟为外部时钟:

14_meitu_14.jpg


4 B. G0 L* m1 S) O! o
. Y1 v0 G, \4 {8 g$ R, C) P% }$ K

追加到回调函数:

15_meitu_15.jpg

5 p; r! N) Z$ \7 p* t

7 o+ ~' L' e3 D* M* s5 b

16_meitu_16.jpg


3 A4 X1 J5 _! ~/ w6 _" U0 l) q- |+ I5 {, `6 P: }3 d$ z; f) t- P

在main.c函数中重新编写fputc 和 回调函数:

17_meitu_17.jpg


) i* X8 X/ a; }
  1. 6 k! q  [2 X+ }9 o% ~) R1 A" N
  2. int fputc(int ch,FILE *f){        / W$ ?9 l+ ^. U4 `5 b" V% D
  3.     while((USART1->ISR&(1<<7)) == 0);       
    " t- ]: W  V% K0 m9 c0 U
  4.     USART1->TDR=(uint8_t)ch;5 X/ {4 O  a& P, T& H
  5.     return ch;7 m& Q8 e) z' l9 z
  6. } . `9 W1 A5 o. _. }

  7. + K0 E/ S4 h2 D  @5 c' F
  8. void HAL_SYSTICK_Callback(void)
      ~2 L: b' f' g, g2 J( ^# D  R' ]- S% G& h
  9. {
    3 M$ D5 }" [( Y, u, L! E% }! o: A
  10.         static int time_flag = 0;
    8 }# v: D5 o1 h0 ~
  11.         time_flag++;" k1 `* d& `$ ?1 y
  12.         if(time_flag >= 500)9 L& V* v. O- v- D, ]* v* k% j' C
  13.         {4 E2 [7 b' ]7 W. i0 `1 Z
  14.                 printf("this is systick test!\n");
    0 N, U$ s' w& x
  15.                 time_flag = 0;
    # L: ~8 _) t4 B# j. v
  16.         }" T9 V: Y2 u: Z8 K7 ]( @
  17. }
复制代码

0 x) P( s6 ?1 G( @

测试结果:

18.png


; A6 q& F; A/ Z6 q" N3 T" V) uHAL_Delay()函数的实现
( S9 b" g  ]1 W

HAL_Delay()分析:

利用SysTick实现精准的延时:

  1. 9 B& D: k0 _' {9 B& N
  2. __weak void HAL_Delay(__IO uint32_t Delay)
    * V9 A9 _0 ?7 x9 q' z
  3. {4 X4 q/ w" ^5 D, t, W$ J' m
  4.   uint32_t    tickstart = 0U;
    ; X  Y  w( P; I  {
  5. 9 q+ B# P; d2 h- z, D8 H4 O
  6.   tickstart     = HAL_GetTick();$ n3 ?% k7 A, z9 z) x5 I
  7.   while((HAL_GetTick() - tickstart) < Delay) ;
    " l1 _+ E' Z2 Z
  8. }
    0 N" i# ~  }' B6 u' J8 {" A. s
复制代码

6 e0 K9 m3 X- ~% L

0 T9 f3 I* _  L" Q9 U2 y0 `

19_meitu_19.jpg


0 z( K4 B! F# `$ e0 F, \

HAL_Delay()  的局限:

HAL库的延时函数有一个局限性,在中断服务函数中使用HAL_Delay会引起混乱,因为它是通过中断方式实现,而 Systick 的中断一般操作系统优先级是最低的,所以在中断中运行 HAL_Delay 会导致死锁的现象。


8 q0 i1 A2 }$ X" z" }


1 p/ j4 J4 W5 Z) e  o

STM32通用定时器介绍2 s2 N% ]- C- r, ~% }4 }
* y1 e: \6 F; j8 g4 S  z

内容概要:

STM32F051定时器介绍

几种定时器功能比较

定时器的计数原理

定时器输入捕获与输出比较

STM32F051定时器介绍:

STM32F051xx 系列器件包括多达 6 个通用定时器,1个基本定时器和1个高级定时器。


0 \$ m. B: T; F1 D2 g" c5 T


7 a) o0 t* m3 n, C2 a

20_meitu_20.jpg


6 f* ~( p; r- w8 }3 k
. x" I7 \/ ?7 p3 ?# U- x

几种定时器功能比较:

通用定时器TIMx功能:

    ● 定时器定时计数

    ● 输入捕获

    ● 输出比较

    ● PWM输出

    ● 使用外部信号控制定时器和定时器互连的同步电路

高级定时器TIM1功能:

    ● 通用定时器的有功能

    ● 带死区控制和紧急刹车,可用于PWM控制电机

基本定时器TIM1功能:

    ● 主要运用于定时计数以及驱动DAC


7 b& f- g  `: u0 I

* k6 @- ?" i3 A- ~. ^. a+ B$ ?

定时器计数模式:

向上计数模式:计数器从0计数到自动加载值(TIMx_ARR),然后重新从0开始计数并且产生一个计数器溢出事件。

向下计数模式:计数器从自动装入的值(TIMx_ARR)开始向下计数到0,然后从自动装入的值重新开始,并产生一个计数器向下溢出事件。

中央对齐模式(向上/向下计数):计数器从0开始计数到自动装入的值-1,产生一个计数器溢出事件,然后向下计数到1并且产生一个计数器溢出事件;然后再从0开始重新计数。


- _6 j: o0 b( R

8 s- d/ x+ w( [% q3 ~+ l7 F- a

21_meitu_21.jpg

' D+ H1 e+ O( B, r8 a" ?( z

2 h  R6 |) A7 B' H# z. d/ k; B

定时器计数原理:(很重要,后面编程时配置通用定时器要用到)


  F9 ?# w. u1 r0 W/ ^4 T$ `

0 C# b/ s+ l" L* T/ |9 P

22_meitu_22.jpg


3 M) X2 J2 x; }! N5 G1 w+ s" X/ t; Z$ p

时钟源:定时器时钟 TIMxCLK,即内部时钟 CK_INT,经 APB 预分频器后分频提供

计数器时钟:定时器时钟经过 PSC 预分频器之后,即 CK_CNT,用来驱动计数器计数

计数器CNT: 是一个 16 位/32的计数器

自动重装载寄存器:这里面装着计数器能计数的最大数值。当计数到这个值的时候,如果使能了中断的话,定时器就产生溢出中断

计时中断时间:     1/(TIMxCLK/(PSC+1))  *  (ARR+1)

定时器输入捕获与输出比较:

输入捕获:输入捕获可以用来捕获外部事件,比如引脚的电平变化(上升沿,下降沿),并记录下变化的时间,通常可以用来测量外部信号的频率或者电平持续的时间。

0 c8 {2 `6 [, d


9 `' Z7 T8 I7 m2 C2 [  R: N

23_meitu_23.jpg


; H; ?' Q- o- y! p  ?. F" P. Z- {1 V

输出比较:此项功能是用来控制一个输出波形,当计数器与捕获/比较寄存器的内容相同时,输出比较功能做出相应动作,比如电平的翻转。通常用于生产PWM波形。

% }- r6 z: A4 g+ ^


+ O) v, I' X6 `6 A2 K' i) O9 I

24_meitu_24.jpg

5 b$ r0 }) w7 m9 Q3 H0 B* H

% T7 W( `# M8 \3 a; n+ ISTM32通用定时器实例2 E' t3 `! `. K" t7 z( \, R1 {

4 I3 s  V- L7 @

STM32定时器使用实例:利用通用定时器实现定时0.5秒中断,并在中断处理函数中打印输出字符。

$ Q" U1 s+ W3 G0 U

25_meitu_25.jpg


' Y6 C# W# o) }5 i! k" ~2 A, S8 P
& C/ W/ N2 r" o! i6 R7 `! R

26_meitu_26.jpg

; H" p  E2 t/ Z# c# r8 x/ x; _

27_meitu_27.jpg

+ J! E1 E5 d% S6 u3 @2 J5 r' Y

28_meitu_28.jpg


6 m+ w( W  `4 {

29_meitu_29.jpg

* y$ P& v" {$ f) [; p
7 J! v6 W7 z* p8 T1 J% t

追加到回调函数:

( |) T9 e- n7 H5 o+ h- A4 ]. S" r  n

30_meitu_30.jpg

31_meitu_31.jpg

重新编写fputc 和 回调函数:

: |  i5 q( J, A5 L& ?! d

32_meitu_1.jpg

% T9 I5 Z& g& G, k/ Q+ a  ?
  1.   r+ w" D' ~$ N4 S& L" d; b% e
  2. ​int fputc(int ch,FILE *f){        4 L5 V# |) q$ z+ W( z
  3.     while((USART1->ISR&(1<<7)) == 0);       
    : y- k" ]- s0 @- I
  4.     USART1->TDR=(uint8_t)ch;  d. C8 ~4 e% w' p+ |/ R- l& ?
  5.     return ch;$ `' i* ]  _+ e& s) k  M8 a
  6. } 7 C9 `3 d3 f) R4 A
  7. 7 b; l( s# L) Q) S: R! Q. A
  8. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim); K) _# o' B1 T( G
  9. {
    % u: D$ u7 s0 Y' M
  10.         if(htim->Instance == TIM3)6 W" I4 b7 P, m% j" D& e" ]
  11.         {+ O8 L' P2 Q. z) D
  12.                 printf("my name is 张三\n");
    2 ^3 y! g" q* i( f1 a  i1 f/ P) |: K
  13.         }
    # l4 w( \  `- i. ~2 l9 e$ E
  14. }
复制代码
8 w) v4 I( C2 L  R/ O9 r; x" @

启动定时器并使能中断:

* ~1 e3 \. o$ h* k% _2 U' P: t0 F


+ G! g! k0 P5 _* U5 A( r

33_meitu_2.jpg

8 X2 D) |7 `2 x( c0 ~1 X7 H
  1. HAL_TIM_Base_Start_IT(&htim3);//启动定时器并使能中断
复制代码

" c. Y& z5 Q0 Y& ]

测试结果:


+ u' p: |- D2 Q7 ]. N

34.png

2 h8 o  [" {* K% T7 L; E, ?
4 @4 \  ]* y" n8 m1 d8 F& H# V
赞 收藏 1 评论0 发布时间:2020-9-27 14:48

举报

0个回答

所属标签

相似技术帖

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