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

STM32CubeMX教程-GPIO输入之外部中断

[复制链接]
STMCU-管管 发布时间:2020-10-14 15:06
STM32CubeMX教程-GPIO输入之外部中断

' p7 P% B8 Q. G2 n

/ g5 C) Q! g! g1 V' x6 ]3 h本篇主要讲述GPIO外部中断输入检测,实际物理输入方式是按键,但是实际上更适合外部设备信号的输入检测,物理按键输入因为有抖动,还需要硬件或者软件去抖才比较可靠。这个例子不考虑防抖的情况。
+ i6 t8 h0 A, s) G0 V软件版本:
) i& w$ h9 N2 c2 }STM32CubeMX V4.25.0  % y3 X" L! w0 t! G+ [
System Workbench V2.4

5 E! S& `9 B1 }' b$ y7 o- e硬件:OneNet 麒麟座V2.3/ b6 V. t) e1 W" k7 c7 i
    在STM32CubeMX中新建项目,选择正确的MCU型号# j, m& E+ b. w1 C* s
11.png     设置RCC和SYS,然后根据板子实际情况设置时钟(麒麟座外部晶振是12M,STM32F103x的最高主频是72M) 12.png 13.png     根据板子的具体连接设置4个GPIO_OUTPUT (连接到LED)和4个GPIO_EXIT*(外部中断模式,连接到物理按键)。8 g4 h# ~7 b9 Y) r2 u, j3 |
14.png
5 V( X: Q6 f0 ?6 k" o: S9 F    GPIO OUTPUT引脚设置
+ [8 c$ Y# u9 o 15.png
: y2 p" N9 N2 B    麒麟座按键有外部上拉,所以GPIO_EXIT*不需要配置内部上拉,检测下降沿(Falling Edge),GPIO_EXIT*设置如下% T# ]  z7 V5 ]' S7 C" ~
16.png 2 W0 U$ F9 F2 _: Y# w5 }; B
    LED名称标号我用了1/2/3/4,SW名称标号我用了2/3/4/5,实例中标号也未必相同,但是要做好一一对应关系。
) j/ r9 Q! V. G5 b    在NVIC(嵌套向量中断控制器)中,勾选EXIT Line2 interrupt 和 EXIT Line[15:12] interrupt 使能中断。右边两个选项设置抢占优先级和响应优先级。此处我们选择默认的,不修改。
8 {# L4 p- x3 }- [  P6 E: c) T. T 17.png
: k  a, i! _2 a& E& H$ n) e3 ^+ i6 m    同样修改Project - setting ,ToolChain/IDE选择 SW4STM32
! ~* s, f; i( }/ s 18.png
& I+ z; U( G: R0 e    勾选这里。
9 O; g6 y, ~5 ~9 P- O- g; @4 O& \$ F 19.png
, z+ T# i$ A' C/ _; ^0 ~( n    生成代码后点击Open Project在Eclipse中打开项目,然后在 在stm32f7xx_it.c中断服务函数文件中,我们可以找到EXTI2 和EXTI15_10中断的服务函数。& H; W2 [; }' `6 M3 s6 ]0 c
7 h; [9 \% E6 E4 d
! c  c/ B, d: T3 E# c4 @% n
  1. ; \/ [: z+ m% q: y' C$ b3 E% s
  2. /******************************************************************************/
    & L: l( s' K( K; A
  3. /* STM32F1xx Peripheral Interrupt Handlers                                    */8 @$ V4 ?& \- q
  4. /* Add here the Interrupt Handlers for the used peripherals.                  */
    : @5 u" Z$ G( C* I( r2 E2 w
  5. /* For the available peripheral interrupt handler names,                      */3 [, k0 p4 ^9 A
  6. /* please refer to the startup file (startup_stm32f1xx.s).                    */+ o% I/ M$ {9 B5 q
  7. /******************************************************************************/
    - I! Y& j6 W1 d- q. m7 z$ W3 |
  8. /**
    . J& ^& o8 J8 Z& T9 V3 Q. N
  9. * @brief This function handles EXTI line2 interrupt.8 A. b2 D3 {( c/ x" `: C1 d# F
  10. */
    5 q) g7 J8 q1 l; L+ r' Y. o% y
  11. void EXTI2_IRQHandler(void)- V8 o% W4 c0 o6 C0 D
  12. {
    ( r2 A, i+ N0 z# w( k' g
  13. /* USER CODE BEGIN EXTI2_IRQn 0 */1 }; ^. Y6 h1 g" N
  14. /* USER CODE END EXTI2_IRQn 0 *// I+ X; K$ _8 H' Z
  15. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);, {: y( l; P; E- w6 k; E
  16. /* USER CODE BEGIN EXTI2_IRQn 1 */
    * A7 V! b3 e8 R
  17. /* USER CODE END EXTI2_IRQn 1 */
    5 J7 r/ {: h( K& o, _$ t* r+ h
  18. }1 Z# Z) i7 o+ e4 N# S
  19. /**; t; X( c; }+ x0 Y9 i( q
  20. * @brief This function handles EXTI line[15:10] interrupts.
    5 c$ ?$ {0 }. e+ D& W0 X$ K
  21. */
    7 ^: |( K5 \( y( o, ^8 E9 L
  22. void EXTI15_10_IRQHandler(void)0 w1 L( s% \" \. E
  23. {/ A) {" A  I4 e
  24. /* USER CODE BEGIN EXTI15_10_IRQn 0 */, @- n6 T) w( l5 H1 K8 \" R" A
  25. /* USER CODE END EXTI15_10_IRQn 0 */
    % M/ w: M3 ]9 s! H
  26. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11);0 k5 D4 F" O* X$ L0 z
  27. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);$ _1 e3 q, W1 g
  28. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
    " {+ x, ^+ M7 t2 z5 O0 q/ U5 q
  29. /* USER CODE BEGIN EXTI15_10_IRQn 1 */
    ! v$ i7 G/ _3 i6 j3 Q
  30. /* USER CODE END EXTI15_10_IRQn 1 */
    + S0 `5 d" a5 Y  _5 S7 u2 D7 L
  31. }
复制代码

" d! z+ D; m) [% r

( a/ ^6 ?: B# x' n: h右键点击HAL_GPIO_EXTI_IRQHandler 选择"Open Declaration"会跳转到如下代码:1 d7 ?. _2 T. [. F9 C/ C

8 D2 w% u( F6 b8 I  t- |: E# u; J& E
) A) C2 l4 `. O, K: g+ c$ ]. V

  1. . e  m. k; d6 L: ^( B  _
  2. /**
    - k" |6 n& f! ?& @+ h4 ?  r
  3.   * @brief  This function handles EXTI interrupt request.
    $ W" Y' `3 F) J1 u
  4.   * @param  GPIO_Pin: Specifies the pins connected EXTI line
    / I3 c0 j# {3 q- I0 Q, m6 C, Q' f0 N
  5.   * @retval None% y* H. s' O2 g& l1 [
  6.   */) O6 g0 X8 h) {0 P; q
  7. void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
    ) \1 f( G8 S+ Q
  8. {  F! b* d8 Q7 r' a5 c
  9. /* EXTI line interrupt detected */4 `, ]0 h6 |- {
  10. if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
    & @1 S0 N, c8 ~. r
  11. {( x' j- x) A6 t2 r
  12. __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);. m6 Z3 Y# T! ]" i
  13. HAL_GPIO_EXTI_Callback(GPIO_Pin);
    * s( C, r9 S+ I# C& t3 c
  14. }
    8 b7 j5 t2 m5 n; m; l. W
  15. }+ \" O7 m2 o7 k7 f% P* i% C
  16. /**
      I& G& K/ y( E  B: j2 z4 ]  E
  17.   * @brief  EXTI line detection callbacks.& P6 u4 I7 p% w) h
  18.   * @param  GPIO_Pin: Specifies the pins connected EXTI line: R/ m7 e8 m3 E2 p
  19.   * @retval None
    1 D1 a& J. m9 }/ w
  20.   */' d8 `& a. ?7 V( k* F
  21. __weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
    9 m& y( T9 `7 l; [# e
  22. {- }, g0 {. ]% o5 Z: b% U
  23. /* Prevent unused argument(s) compilation warning */3 k, Z0 [: w, D
  24. UNUSED(GPIO_Pin);3 }( V" t. N# J, Y
  25. /* NOTE: This function Should not be modified, when the callback is needed,! r# a- l7 B: i
  26.            the HAL_GPIO_EXTI_Callback could be implemented in the user file
    # A" k, E% L( i1 n3 ^. q9 d
  27.    */
    8 A+ D5 Q; E4 ~4 |- A  C4 i
  28. }
复制代码

$ g, v' F4 l: D5 S2 x
, e: ^. m3 ]0 C+ R. J! G/ e
上述代码中可以看到GPIO外部中断处理函数首先清除中断标识位,然后调用中断回调函数HAL_GPIO_EXTI_Callback()。往下看这个回调函数定义的时候使用了__weak修饰符(关于__weak修饰符, 可以参看此博文),里面没有任何有作用的代码,我们需要重新定义这个函数。编辑gpio.c(或者main.c也可以),进行如下修改:
6 I1 y) s  l# @7 A4 o7 w& A2 I5 [1 }
5 ], v3 V4 N& l1 z- I" Z: B
  1. 1 k' Q* H6 ?* l. E
  2. /* USER CODE BEGIN 2 */1 I: K5 i# t$ u) [7 g% _
  3. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)7 k' l  h; q4 L4 o8 x
  4. {
    - C& V/ F1 A; N6 G# G+ ?
  5.   if(GPIO_Pin == SW2_Pin)
    1 a: s- c7 X; U! o9 q
  6.   {
    4 x! e1 ~" T: l) m+ M
  7.   HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
    1 ]2 t* R+ a. P" W# c8 j
  8.   }
    1 F/ ~7 n5 ~: N2 K- ?
  9.   if(GPIO_Pin == SW3_Pin)
    ' K" Z2 k8 [$ O) `5 @9 V) Q+ k
  10.   {
    9 v0 z3 M: }1 [) }) ]  p
  11.   HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin);. N5 s1 X% M0 y! C9 k# d0 p$ }
  12.   }
    1 e" {5 N& _5 Q" `' b) p
  13.   if(GPIO_Pin == SW4_Pin)
    . d7 a/ P, a% k: h0 D
  14.   {
    ' Q4 L% ~& k8 Y- \4 s
  15.   HAL_GPIO_TogglePin(LED3_GPIO_Port,LED3_Pin);+ }$ c! C* W1 p2 F- Y
  16.   }# j4 u7 ]. N, g, s. m# ^
  17.   if(GPIO_Pin == SW5_Pin): w# s: }/ l  d7 m
  18.   {- @$ t6 y+ R. T- s% C( ~8 `7 z
  19.   HAL_GPIO_TogglePin(LED4_GPIO_Port,LED4_Pin);( H4 y& i0 m& h5 Q& ^% F* ~
  20.   }
    $ G" K1 F5 V1 M0 o0 ^+ |8 X- \) O
  21. }# ?( `3 i* g% V- G9 @- M
  22. /* USER CODE END 2 */
复制代码

, ^8 O6 _, G" E2 Q0 t1 B& X

, b9 x# i' |4 q9 s  \# q) t然后右键点击项目,选择Properties, Run-Debug Settings, 点击右侧的New,在弹出对话框中选择Ac6 STM32 Debugging。& _2 y1 C0 ?7 v( R8 h
20.png " V/ C/ a- B% Z7 U& X. R8 V
然后任务栏上点击Run图,当然会报错的,原因请查看另一篇我的博客,所以需要右键点击  项目名Run.cfg ,给它改个名字,0 \4 `) M( i0 X; o  d7 E! F
21.png
; G( i0 s0 o8 W, q7 c - @  P3 e! }9 I% K6 f6 r
    然后右键点击项目树里面的项目名称,选择“Propeties”,然后在Run/Debug Settings-选择项目名-Edit-Main-C/C++Application那里点击“Search Project”,然后选择出现的默认的elf文件:; E4 B: g( u3 |6 W! G2 ?8 ?+ C
22.png
  X# L. l3 ^( c$ Y1 l: \2 n    然后在Debugger-User Defined-Browse 那里选择你自己改名的配置文件:4 o. a9 H  }4 y, m/ F
23.png
9 ^1 H: K9 b( @9 s    然后右键点击那个新的cfg文件,选择"Open With - Text Editor", 进行如下更改:
- x9 \5 d* }* q4 j! f

  1. ) D& `/ Z. i5 R, v- n- N. b
  2. source [find interface/stlink.cfg] : U, y9 J) Y: R
  3. //更改为 source [find interface/stlink-v2.cfg]# k: b/ R4 g1 _

  4. 8 B8 y# y! |6 h, a, f: d0 p. K  J/ c
  5. reset_config srst_only srst_nogate connect_assert_srst
    ; m. L; ]* |- q3 V) S; z
  6. //这一行改为 reset_config none
复制代码

2 K5 ^3 C. C  {1 U& E3 ~$ K. c
# h, j5 U9 u. @% \. }
Run一下,就可以了。然后再Run一下,就实现四个按键分别控制LED的开关切换了。但是这里没有防抖处理,你会发现有时候LED会闪一下,或者没反应,其实是很快地点亮然后熄灭一次或者若干次,只是由于速度太快电流很小导致你看不到。下一篇我们会通过使用SysTick中断来实现按键去抖扫描。在实际项目中,最好加上硬件防抖,因为抖动产生的反向电压可能会冲击GPIO导致损坏。
  W9 b7 X, _4 E( w3 |7 N' g* L: Y* O: D6 ?; D
/ C. G0 b/ c8 T+ W! o+ g. R  A: S8 _

* O- b" t. ^; h  _$ n- a

: \; v3 q/ [/ J; a) X- @; o+ p) L# \( H. J  ]

* X% a" Q% T6 H
, V# d: T& W9 `' f) Y$ @2 _
! z2 h+ f/ s+ Q) Q0 u$ X. L

% E/ l, n' W  `; i7 Z) \- I$ p
# j- R4 e; s. M8 T# |

' w* e. Y0 ]+ ]4 b+ ?# o+ |
收藏 1 评论0 发布时间:2020-10-14 15:06

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版