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

MiniPro STM32H750 开发指南_V1.1-蜂鸣器实验

[复制链接]
STMCU小助手 发布时间:2022-10-7 12:43
蜂鸣器实验
2 G; @  a1 N5 N/ C8 n6 q# B  v6 t本章,我们将通过另外一个例子继续讲述STM32H7的IO口作为输出的使用,不同的是本章讲的不是用IO口直接驱动器件,而是通过三极管间接驱动。我们将利用一个IO口来控制板载的有源蜂鸣器。
/ U" j( m& ]+ X! l
( J+ ^& K% r0 N3 Q0 i14.1 蜂鸣器简介
5 S4 f( I( r3 l7 a! H8 C! i  y蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。; K, w" q" x: Z) \9 C) B8 H( i' K
MiniPRO STM32H750开发板板载的蜂鸣器是电磁式的有源蜂鸣器,如图14.1.1所示:/ ?8 H, z! w6 Z( p9 |+ ~+ s
+ \- m, E( q$ l3 g
38c784882c104f0384930fe335326bf9.png
7 K' D7 G; T. y8 a
- i. r4 G# M& }8 x% b% m图14.1.1 有源蜂鸣器1 W3 J: M- z' q9 h6 \% b* ?
这里的有源不是指电源的 “源”,而是指有没有自带震荡电路,有源蜂鸣器自带了震荡电路,一通电就会发声;无源蜂鸣器则没有自带震荡电路,必须外部提供2~5Khz左右的方波驱动,才能发声。
$ i: e' {( w  A1 [# e  |* t上一章,我们利用STM32的IO口直接驱动RGB灯,本章的蜂鸣器,我们能否直接用STM32的IO口驱动呢?让我们来分析一下:STM32H7的单个IO最大可以提供25mA电流(来自数据手册),而蜂鸣器的驱动电流是30mA左右,两者十分相近,但是全盘考虑,STM32H7整个芯片的电流,最大也就150mA,如果用IO口直接驱动蜂鸣器,其他地方用电就得省着点了,所以我们不用STM32H7的IO直接驱动蜂鸣器,而是通过三极管扩流后再驱动蜂鸣器,这样STM32H7的IO只需要提供不到1mA的电流就足够了。
$ Q" i+ p+ c4 r3 `4 U: L/ XIO口使用虽然简单,但是和外部电路的匹配设计,还是要十分讲究的,考虑越多,设计就越可靠,可能出现的问题也就越少。
1 ~' p" t! d/ ~2 w( O  I7 N9 n5 d; u! ]; v
14.2 硬件设计3 c0 @, I' ]+ Q% O
1.例程功能: z. O; V* E2 G6 a& d( n
蜂鸣器每隔300ms响或者停一次。LED0每隔300ms亮或者灭一次。LED0亮的时候蜂鸣器不叫,而LED0熄灭的时候,蜂鸣器叫。/ n1 R1 ?: k2 T8 s: K+ P: G* c
2.硬件资源
2 G( w5 n3 q+ W0 P  }5 e& a1)RGB灯0 p4 u# e% g& H# ?7 D  d
LEDR : LED0 - PB4(红)3 Z$ h5 H7 S+ d+ w4 O+ T
2)蜂鸣器
1 Z$ h4 t; g1 Y" g- v$ x# \, `BEEP(PE4)
$ `+ m6 x4 g" v$ v3.原理图
) v  j+ H' T- Y8 R! V蜂鸣器在硬件上是直接连接好了的,不需要经过任何设置,直接编写代码就可以了。蜂鸣器的驱动信号连接在STM32H7的PE4上。如图14.2.1所示:
, l+ Q& w+ [8 [5 Q$ a) _6 z5 H& p) I( ? 1ab0620eafb54148bdf11a7a6e2f1a61.png 7 R, |; f9 ^# |! U

! O9 M# C3 U4 u7 r& l图14.2.1 蜂鸣器与STM32H7连接原理图
3 a$ i( Y7 m" v. N9 O( e图中我们用到一个NPN三极管(S8050)来驱动蜂鸣器,R30主要用于防止蜂鸣器的误发声。驱动信号通过R29和R30间的电压获得,芯片上电时默认电平为低电平,故上电时蜂鸣器不会直接响起。当PE4输出高电平的时候,蜂鸣器将发声,当PE4输出低电平的时候,蜂鸣器停止发声。
- c2 I: {5 T! Z# r. u/ Q3 v; g* a* t& Q9 t: ~$ r; p
14.3 程序设计
4 N! c( m/ q! i/ q本实验我们只是用到GPIO外设输出功能,关于HAL库的GPIO的API函数请看跑马灯实验的介绍。下面我们直接分析本实验的程序流程图。
# Y6 h5 [( Z. O' E1 d- G7 U6 ~  A14.3.1 程序流程图2 V7 [3 V; ~& x
+ Q/ L, z! H( l6 c" `6 b+ R5 T
922ff991783a47d6a91e369410838f35.png - t0 Y* f3 {) G( Q' _3 v

& m) m4 H8 F- Q图14.3.1.1 蜂鸣器实验程序流程图& b: }: w+ b* r2 w; ~0 V8 u' J! ~

+ e2 d# a# ~0 M5 b# R; b5 H$ m. [6 ^# t14.3.2 程序解析
3 p  l$ m; A+ l: g1.蜂鸣器驱动代码
. [, z$ q! H. b) _5 {8 L; U这里我们只讲解核心代码,详细的源码请大家参考光盘本实验对应源码。蜂鸣器(BEEP)驱动源码包括两个文件:beep.c和beep.h。2 ~' u" L+ \& _" _
下面我们先解析beep.h的程序,我们把它分两部分功能进行讲解。* D0 O% X! `$ b5 F& n
由硬件设计小节,我们知道驱动蜂鸣器的三极管在硬件上连接到PE4,我们做了下面的引脚定义。: Z/ b' N3 \' ]$ a- c% C
  1. /*****************************************************************************/
    : {' M: `; N! K1 h  z
  2. /* 引脚 定义 */
    + r  U* O7 d* w
  3. ! S: B# k# {) h7 D" `) _$ U& Q( w
  4. #define BEEP_GPIO_PORT                 GPIOE
    1 ~$ k1 J7 S% k: s" W
  5. #define BEEP_GPIO_PIN                  GPIO_PIN_4
    - y+ L6 _- h0 q4 c& G
  6. /* PE口时钟使能 */
    : y$ X3 [+ E) S+ ~
  7. #define BEEP_GPIO_CLK_ENABLE()       do{ __HAL_RCC_GPIOE_CLK_ENABLE(); }while(0)2 J" D1 q* _* Q1 n/ w) [' W
  8. /*****************************************************************************/
    9 Y# T- t) f) D+ q( }* a
  9. 可以看到这样定义跟跑马灯实验的是类似。
    ( x" q; D. _; w
  10. 为了后续对蜂鸣器进行便捷的操作,我们为蜂鸣器操作函数做了下面的定义。, f4 M8 L; q3 |8 G' _/ m6 d
  11. /* 蜂鸣器控制 */
      n0 L4 q8 P6 \3 k; `4 g# t
  12. #define BEEP(x)   do{ x ? \
    , V" t% J! o- u: C* O# u9 a  g
  13.                          HAL_GPIO_WritePin(BEEP_GPIO_PORT,: s/ R) [$ ^, q- n& V& e* ~# D
  14.      BEEP_GPIO_PIN, GPIO_PIN_SET) : \
    4 \4 ?# o2 a/ \! Y3 Q
  15.                          HAL_GPIO_WritePin(BEEP_GPIO_PORT, - @  c9 R) m; \" b  n
  16. BEEP_GPIO_PIN, GPIO_PIN_RESET); \" a6 j" y0 s  P) D+ E
  17.                      }while(0), t7 s( X" b1 W, r7 E" p  x. r
  18. 7 V7 b# v( U  J2 S
  19. /* 蜂鸣器取反控制 */
    6 X+ t- Z3 @' u3 ?) J5 A
  20. #define BEEP_TOGGLE()  do{ HAL_GPIO_TogglePin(BEEP_GPIO_PORT, 1 O3 Q  n# Y( L% d  `
  21. BEEP_GPIO_PIN); }while(0)  /* BEEP = !BEEP */
    2 z' n+ j. {/ m
  22. BEEP(x)这个宏定义就是控制蜂鸣器的打开和关闭的。例如:如果要打开蜂鸣器,那么调用宏定义BEEP(1)即可,如果要关闭蜂鸣器,调用宏定义BEEP(0)即可。
    $ T& F, E2 T; M% \9 d) L
  23. BEEP_TOGGLE()是控制蜂鸣器进行翻转的。这里也利用HAL_GPIO_TogglePin函数实现IO口输出电平取反操作。+ P  s1 ^. l) B) B. \% L# C
  24. 下面我们再解析beep.c的程序,这里只有一个函数beep_init,这是蜂鸣器的初始化函数,其定义如下:( g: j, Q  ?  l! u& O/ H
  25. /**
    + q$ l& ^  a) B. S0 b, U1 Q; Q
  26. * @brief       初始化BEEP相关IO口, 并使能时钟; M5 i2 v( |( @1 [- g
  27. * @param       无$ U1 z, K! Q1 R0 U' p
  28. * @retval      无( w6 p3 L% P6 h( |& u4 P
  29. */
    9 e( a$ O+ x) N( Z2 l
  30. void beep_init(void)
    # d4 T$ K( C9 F* O
  31. {
    ) i7 N- D- f+ p
  32.     GPIO_InitTypeDef gpio_init_struct;
    ! T7 o0 }, |7 S- I' v7 ^0 P8 e: x
  33.     BEEP_GPIO_CLK_ENABLE();                                       /* BEEP时钟使能 */
    5 Z  s( l. K8 d, S" @5 N- B
  34. 7 b; b. n7 W9 S7 o: M
  35.     gpio_init_struct.Pin = BEEP_GPIO_PIN;                      /* 蜂鸣器引脚 */& }3 Y/ B% e$ W. |$ ]
  36.     gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;              /* 推挽输出 */+ P+ I+ s7 i0 F
  37.     gpio_init_struct.Pull = GPIO_PULLUP;                        /* 上拉 */
    - Y5 ~% N6 |/ W) I- m, Y9 E  D
  38.     gpio_init_struct.Speed = GPIO_SPEED_FREQ_MEDIUM;          /* 中速 */0 G! }6 X* [7 a  _
  39.     HAL_GPIO_Init(BEEP_GPIO_PORT, &gpio_init_struct);         /* 初始化蜂鸣器引脚 *// H2 n; t$ ?( Z2 z. i

  40. * E, Q, ?  r2 l# i- q
  41.     BEEP(0);                                                          /* 关闭蜂鸣器 */# J/ H  P2 `  f2 [, W
  42. }
复制代码
$ T6 ?9 x* L) s$ p3 p: O0 ^
对蜂鸣器的引脚设置为中速上拉的推挽输出。最后关闭关闭蜂鸣器,防止没有操作就响了。
6 I  @8 h$ A, @4 U0 o7 X2. main.c代码+ o4 g+ a1 o7 Z, F
在main.c里面编写如下代码:5 h/ u) P7 r# T, [0 T/ Y

0 I. B) p+ z4 @5 }9 P0 X
  1. #include "./SYSTEM/sys/sys.h"
    8 x9 L" _+ _3 V2 c
  2. #include "./SYSTEM/usart/usart.h"
    ) z9 h/ L7 A& S* T
  3. #include "./SYSTEM/delay/delay.h"7 Y( h  E+ E0 w0 F) N( _1 D
  4. #include "./BSP/LED/led.h"
    & P' r' X% b+ u* \9 [" L
  5. #include "./BSP/BEEP/beep.h"
    $ ^/ y4 x$ x' p1 w+ d

  6. ; J! m! r& J# V# ^
  7. int main(void)! N9 i- W' [# M: a+ Q& o
  8. {3 ]2 F  S1 N& y5 N4 X
  9.     sys_cache_enable();                             /* 打开L1-Cache */
    4 d9 t  P) Y. m5 y! N4 ]
  10.     HAL_Init();                                       /* 初始化HAL库 */
    ( M/ n9 o5 f6 C1 x) R
  11.     sys_stm32_clock_init(240, 2, 2, 4);          /* 设置时钟, 480Mhz */
    # t& ?* Y$ j3 c0 i0 h$ \* @" h
  12.     delay_init(480);                                 /* 延时初始化 */
    3 v' j( f* R6 u1 h% A/ a1 M
  13.     led_init();                                       /* 初始化LED */
    " Y9 C& _( M% z3 X/ C
  14.     beep_init();                                      /* 初始化蜂鸣器 */+ l' B' k2 h( X, x# |$ I0 K& w

  15. 4 K0 M# h+ K4 R& T
  16.     while (1)
    4 Z; b5 S& S  ~, e4 Y5 F
  17.     {
    , J8 c+ i3 ^; a0 E; c
  18.         LED0(0);
    % I+ G6 P) R2 t) p2 I- ~: O
  19.         BEEP(0);
    : y' e6 m! [0 l& J
  20.         delay_ms(300);1 s* p( e: n) R" o
  21.         LED0(1);
    ' ~. C7 }' o9 _3 K* Y
  22.         BEEP(1);
    . k6 d! J) ?1 x" x- \  Z5 e
  23.         delay_ms(300);' C/ P- A1 j% t1 b6 d6 P  \
  24.     }
    ( B6 x* Y! \  N
  25. }
复制代码
" ?4 u: u6 Q) j2 v
首先是调用系统级别的初始化:sys_cache_enable函数使能I-Cache和D-Cache,然后初始化 HAL库、系统时钟和延时函数。接下来,调用led_init来初始化RGB灯,调用beep_init函数初始化蜂鸣器。最后在无限循环里面实现LED0和蜂鸣器间隔300ms交替闪烁和打开关闭一次。" M4 U. U" T- I% e( \- y/ I
, e) _% x; |3 {
14.4 下载验证
' ~" s6 X4 l" W/ d# r下载完之后,可以看到LED0亮的时候蜂鸣器不叫,而LED0熄灭的时候,蜂鸣器叫(因为他们的有效信号相反)。间隔为0.3秒左右,符合预期设计。6 u) G7 y2 C" Q3 T" k8 S+ ?
至此,本章的学习就结束了。通过本章,我们进一步学习IO作为输出的使用方法,同时巩固了前面知识的学习。希望大家在开发板上实际验证一下,从而加深印象。0 w/ Y$ ^: b. ]0 _# X( p8 q
————————————————& b2 r) N/ t2 a
版权声明:正点原子
; ?' M. x0 n9 `9 _) k8 ]
* U8 S0 ~* L' h0 A5 O$ Y" t4 E) k. L. l- w
赞 收藏 评论0 发布时间:2022-10-7 12:43

举报

0个回答

所属标签

相似技术帖

官网相关资源

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