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

【经验分享】基于HAL库实现按键(外部中断)翻转一个LED

[复制链接]
STMCU小助手 发布时间:2022-3-17 17:21

STM32CubeMX是官方推荐的配置软件,而HAL库也是取代之前的库函数的通用库,所以STM32CubeMX+HAL库是当前主流的工程创建方式,HAL库的可移植性也高于被取代的库函数。

之前在[程序员小哈]的公众号中写过两篇基于STM32CubeMX软件的文章,今天对其进行了转载。

今天我们利用STM32CubeMX实现按键(外部中断)翻转一个LED,涉及到的新知识点:外部中断。

% x. z1 l) u. I; j3 I

软硬件环境
  • Keil 5.14
  • STM32F103RET6核心板【202006每月活动】
  • STM32CubeMX 5.3
  • 按键(PA12)
  • LED(PA11)
    - L  L' e6 l& [2 v
  L7 D6 c, _7 V

  g" L) @: [- c7 T+ t; RSTM32CubeMX创建工程
  • 打开STM32CubeMX软件,从如下箭头所示两个位置可以新建工程。9 ?9 |7 w/ @, r9 t  r: r. W, a  F

' l3 d0 r% _: h) Y# ?4 }* X N(97AYITZ[Z%)Q_QT2%[}G4.png ! Q% r+ H5 r8 A* d: v
  • 选择芯片STM32F103RET6,可以在下图左侧位置进行检索,缩小待筛选范围。1 x" V6 C/ i( g$ k% {8 F; \
F7BVLUX14[)E3~`S6O)FW0Q.png
. t8 {* @- `: G5 j, T4 n/ {' X
  • 查看核心板的原理图,知道LED对应GPIO的PA11,按键对应的GPIO为PA12。. P: P3 m8 j; V3 J9 j

    * x2 X* G7 ?9 W% P9 `: S3 H
[64Y2R}_`~%M(G4G)~S[4Y4.png
. t+ x% m# Y& v; E4 e5 K5 v/ @( m
  • 配置PA12为外部中断模式- l  |( S/ Z/ g+ n8 x  d" z
    $ {, c5 Q, @* J9 N
_XJQ4[(FLOP%R7JKPF}RK{8.png
7 V4 s2 _, ?# I+ B  R9 X6 i2 Z2 i
  • 配置PA11为输出模式% s- |+ w' e- I% g$ S

    9 C; Q. `/ j! f8 _: P) C4 z' E
LT{@13`SWMR3S%%UMZ`@RO0.png : x1 O  ~3 G; u6 T9 V
  • GPIO配置
    & X( ^$ ?4 `6 c9 V, j6 _; _
      \7 }- m6 s# S. u5 z' E

注意:因为下面按键中断的回调函数中我们加了延时防抖功能,所以此处必须是下降沿触发,至于为什么?大家可以想想哈,大家可以在留言中交流一下。

KL$YQBI8VOOBZRL7`R7XW3H.png
5 H8 h# f. u3 @! Y
  • 使能外部中断,注意中断分组
    % M/ j5 y7 V* G6 Y, w4 K

    ( U. F5 T  L4 D
GCX]M{Z[642N_O)4I_P@{N2.png
! R( y  Y9 [% a! Q" B0 ?% L, P7 ?
  • 配置RCC
    , n& x/ j, L4 {/ T9 }# R

    " ]( D( g: G6 f1 P: g' R
[C0V`A6RHNWH_(GB`6R~T4N.png # H+ f' w/ b6 y$ u
  • SYS要如下设置,否则下载一次程序以后将无法再次下载!!!+ G* p1 M. w% _7 H' |

    0 Z+ U- L9 k4 B* M  B/ I
B{UK{YHPT7PZCB58@JW]016.png 3 K* n3 d4 k; B) P$ m7 F- [
  • 配置串口1为异步串口
    4 J; G! f) i/ ?" A0 t& o
    & Y8 H5 r( r; E' t' N

因为PA12占用了串口1的USART1_RTS引脚,所以串口1配置成禁用硬件流控的异步串口即可。

FFSYMP~LUA7YZQN_H%]TI5M.png
# o+ @7 S% G" j& k- N2 b- o* q
  • 时钟树配置/ ^  n0 D2 g, W+ f! `4 f

    : W: c2 B. ^' c: J
OCLF}RJ1L19RIMF~ZBSC8BC.png
" s9 n' B, @' w" N
  • 工程配置,工程名称:STM32EXTIDemo。
    0 j( ~4 ^0 l* r  y
    # L( R8 p9 m( x# T$ ]9 p; z
(O939L8ZO8M_5N%5]~GK{.png
: O+ F8 d3 k5 y3 p0 _; Q  C- J+ l
  • 生成代码
    4 Q# b0 ~# i! E
    % e0 l: i! e( b6 f: Q
8HWG8W_6$B}L367CN7R${7K.png " f" a( q4 d, l9 F
8 V4 e, N- T. A& I2 x9 ^2 R

; n0 t! I' H' ~$ F- `2 W  nusart.c文件中,添加串口printf输出代码2 Y5 {7 Y+ z4 s5 S3 ]
$ J! s4 ~% t' C2 U6 x' F
)C$X%AXFZ0ZC63$YJ5XCM[P.png
" h' ]: Z3 O  l: E) l& w9 \
  1. #include "stdio.h"
    + h1 ?; `; a' w1 E' P6 N
  2. 7 o7 P2 K6 G7 v# E" G
  3. #ifdef __GNUC__
    & X2 r; G* L. e* ?
  4. <i>/* With GCC, small printf (option LD Linker->Libraries->Small printf
    0 e+ U0 j8 j, |2 B
  5.    set to 'Yes') calls __io_putchar() */</i>- E5 S/ ~5 k" J2 [) k- G8 O/ [
  6. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)7 k  i) T/ l* w) e- A4 _6 `
  7. #else$ C3 ]+ J$ ~7 J# f% m7 V
  8. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)0 T. H9 P* I! b* ^) W' l- `  }
  9. #endif /* __GNUC__ */5 D6 x  G0 w9 C; Q# O0 |3 R

  10. : B& K, z; f* \) j' i4 ~" G8 d; R! g& m

  11. $ D4 u: Q2 ^% b4 T9 e. b
  12. PUTCHAR_PROTOTYPE; S' a3 x0 Z. i: A6 h
  13. {& g2 u  ^5 I+ S1 H: N
  14.     HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
    * j0 i' p% @8 J; `5 Q( d" |
  15.     return ch;$ X& S9 Z. D( u: N+ v
  16. }
复制代码

: f) N& X  X% p9 q  R 6J8IZ}R2J(GD{IUKZE05N.png
( l9 m4 e( h5 Q, _8 c3 p, A
  • 添加按键中断回调函数1 m4 B+ D) v1 d
      m- P; @3 q$ k2 C0 g$ Y9 Q
5WVHQ2~27C[@K{2A3$Y8ALP.png # {0 P, D* w1 P4 u6 ?
  1. <i>/* USER CODE BEGIN 4 */</i>
    6 v- M9 [9 L) D- L& _/ b
  2. ( O- y$ |' Z7 A. C# Y
  3. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)  ' Y% b2 \7 B- C% p; |7 A) w1 G  \
  4. {
    ' T  D1 b- E7 U- b4 R% L% S
  5.     switch(GPIO_Pin)( [8 O1 n+ f9 J3 V8 B! }
  6.     {
    0 _1 D6 P# W, E. [
  7.         case KEY0_Pin:   
    1 W9 K. i: ]7 U9 ~" [* M
  8.    
    ! _: w0 k5 M7 |8 @' }6 G
  9.    HAL_Delay(10);
    ; `6 ^  F4 n+ P7 {
  10.   + t' u% Y/ S8 i+ b
  11.    if( HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin)==0) <i>//延时10ms之后再判断是否有按键被按下,防抖</i>
    % p1 H5 C& |; Y/ i+ \
  12.    {
    1 q. f$ T6 D: ~, `+ @) z
  13.     printf("KEY0 Press ... \r\n");" ]5 F1 f- O. t' M( {; l' H
  14.   
    " K3 d$ J& O: p4 e
  15.     HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin);# E3 h, z# G6 y* a% N& G) ?
  16.    }5 f  S  L2 n' R$ m& y3 ?) c
  17.    break;  
    0 j  f! M6 k2 T

  18. ' ^5 {8 B7 D% z# k) a% e
  19.         default:break;
    , i5 c* N$ l4 }
  20.     }  C/ O8 h8 k6 R! e( G
  21. }
复制代码
" W0 b' q1 B: Y( }5 }, X

其中:

HAL_GPIO_TogglePin() 函数用于实现翻转 IO 口的电平。

实现同样功能,还可以使用下面代码分别控制LED的亮灭:HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_RESET)  // 输出低电平--亮 HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_SET)    // 输出高电平--灭. n' J. |; G! I- B8 C3 @

我们为什么添加了上面的函数,然后就能与中断函数绑定到一起呢?

因为这里涉及到一个“弱函数”的知识。

在 HAL库中,很多回调函数前面使用__weak 修饰符。weak 顾名思义是“弱”的意思,所以如果函数名称前面加上__weak 修饰符,我们一般称这个函数为“弱函数”。加上了__weak 修饰符的函数,用户可以在用户文件中重新定义一个同名函数,最终编译器编译的时候,会选择用户定义的函数,如果用户没有重新定义这个函数,那么编译器就会执行__weak 声明的函数,并且编译器不会报错。

我们搜索HAL_GPIO_EXTI_Callback()这个函数,发现的确有__weak修饰的同名函数。

7[%{S(`73}PN7X)I65XTME5.png / y% Y  g: U( `6 `

这个函数在stm32f1xx_hal_gpio.c文件中的HAL_GPIO_EXTI_IRQHandler()函数中被调用,该函数对中断标志位进行了清除。

1POVD)JB0C$XG04PIU_(4E5.png
. R! [0 G# d' n9 ?- v6 l

而上面的函数正好在外部中断函数EXTI15_10_IRQHandler()中被调用。

OH7CGF~LA$_6$U9MP@O2`CK.png ( O- ^8 T4 d9 k  J. v; a# ?

由上可知,当GPIO发生外部中断时,我们只要在回调函数HAL_GPIO_EXTI_Callback()中,添加逻辑代码即可。

  • 配置JLINK下载工具8 }: D) ^' f2 \+ b( Q$ B

    ; b" z' B: {8 I# @* H
TS(K$~QEY3_DEADO2U$W2MG.png
+ L, |3 |" F, L% }) b
  • 下载程序后,复位核心板,按下按键,串口助手窗口可以正常打印预设信息,LED亮灭来回切换,证明满足预期使用外部中断反转一个LED。
    , g5 J8 l1 V# L2 D8 y% Q9 K- Z% a7 k8 @

    8 d$ E. D2 V: G# D. T5 b( Y0 n
%JOK_]~`TJJ}]PKHE_[Y7.png $ {7 ^: l$ n- H# C
. g: W# l& B5 G$ r% p9 A. ^

+ q6 z6 n* }. g- g: l$ ]/ x
赞 收藏 评论0 发布时间:2022-3-17 17:21

举报

0个回答

所属标签

相似技术帖

官网相关资源

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