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

【经验分享】HAL库 STM32CubeMX教程三----外部中断(HAL库GPIO讲解)

[复制链接]
STMCU小助手 发布时间:2022-3-24 23:52
前言8 l1 ^- E& r  m/ v9 v# y0 R2 x
上一节我们讲解了STM32CubeMX的基本使用和工程的配置,那么这一节我们正式来学习CubeMX配置STM32的各个外设功能了
2 d3 d6 T. d/ v7 S9 k  C. f/ y  j) [3 A  m, j
今天我们会详细的带你学习STM32CubeMX配置外部中断,并且讲解HAL库的GPIO的各种函数,带你学习不一样的STM32) b/ K7 J0 K2 b6 {

( Z) d$ q5 v/ }那么话不多说,我们开始正式的讲解吧!4 I7 G, P' ~  c; h3 f

: N" B0 ~% k, f- D3 F+ s) @准备工作:; v* Q, ?! W7 o$ l. q* [
0 k$ N0 w& Y2 S
1、STM32开发板(我的是STM32F407ZE和STM32F103RC)
* L( m  }/ Z) {( {4 ~6 [: {
# v( z+ s9 W; s+ d6 P( e7 k2、STM32CubeMx软件、 IDE: Keil软件
& U) P8 l5 x1 J" P
2 c% W1 O: g  f2 n4 ~7 o3、STM32F1xx/STM32F4xxHAL库  4 J9 K! W- I. N5 T; m

0 I* X2 p& g3 a5 @: Y+ G4、按键管脚  PA11  PB4   
, B, F0 a" W) @$ f5 O3 r$ _
, ^4 @: M/ h1 k% f3 F5   LED管脚 PC4 PC5 PB0 PB1
" r/ |/ _! I  N3 i4 {
0 b& l4 j- F% r+ j" }1新建工程
( m' x, V4 F: z% ?+ i4 x1.1New Project
, u8 U& K" Z& q$ S$ v: V6 [) N6 ^
) Q4 J- U* R/ a" Q8 {5 y
20190809195826464.png
" k% Q8 `: D) O3 V3 E+ U* {; {3 z3 g0 D  x* K: o6 N; B
1 搜索芯片型号2 r" r- L1 r4 ^1 h3 b
2选择芯片
6 A+ k! K5 p% Q3创建工程
" i3 R: e$ U+ a, m* |% ~) [% J1.2设置RCC  $ v: F' }; r5 b# t7 l

- [3 i8 s0 @# w# h4 M1 f/ U+ c- ~ 20190809201413410.png , \8 u  U, j. M9 P( @! a1 b

2 k- ^& W* r" g1 点击RCC
0 @3 n) U6 w9 H9 C9 B2高速时钟(HSE)选择外部晶振; l7 b$ j! G& U  w6 @% l+ q: h
3 软件自动配置管脚
( J* H  ~0 B) a# J3 P/ [0 t+ x% T# h8 j2 Z$ o* V, {
1.3GPIO初始化
1 @5 P: [  g! a0 _% w6 L/ O' j. P8 g: c+ m$ v) ?! b- F
LED:4个GPIO_OUTPUT (输出模式)
$ A- L6 R, ?3 U1 I
4 Z/ c/ ^+ F( u7 J按键:2个GPIO_EXITx(外部中断模式)
2 K/ C% [% D+ p9 l4 I3 K) W- E. \" v" r! R, v* s9 ~5 q6 ~; u
20190809202500547.png
  e3 i# w% }! A1 T  r3 b  Z7 h) g- z- b% G! Y( D: b
1 点击对应管脚
# f/ _+ y+ g, y& F% ?2 设置对应模式
/ U0 A8 `5 A! i2 |. z$ Y" J3 b# @0 i0 A
GPIO的各种模式设置
, g: W( z  y. L6 a- v) M! x
3 r0 d  f5 F$ {* i2 D( V 20190809204340366.png
4 _4 B: a: P) |% d. Q& Q1 K
3 i6 q, Q5 L, e: qGPIO output level   引脚电平设置   高/低$ j2 W- B3 ?+ |$ T% q
GPIO mode   GPIO模式     推挽输出/开漏输出
8 d2 p; _4 [- t0 c* A, j% I. Z0 @+ IGPIO Pull-up/Pull-dowm   上拉下拉电阻      上拉电阻/下拉电阻/无上拉或下拉
% }) r5 M$ l2 QMaxinum output speed   引脚速度设置   低速/中速/高速  _7 P# t) ^- X8 t8 w; x7 u
User Label    用户标签   给引脚设置名称  如LED0
, c+ f9 C3 y: o; M5 d- e0 U/ j# z4 A/ \) f& z, Y- g5 ^) o
这里可以看出看和我们使用库函数的时候配置是一样的,但我们只需要动几下鼠标便可以完成操作,这正是STM32CubeMX的强大之处
8 o' R0 B  Y* Y/ `8 X- b1 w
4 g% \" F1 w* \( i; t3 s# B1 j  \) `GPIO_EXIT的6种模式

2 |) ]5 l0 U. w+ z
4 z, c3 w3 s9 e0 {7 s4 b 20190809204020820.png
5 A3 m7 p9 y4 I6 C% T) v4 H. `8 x
& W' c9 @' \# f- [7 L1 e& `9 X, z' p我们的按键选择下降沿触发  {: g( U0 H# J2 x( i3 f5 z

& d  e: H1 P: x1.4设置NVIC(嵌套向量中断控制器)
) j2 z) s9 W4 ]7 @( g. M" w  j' ~) J: u
20190809205728173.png 1 }3 m" A8 K: m' g3 v

: U3 ?9 i3 X5 ~6 v* {! c7 I  e4 f1点击NVIC2 勾选EXIT Line
) w* n, s( k% S: t8 I2 interrupt 和 EXIT Line[15:12] interrupt 使能中断, q( O6 M/ E+ R  q5 B3 r) b6 f
# m6 p$ s8 Y  A6 H/ V
1.5时钟源设置+ J' q$ ]4 r; I1 u" T" {
* ?6 A8 A. {* y$ B1 L3 w$ F# Y
20190809211230663.png
6 y! d9 A4 a3 E" U
, X* I) P9 x6 K1选择外部时钟HSE 8MHz   
: A- F2 R& F6 M. T6 t; H- _# O# Y2PLL锁相环倍频9倍0 y- A7 R" |3 s/ j) n5 M  u9 |( t
3系统时钟来源选择为PLL
* P8 P( m. }3 Z4设置APB1分频器为 /2
2 X! U. J5 f* O3 w% o6 b: |+ [: g32的时钟树框图  如果不懂的话请看《【STM32】系统时钟RCC详解(超详细,超全面)》; g) a- [% d0 W* l# h
5 e8 l0 u: d9 L0 p: C5 J
1.6项目文件设置; y7 `1 m( r1 B, k3 M

0 `8 Z2 r1 ?4 Q( F 20190809210713570.png
/ z1 ]: ?" |* `# Z, b, g2 `3 r6 T% r& u/ e. W+ M# F0 r% ?; Y
1 设置项目名称6 w* K1 |9 X/ j5 z" E$ c
2 设置存储路径" m+ P/ e" Q9 m% p6 q8 e% i) c- A  Y
3 选择所用IDE
- Q6 Q: {' G: [8 p
9 c# q- ~" w  X0 y 2019080921100765.png
$ C0 a& t, u& K& M, a7 e  Z9 N% U/ ]3 @5 c
1.7创建工程文件
' ?9 s& m  G$ I1 c7 J6 c! V$ w9 i& X# ]4 Z# W
然后点击GENERATE CODE  创建工程
  l# O# H5 P; P/ g; i6 N
5 L  s/ S4 ?0 z 20190809211414833.png
/ h* L* b) m" F2 N) K1 W5 n# `, Q0 T# F/ ~; I% z5 M
随后我们可以在stm32f1xx_it.c中看到我们所配置的中断服务函数  并且可以看到gpio的初始化分到了gpio.c里面* N9 b+ @$ a. W( |: q
" c. f+ R1 Z8 R$ r. @
20190809212553423.png
- k+ [' k0 F- F2 S% v2 Q
. f! s* b3 A2 E: y& Z3 r6 c% A1 i我们看到他有一个HAL_GPIO_EXTI_IRQHandler();函数
) O/ b. @2 \) L0 G
" i* c! M1 t3 S1 U% m5 BGo To Definition 查看一下函数代码
2 |0 z9 F: r* H  @3 m
  A; C9 {7 B( C9 @3 v& [/ U8 D& w 20190810093650879.png ' N) E& ]% z) v' G" i* w
. N  j5 Q3 `, d/ ~0 t
和我们库函数配置差不多,就是清除中断标志位,之后进入中断回调函数中8 I" @% Z# j, y* Y7 G2 J  o; u7 _; o
9 o! s8 z* L. _8 p
在HAL库中,中断运行结束后不会立刻退出,而是会先进入相对应的中断回调函数,处理该函数中的代码之后,才会退出中断,所以在HAL库中我们一般将中断需要处理代码放在中断回调函数中,% E( t4 @/ |- f, o" m7 H! }5 _
+ k' w$ M4 R, M
配置下载工具
! r- t0 F) p& E- ?: `新建的工程所有配置都是默认的  我们需要自行选择下载模式,勾选上下载后复位运行
. ]3 |$ R! c' c. S1 _. E
$ P, V' Y, E1 |. M4 D+ g 20190809172359875.png
' x$ s8 Q; ]5 A/ {; X
8 l  p+ M+ r/ {所有自己编写的代码请放在/* USER CODE BEGIN XXX */   /* USER CODE END XXX */之间 ! `) K8 X" A- v& x

) _7 l+ |2 Z- |9 \, [: z$ B 这样我们修改工程的时候你自己写的代码就不会被删除' z1 Q5 a5 s1 f+ t% z, v% i

' j& _* w. N+ g 20190809175342848.png
# v9 ~) V7 q2 i$ m( o# a: c. ?
4 \- Q4 I( H4 ?% \( m& o2 `5 Q1 aHAL库 GPIO函数库讲解; U4 y1 E' Y% e. A4 m0 Y, p
在正常使用中,除了STM32CubeMX配置之外,我们有时候还需要自己配置一些东西,学习并理解HAL库,也是我们必须要学习的一个地方# P* z, f+ [, D. W1 J* m2 g
3 S- D# J0 j8 Q
首先打开stm32f4xx_hal_gpio.h  发现一共定义有8个函数' z9 Y# |) Q2 {* t/ n! }8 }3 f& p/ d

1 j% j1 O+ W5 N- o
  1. void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);
    , J/ J) z, Z' H
  2. void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin);
    9 c* Q( D0 M8 t( A
  3. GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);+ R/ t' r6 b# `& c
  4. void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
    2 q: s. d9 ^; r- }9 n# K4 }
  5. void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
    ' {; A% q5 A- V/ x1 H
  6. HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
    7 t7 |0 V, E: z) d
  7. void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);
    ! L( S% P& d  u/ u5 w3 `3 v
  8. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
复制代码
  1. void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);
复制代码
* R/ J& j9 s+ M- W- ]
6 r- ?6 K. f/ B0 T& i, Q# k4 ~
功能: GPIO初始化
  ^+ m' k" e. b, c; [& t$ }
; G. p9 E; m" W! J/ p* f: _实例:HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  1. void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin);
复制代码
& z, U2 H( j7 l$ G
功能:在函数初始化之后的引脚恢复成默认的状态,即各个寄存器复位时的值
6 f4 ]( ~. H1 C8 U/ G. I8 J9 I% y2 R# l: Z( G
实例:HAL_GPIO_Init(GPIOC, GPIO_PIN_4);
! `; c6 z& X0 G  I  k
. H& U$ w# q8 S
  1. GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
复制代码
% K3 h, O% h6 ]
功能:读取引脚的电平状态、函数返回值为0或1
4 j5 Y& k% `5 g" C7 w$ m. S6 e2 `1 D8 h0 r
实例:HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4);( }5 Z: p; r6 Q5 N8 Q, N" V" X; q/ `5 l

9 F) t. r; ^. s4 X0 b8 `, F# y
  1. void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
复制代码
3 U2 Q+ G& P7 l
功能:引脚写0或1; u+ d4 @! H  f# T+ P

5 K$ b; d2 R' v" _6 {/ K实例:HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4,0);
* u: c+ S1 T) P) Z
3 \. b% ~9 C8 p7 r$ S$ h% E6 l
  1. void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
复制代码
0 S" h8 u0 y" C4 G9 u
翻转引脚的电平状态   
4 z) t0 ?7 m9 L  G, q9 U! b" d$ J7 T) f3 \" k
实例:HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_4);    常用在LED上/ M8 q9 d6 f+ T4 Z
5 h1 p" G+ V4 y1 F8 Y( A9 E9 z4 Q4 E
  1. HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
复制代码
) g# C" Z: j  d! y1 A8 ?( p& x7 }
功能:锁住引脚电平,比如说一个管脚的当前状态是1,当这个管脚电平变化时保持锁定时的值。0 s' }9 U: Y# Z8 Z( g- o

' B9 ?7 v, E3 V( r2 J实例:HAL_GPIO_LockPin(GPIOC, GPIO_PIN_4);    8 q+ p, O- D6 b
9 P3 Q$ q: J. c* y& X0 D* M
  1. void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);
复制代码
0 ?0 V2 {. u6 ^
功能:  外部中断服务函数,清除中断标志位8 c7 F, I$ B& R3 s* u
% c% E5 K5 u) u& h
实例:HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);      b  }, g& V2 C1 H' T8 O! e0 y

/ }3 {" \4 K4 a! c3 f
  1. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
复制代码

8 e' E* Q& D, X4 j. x" c0 V8 r功能:  中断回调函数,可以理解为中断函数具体要响应的动作。
' |7 s/ _$ `% _. ?' i' v) H  C5 ?; J
! j# B+ M0 w* ?" `5 j实例:HAL_GPIO_EXTI_Callback(GPIO_PIN_4);   
& W+ @, M  E" A0 I/ O2 h0 H. m
2 s( k/ j* w0 v7 o/ H( H* k
' s. [/ r/ n, ZGPIO_InitTypeDef结构体定义( \. v( G. |7 R

% k* d8 c1 T3 q4 S7 c
  1. typedef struct( Y$ Y6 e8 I" F8 I
  2. {
    . K6 K. v" I7 F% j1 A
  3.   uint32_t Pin;       /*!<   选择引脚
    " O" P% b( A( H/ i$ C
  4.                            */
    ; ?( I! T) P* B- Y' ]2 W( C

  5. / K5 b3 c6 k7 K& o0 A( i
  6.   uint32_t Mode;      /*!< 设置引脚模式
    8 k2 I  i3 ^) m( r0 r
  7.                             */
      N* r6 S3 F3 u5 U+ @

  8. 4 O' k. u: [" x" ]- ?$ P
  9.   uint32_t Pull;      /*!< 引脚是否上拉或下拉
    - A  y/ x( y+ R* H  `, A3 [1 L
  10.                            */& J# P0 W0 d) ?8 U! f
  11. + t+ L3 _( |) ^0 T; z6 y& _7 \
  12.   uint32_t Speed;     /*!< 设置引脚速度$ k$ G4 B5 [6 J/ E
  13.                             */
    ( `6 v/ ?# [7 E8 x0 Q
  14. } GPIO_InitTypeDef;
复制代码

* w+ w  N& x0 C  q# s同时,不管是标准库还是HAL库,都是基于寄存器开发的,寄存器编程在哪个库都是适用的% E# U8 t8 ]# z% A
- l1 y; ]2 T& G( l7 D
GPIO的相关配置寄存器+ D9 q# ~, }+ R
STM32的每组GPIO口包括7个寄存器。也就是说,每个寄存器可以控制一组GPIO的16个GPIO口。这7个寄存器分别为:$ M& V& W2 z% C- w

4 |9 Y1 W, U9 z! ]+ ]GPIOx_CRL:端口配置低寄存器(32位)
+ X! z3 x0 J6 K) a; ?GPIOx_CRH:端口配置高寄存器(32位)
( u% B( \  h0 D0 LGPIOx_IDR:端口输入寄存器(32位)
$ U, P9 x2 D9 A7 b: ~GPIOx_ODR:端口输出寄存器(32位)+ D; a6 D$ `/ {2 q
GPIOx_BSRR:端口位设置/清除寄存器(32位); r8 g+ O: s7 R; Z% n& ~
GPIOx_BRR:端口位清除寄存器(16位)
! u% Q5 {. H) o! H; m5 k6 q5 v8 O9 @GPIOx_LCKR:端口配置锁存寄存器(32位)
# s! t1 T+ g6 s
  C1 S; \6 V/ v7 q0 E具体我们这里就不讲了,篇幅有限,可以到《STM32中文参考手册》中查看% s( ~( d. [4 g- H, Q+ o
& X7 N3 N7 l+ c3 _
关于GPIO的八种模式请参看 《STM32 GPIO八种模式及工作原理详解》
# i# w( p, o5 k7 R7 L% j5 S& C$ h0 K0 I: V; Q4 Y/ A5 V/ l
按键消抖:8 N9 C% n' ~0 h5 i# Y
* d1 l. n6 U: N; V$ H8 G- u
  1. /**
    1 l! Q* @, w$ l* P
  2.   * 函数功能: 按键外部中断回调函数9 Z/ ^, {6 B8 c# v3 `# ?
  3.   * 输入参数: GPIO_Pin:中断引脚9 L2 }$ ^2 H5 d, r
  4.   * 返 回 值: 无9 W8 ]& T' [0 w' q% p% d  M
  5.   * 说    明: 无1 x6 w% `% t: w
  6.   */4 P* d% h" P4 E# a+ j; A
  7. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)4 E* S  j# T1 Y
  8. {
    2 Z( H% o. @# U
  9.   if(GPIO_Pin==KEY1_GPIO_PIN)& `( Q' \/ l* K/ a
  10.   {
    # @# L( C& N/ S4 Y( K+ l. t
  11.     HAL_Delay(20);/* 延时一小段时间,消除抖动 */
    # x" E# {- _' ?& p; c, @. w
  12.     if(HAL_GPIO_ReadPin(KEY1_GPIO,KEY1_GPIO_PIN)==KEY1_DOWN_LEVEL)
    ! m" z8 h4 z( F0 y/ R0 D1 X2 r" ^" {
  13.     {' e5 R$ x9 Y% o' t" K- f
  14.       BEEP_TOGGLE;
    4 ~; R; j+ r: n
  15.       LED1_ON;
    + h( g' }2 i5 M1 j/ \8 |
  16.       LED2_ON;
    ' h9 T$ L8 z8 {0 Q
  17.       LED3_ON;7 P" M. ?; D: R  a0 }
  18.     }
    * l, K, \+ \# [  r! I4 K7 i9 n
  19.     __HAL_GPIO_EXTI_CLEAR_IT(KEY1_GPIO_PIN);
    ; [) k% C% m8 r4 e9 M9 [. Y
  20.   }" T0 B* G5 o$ p
  21.   else if(GPIO_Pin==KEY2_GPIO_PIN); b! T" C! Y' C" i2 ^4 a) C1 ]) H
  22.   {
    ( ?+ h/ w% w! J3 S, c  @
  23.     HAL_Delay(20);/* 延时一小段时间,消除抖动 */
    / L5 J$ F9 G1 C& V3 C9 z* E
  24.     if(HAL_GPIO_ReadPin(KEY2_GPIO,KEY2_GPIO_PIN)==KEY2_DOWN_LEVEL)
    , w0 `2 M% R$ \/ x! [
  25.     {4 V4 ?" Q8 [9 i  m- ~* u$ S8 ~/ a- x
  26.       BEEP_TOGGLE;0 V7 `9 v: Q9 V% P
  27.       LED1_OFF;+ h9 E7 H+ {% t, S  d/ R: N
  28.       LED2_OFF;$ y5 S6 q5 ~" g9 @) @; v
  29.       LED3_OFF;8 P1 E# M" Q' W6 d
  30.     }( G9 n- h) [: ~3 Y# {8 a
  31.     __HAL_GPIO_EXTI_CLEAR_IT(KEY2_GPIO_PIN);
    * d7 O, V& I: j( L2 C; C
  32.   }& |# x+ x, }8 \! N, T
  33. }
复制代码

8 p3 d; o5 q# k& l5 A; x  ~- M) k; x
收藏 评论0 发布时间:2022-3-24 23:52

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版