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

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

[复制链接]
STMCU-管管 发布时间:2020-10-14 15:06
STM32CubeMX教程-GPIO输入之外部中断
( p$ z  j, x5 N3 O2 `4 t, o
& M' X  V6 }! V) d) x
本篇主要讲述GPIO外部中断输入检测,实际物理输入方式是按键,但是实际上更适合外部设备信号的输入检测,物理按键输入因为有抖动,还需要硬件或者软件去抖才比较可靠。这个例子不考虑防抖的情况。1 @3 ?4 c2 E- s) o- a
软件版本:
3 [, Z8 u% A9 h  M) Q9 c4 {* E3 YSTM32CubeMX V4.25.0  , O3 ?$ N; Z" M/ L
System Workbench V2.4

2 P. E5 l) l- y( }2 e硬件:OneNet 麒麟座V2.31 @- P* s/ k6 Q* s/ h. g3 Q
    在STM32CubeMX中新建项目,选择正确的MCU型号( Z- B; U% l! `  K4 n1 M- ~
11.png     设置RCC和SYS,然后根据板子实际情况设置时钟(麒麟座外部晶振是12M,STM32F103x的最高主频是72M) 12.png 13.png     根据板子的具体连接设置4个GPIO_OUTPUT (连接到LED)和4个GPIO_EXIT*(外部中断模式,连接到物理按键)。- h* A% d9 i4 L, }5 e
14.png
2 _: H$ g/ K2 |9 }    GPIO OUTPUT引脚设置9 M6 [$ A2 Q2 d4 Z1 y' [
15.png $ c5 W8 Z9 s* w& {: {. U
    麒麟座按键有外部上拉,所以GPIO_EXIT*不需要配置内部上拉,检测下降沿(Falling Edge),GPIO_EXIT*设置如下$ F- A" Y$ x3 `7 R  Y3 u% J
16.png
  T( p5 x+ A+ T& G% ^7 R  v    LED名称标号我用了1/2/3/4,SW名称标号我用了2/3/4/5,实例中标号也未必相同,但是要做好一一对应关系。8 X! N/ a2 p4 r/ J* r9 u6 I2 m7 r5 a- l
    在NVIC(嵌套向量中断控制器)中,勾选EXIT Line2 interrupt 和 EXIT Line[15:12] interrupt 使能中断。右边两个选项设置抢占优先级和响应优先级。此处我们选择默认的,不修改。( r( m! {- W5 j5 f/ p8 f  d7 A6 M
17.png
8 ]5 r8 b4 I, P7 g6 u$ X" |* [$ m    同样修改Project - setting ,ToolChain/IDE选择 SW4STM32
  D0 s' o8 b% f( F! N& } 18.png ! y$ \) |0 k: e' d" |" U" I( d6 [
    勾选这里。
  v" m/ y, U" }7 X4 o 19.png + {# L0 o4 H5 n7 r2 c$ k2 D5 t- P
    生成代码后点击Open Project在Eclipse中打开项目,然后在 在stm32f7xx_it.c中断服务函数文件中,我们可以找到EXTI2 和EXTI15_10中断的服务函数。
) ^$ n$ C- `4 H* {' s, c, I* I5 f: }/ x) Z' M

2 L/ d9 y0 V* I* M- n, a
  1. + P: e5 j5 S6 r( X7 [
  2. /******************************************************************************/
    # U9 C3 A! V! ~7 z3 X& E
  3. /* STM32F1xx Peripheral Interrupt Handlers                                    */
    5 I  F$ m! `3 q2 O3 R! y
  4. /* Add here the Interrupt Handlers for the used peripherals.                  */- ^, f! r2 I* ]0 g
  5. /* For the available peripheral interrupt handler names,                      */! ~, e' E, j1 R* O" Z$ m; O
  6. /* please refer to the startup file (startup_stm32f1xx.s).                    */
    6 r6 U4 w  w/ b* d, @  G+ b
  7. /******************************************************************************/
    7 q% {( p/ Q8 o+ g) k/ [
  8. /**7 {- ?, i6 G. {, P, q
  9. * @brief This function handles EXTI line2 interrupt.' R% @' E+ _" k5 T& W9 m
  10. */
    ) O5 T. P( U2 ^1 {9 l/ D$ u' L
  11. void EXTI2_IRQHandler(void)) o* x/ }: ?6 j8 P
  12. {9 U9 b3 {8 g! [- V
  13. /* USER CODE BEGIN EXTI2_IRQn 0 */0 o2 p2 c$ d$ S* B% L  L
  14. /* USER CODE END EXTI2_IRQn 0 */; I: |+ ?0 r- S$ s
  15. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);# S+ N" r3 y/ @' _+ D3 d5 {
  16. /* USER CODE BEGIN EXTI2_IRQn 1 */
    8 |) I/ ]' q% d$ M
  17. /* USER CODE END EXTI2_IRQn 1 */; I* K  e3 @0 ]% S
  18. }' G- v' _3 V; j6 m& U4 Z* ]: E
  19. /**1 M7 `4 e1 u. Q
  20. * @brief This function handles EXTI line[15:10] interrupts." @: T5 @, J+ o7 u
  21. */
    " P9 H$ [( A2 B
  22. void EXTI15_10_IRQHandler(void)
    ) n+ S; ]4 N1 T3 t
  23. {( I: I$ ^3 c5 v8 h7 `
  24. /* USER CODE BEGIN EXTI15_10_IRQn 0 */
    $ e; [1 j' D. g9 T
  25. /* USER CODE END EXTI15_10_IRQn 0 */3 c2 A0 c( U8 E$ e1 V5 ~0 C4 n
  26. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11);
    . s/ Z  v, H5 k8 f/ {! X
  27. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);) b5 w+ y# y; M1 A
  28. HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
      V$ t6 {+ T% |
  29. /* USER CODE BEGIN EXTI15_10_IRQn 1 */
    3 Z* I& E3 j4 d& d* L; D
  30. /* USER CODE END EXTI15_10_IRQn 1 */
    6 P$ f! \% E# v- z3 J" d1 ?2 h
  31. }
复制代码

9 t5 o! l3 ?+ D7 x3 p, x

, ]1 R0 a5 s; i" k6 Z: c( M, q右键点击HAL_GPIO_EXTI_IRQHandler 选择"Open Declaration"会跳转到如下代码:
" }( t9 b8 W5 r- _/ u& _! W7 Y+ L1 H# m
! U. u4 [4 T0 J# a, X

/ `. E% p8 g$ M: R1 o! N
  1. , `# b8 e7 }/ R4 h7 O& u
  2. /**
    / ]4 u) i! I1 N9 g* n- ^6 r
  3.   * @brief  This function handles EXTI interrupt request.
    + [. C& R; x, g  X! J& d; v" [
  4.   * @param  GPIO_Pin: Specifies the pins connected EXTI line
    ' J# d5 R- A( R1 {. ~; P  @
  5.   * @retval None
    # v. M8 p5 ^; I6 ], |
  6.   */
      U) m# x' k: Z3 Z5 R; L8 Y
  7. void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)  ^0 `5 X, R: l' v) p. y
  8. {1 U. U' E2 u! L) J  l
  9. /* EXTI line interrupt detected */
    & h; u* N; }5 z* C; n% S+ z
  10. if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
    2 t9 x% `8 q2 }- J- _
  11. {# C5 U2 ]: c& ?; n7 J3 I! B9 C$ M. j
  12. __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);$ [& B. Z2 `$ N7 B. s
  13. HAL_GPIO_EXTI_Callback(GPIO_Pin);* g7 a3 ]+ \: N1 G# m; U  R- V9 j
  14. }
    ' d) R9 ~# l# o" e# F) X
  15. }1 ]! q! p0 y, W: q6 p9 {
  16. /**
    + E5 N0 _; K- p( q, ~3 _" ^
  17.   * @brief  EXTI line detection callbacks.' S; d' I( i1 M+ g( n
  18.   * @param  GPIO_Pin: Specifies the pins connected EXTI line
    : ]' \  T6 P+ V2 r! V& d: G
  19.   * @retval None/ m8 q4 f$ b5 u4 Y; w0 H
  20.   */8 [4 }) V. }+ k( j  A, V
  21. __weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)3 P3 A2 p& h% |+ u4 h; {9 H8 j
  22. {
    , S9 T, B$ R3 V2 m) Q9 P- `
  23. /* Prevent unused argument(s) compilation warning */3 v) A6 U' i( t, o/ Q
  24. UNUSED(GPIO_Pin);
    ' h7 a. N  |# c: n' v# b. I
  25. /* NOTE: This function Should not be modified, when the callback is needed,! {) {* O' @+ v' J( J+ p, D2 N$ G# b
  26.            the HAL_GPIO_EXTI_Callback could be implemented in the user file( t" S' z6 q7 M$ g
  27.    */: V7 W1 y* @' g# z
  28. }
复制代码
) V" l/ D) u4 w% ]# i2 y& t
0 f6 x7 t# l9 f( N
上述代码中可以看到GPIO外部中断处理函数首先清除中断标识位,然后调用中断回调函数HAL_GPIO_EXTI_Callback()。往下看这个回调函数定义的时候使用了__weak修饰符(关于__weak修饰符, 可以参看此博文),里面没有任何有作用的代码,我们需要重新定义这个函数。编辑gpio.c(或者main.c也可以),进行如下修改:! q1 K( ?/ p+ g3 e3 x& Z

1 |! j, n* ^$ ]

# Z6 M  b1 ?3 b  q
  1. ' C4 E) x4 e% a' C. B6 I/ n4 p+ t
  2. /* USER CODE BEGIN 2 */0 j: p& W  j$ ?& i
  3. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)  \% V/ v5 j, @9 I
  4. {
    * e: d% s/ l+ l$ k3 N- w8 @
  5.   if(GPIO_Pin == SW2_Pin)6 D; P- {; Z, y* c6 x$ s' k' f
  6.   {
    ' L# N( j( K/ p. o
  7.   HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
    6 }- A5 ~4 ~. K6 S* ~) K
  8.   }$ ~1 W7 R, O  i& F- Q
  9.   if(GPIO_Pin == SW3_Pin)
    " @- u5 }; P) e8 S" I6 @7 f
  10.   {
      j; E6 ?/ n6 S8 X
  11.   HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin);8 U5 _7 O1 M( a& T/ B! Q
  12.   }
    8 Y: ~2 e! {+ D" Z2 a# N
  13.   if(GPIO_Pin == SW4_Pin)6 r0 W6 V+ r  f6 t) `+ S
  14.   {5 f: n1 c1 C2 ^6 x+ e
  15.   HAL_GPIO_TogglePin(LED3_GPIO_Port,LED3_Pin);- x" y/ Y+ W, c3 o
  16.   }; _" f" g4 B8 A) C' T9 k! M
  17.   if(GPIO_Pin == SW5_Pin)" B6 [2 l  d' s' r6 N
  18.   {# n; ~; G' o. u" a; e; i
  19.   HAL_GPIO_TogglePin(LED4_GPIO_Port,LED4_Pin);  i) y5 d. i. \
  20.   }
    . i6 `+ z  g) V5 @
  21. }! R7 J, l, u% Y' e5 {9 G4 V0 Z; Z
  22. /* USER CODE END 2 */
复制代码
+ @$ y1 ?' z, p9 h" G: E4 V( B
/ h0 v: B6 _9 v
然后右键点击项目,选择Properties, Run-Debug Settings, 点击右侧的New,在弹出对话框中选择Ac6 STM32 Debugging。
6 _9 R9 w" Z1 d! A% T: ? 20.png
: E  K% D3 |$ {! V3 F$ L- O然后任务栏上点击Run图,当然会报错的,原因请查看另一篇我的博客,所以需要右键点击  项目名Run.cfg ,给它改个名字,
8 r9 a, \% G! L- C 21.png 8 f7 c6 J" L3 k( `

+ Y+ r0 I6 y4 K' J4 t    然后右键点击项目树里面的项目名称,选择“Propeties”,然后在Run/Debug Settings-选择项目名-Edit-Main-C/C++Application那里点击“Search Project”,然后选择出现的默认的elf文件:
: N# M0 D: W0 b6 W- t2 {$ p) f1 T1 I 22.png
3 V. a* A' H, N1 ]0 A; R" p    然后在Debugger-User Defined-Browse 那里选择你自己改名的配置文件:* f* K0 J/ E! Z: T: c3 O! j
23.png & W1 I/ t( `1 n- _  V+ k
    然后右键点击那个新的cfg文件,选择"Open With - Text Editor", 进行如下更改:
7 X, A# u, H6 ?% ^5 c5 K* F2 |
  1. ' F* h7 _2 \/ c: L2 l. H5 Q( S
  2. source [find interface/stlink.cfg] 1 K. D) |3 Q! V9 s
  3. //更改为 source [find interface/stlink-v2.cfg]) w8 u( K% R& b$ z
  4.   L% ^% h$ @2 @# s; p
  5. reset_config srst_only srst_nogate connect_assert_srst
    8 H* J4 a( N6 R" u, u& B
  6. //这一行改为 reset_config none
复制代码

4 h0 {/ J5 d* s  B) U3 T1 L

4 K/ c: i( C3 ]4 G; f/ K' n( bRun一下,就可以了。然后再Run一下,就实现四个按键分别控制LED的开关切换了。但是这里没有防抖处理,你会发现有时候LED会闪一下,或者没反应,其实是很快地点亮然后熄灭一次或者若干次,只是由于速度太快电流很小导致你看不到。下一篇我们会通过使用SysTick中断来实现按键去抖扫描。在实际项目中,最好加上硬件防抖,因为抖动产生的反向电压可能会冲击GPIO导致损坏。9 U  \7 [3 ^( h) j) c/ i* }

+ N, l, i& O% s: F, F
. l) H; r3 @! K6 Y$ l$ T
  d% W2 _- d' c1 ?
3 }/ U: |* c& @( F9 F0 p8 d
7 W/ y% M* l0 x; q' {/ i

6 a$ r) I8 E0 e% X; w4 K% h" B6 j; _6 s& M# z( p: u
; Q( T  \0 T' R" l/ r% {
) g! T% w& X( x" n) V) J1 g

8 S; o' i5 b+ V  L& L: Z  r) J% @+ N2 z
赞 收藏 1 评论0 发布时间:2020-10-14 15:06

举报

0个回答

所属标签

相似技术帖

官网相关资源

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