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

【STM32CubeMX】+外部中断

[复制链接]
神圣雅诗人 发布时间:2020-3-6 17:02
1新建工程
1.1New Project
  • 1 搜索芯片型号
  • 2选择芯片
  • 3创建工程
    6 g9 K. F. a" a
1.2设置RCC  
  • 1 点击RCC
  • 2高速时钟(HSE)选择外部晶振
  • 3 软件自动配置管脚
    % E2 t. I# e: i
1.3GPIO初始化
LED:4个GPIO_OUTPUT (输出模式)
按键:2个GPIO_EXITx(外部中断模式)
  • 1 点击对应管脚
  • 2 设置对应模式
    4 }: V* G: X8 I; l; Y; B6 `
GPIO的各种模式设置
  • GPIO output level   引脚电平设置   高/低
  • GPIO mode   GPIO模式     推挽输出/开漏输出
  • GPIO Pull-up/Pull-dowm   上拉下拉电阻      上拉电阻/下拉电阻/无上拉或下拉
  • Maxinum output speed   引脚速度设置   低速/中速/高速
  • User Label    用户标签   给引脚设置名称  如LED0
    : s( D/ q6 s( w% m) M7 [! E0 Z+ d- n
这里可以看出看和我们使用库函数的时候配置是一样的,但我们只需要动几下鼠标便可以完成操作,这正是STM32CubeMX的强大之处
GPIO_EXIT的6种模式
我们的按键选择下降沿触发
9 Y9 f* L: `: ?/ B/ n6 v# c6 P
1.4设置NVIC(嵌套向量中断控制器)
  • 1点击NVIC2 勾选EXIT Line
  • 2 interrupt 和 EXIT Line[15:12] interrupt 使能中断5 Y2 u# o4 g* u+ W: T
1.5时钟源设置
  • 1选择外部时钟HSE 8MHz
  • 2PLL锁相环倍频9倍
  • 3系统时钟来源选择为PLL
  • 4设置APB1分频器为 /21 K7 i% a- P+ V9 Z# n2 L: M
32的时钟树框图  如果不懂的话请看《【STM32】系统时钟RCC详解(超详细,超全面)》
1.6项目文件设置
  • 1 设置项目名称
  • 2 设置存储路径
  • 3 选择所用IDE
    9 M6 c, A9 N; k# ~+ [
1.7创建工程文件
然后点击GENERATE CODE  创建工程
随后我们可以在stm32f1xx_it.c中看到我们所配置的中断服务函数  并且可以看到gpio的初始化分到了gpio.c里面
、
我们看到他有一个HAL_GPIO_EXTI_IRQHandler();函数
Go To Definition 查看一下函数代码
和我们库函数配置差不多,就是清除中断标志位,之后进入中断回调函数中
在HAL库中,中断运行结束后不会立刻退出,而是会先进入相对应的中断回调函数,处理该函数中的代码之后,才会退出中断,所以在HAL库中我们一般将中断需要处理代码放在中断回调函数中,

$ Y% j4 K1 x) v/ c
$ M1 ?6 [+ d( _' u' ^- C配置下载工具
新建的工程所有配置都是默认的  我们需要自行选择下载模式,勾选上下载后复位运行
所有自己编写的代码请放在/* USER CODE BEGIN XXX */   /* USER CODE END XXX */之间
这样我们修改工程的时候你自己写的代码就不会被删除
HAL库 GPIO函数库讲解
在正常使用中,除了STM32CubeMX配置之外,我们有时候还需要自己配置一些东西,学习并理解HAL库,也是我们必须要学习的一个地方
首先打开stm32f4xx_hal_gpio.h  发现一共定义有8个函数
  • voidHAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);
  • voidHAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin);
  • GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
  • voidHAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
  • voidHAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
  • HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
  • voidHAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);
  • voidHAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);8 A/ C2 t4 U+ R, |0 _  F! K* h/ w: P

. b/ ^) {$ m( x9 r( xvoidHAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init);
( T! ~. ~, b/ B" g0 b) z( Y6 w
功能: GPIO初始化
实例:HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
voidHAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin);
* J- Y  f+ b4 Y; Z: Y7 R
功能:在函数初始化之后的引脚恢复成默认的状态,即各个寄存器复位时的值
实例:HAL_GPIO_Init(GPIOC, GPIO_PIN_4);
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
- [9 s" O& j: R$ b- `3 X
功能:读取引脚的电平状态、函数返回值为0或1
实例:HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4);
voidHAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
1 n$ w" j/ A4 j
功能:引脚写0或1
实例:HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4,0);
voidHAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);" h1 s) r% o6 c2 _' O5 J2 J8 C8 s
翻转引脚的电平状态   
实例:HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_4);    常用在LED上
HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);0 y8 o4 {3 V; k' v4 \% C7 o
功能:锁住引脚电平,比如说一个管脚的当前状态是1,当这个管脚电平变化时保持锁定时的值。
实例:HAL_GPIO_LockPin(GPIOC, GPIO_PIN_4);   
voidHAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin);
0 w# K9 S9 X! r9 j
功能:  外部中断服务函数,清除中断标志位
实例:HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);   
voidHAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
2 [+ F8 N( T! }5 B" L( a
功能: 中断回调函数,可以理解为中断函数具体要响应的动作。
实例:HAL_GPIO_EXTI_Callback(GPIO_PIN_4);   
' j! L4 J7 k; M9 V
GPIO_InitTypeDef结构体定义
  1. typedefstruct  k7 I9 H) t; t9 l  [7 T
  2. {
    4 a; i2 m- ^) H
  3. uint32_t Pin; /*!< 选择引脚*/3 K" A+ s, h$ r$ }( I1 a' t
  4. uint32_t Mode; /*!< 设置引脚模式*/+ s( d- p" @. A$ J+ a; C5 q: a  R9 Z
  5. uint32_t Pull; /*!< 引脚是否上拉或下拉*/
    . j8 m) W3 L- D* P
  6. uint32_t Speed; /*!< 设置引脚速度*/) i/ u6 f" W1 B8 Y( i/ ~6 m3 W
  7. } GPIO_InitTypeDef;
复制代码

7 P5 Y; F" n% }/ {
同时,不管是标准库还是HAL库,都是基于寄存器开发的,寄存器编程在哪个库都是适用的
GPIO的相关配置寄存器
STM32的每组GPIO口包括7个寄存器。也就是说,每个寄存器可以控制一组GPIO的16个GPIO口。这7个寄存器分别为:
GPIOx_CRL:端口配置低寄存器(32位)* m& i& t& J8 k5 ~; J, L3 s
GPIOx_CRH:端口配置高寄存器(32位)
+ ^( Y/ m; k, x9 CGPIOx_IDR:端口输入寄存器(32位)3 l1 h5 i) x2 ]3 e; Z8 T+ g
GPIOx_ODR:端口输出寄存器(32位)
& e$ z( S2 h/ G& I; q8 wGPIOx_BSRR:端口位设置/清除寄存器(32位)- y/ {/ c, ?  `. y$ P8 F
GPIOx_BRR:端口位清除寄存器(16位)4 c3 Q  P  B1 S& y. ~
GPIOx_LCKR:端口配置锁存寄存器(32位)
具体我们这里就不讲了,篇幅有限,可以到《STM32中文参考手册》中查看
8 K! B; r6 k! j# R0 {
关于GPIO的八种模式请参看 《STM32 GPIO八种模式及工作原理详解》
按键消抖:
  1. # e! [1 H( ?: ^' Z
  2. 6 M* h1 r  c9 V3 m5 b: |3 k
  3. /**' w, u& J% Z  _1 K* v0 H, ^& g
  4. * 函数功能: 按键外部中断回调函数5 R4 J/ i; O% S7 F0 i
  5. * 输入参数: GPIO_Pin:中断引脚& U- @1 A6 h$ g  T
  6. * 返 回 值: 无8 _" w! |9 j7 g, ~
  7. * 说 明: 无
    . N- ]6 U+ D. b1 X: Q- |
  8. */
    5 L6 o% N( H2 S' @* x' O( p& H
  9. voidHAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
    ; K6 l4 w  E' Z& Y# T" y
  10. {% g# a9 Q2 c( ]9 I9 T
  11. if(GPIO_Pin==KEY1_GPIO_PIN)+ D2 i1 }2 |" o- A+ h
  12. {
    + ~& \3 D# o* n7 v$ k
  13. HAL_Delay(20);/* 延时一小段时间,消除抖动 */+ [( Q8 u* p6 p
  14. if(HAL_GPIO_ReadPin(KEY1_GPIO,KEY1_GPIO_PIN)==KEY1_DOWN_LEVEL)1 T$ m% j9 j" u- C
  15. {: b9 U; u! w& _% M
  16. BEEP_TOGGLE;
    0 W8 [4 w" z% [, c3 Q
  17. LED1_ON;
    . e7 m8 W$ z- q, w
  18. LED2_ON;% h/ @% {1 d) _+ G  X& j1 o
  19. LED3_ON;
    $ Y4 l" F: w) t+ z
  20. }2 J; i( G1 @9 y, U
  21. __HAL_GPIO_EXTI_CLEAR_IT(KEY1_GPIO_PIN);
    # f% D0 o# m7 _5 v2 C8 q5 z% D7 \, C
  22. }
    7 |. m% [& v' M: V0 A8 @: O& x( m* M
  23. elseif(GPIO_Pin==KEY2_GPIO_PIN); K9 U5 G( U+ Z& ~; C. b
  24. {
    ) H$ g: ?) {2 }% v. A* |1 U/ Z
  25. HAL_Delay(20);/* 延时一小段时间,消除抖动 */! V5 ]- v4 A4 O* l8 V/ @
  26. if(HAL_GPIO_ReadPin(KEY2_GPIO,KEY2_GPIO_PIN)==KEY2_DOWN_LEVEL)
    % v3 |, [- ]  [$ [6 O! x3 ]
  27. {3 E$ p0 d# o$ `; o: U; Y7 `3 W
  28. BEEP_TOGGLE;
    0 z6 a0 t  Z* ]* H* ~
  29. LED1_OFF;0 n% B3 m% m4 {- ^+ K9 F; R
  30. LED2_OFF;# n  R+ f) O! g9 f
  31. LED3_OFF;" Q9 {3 M& p$ [' U
  32. }
    9 t# o  T$ a# ?8 t7 z$ A- o& V
  33. __HAL_GPIO_EXTI_CLEAR_IT(KEY2_GPIO_PIN);' }" R0 R6 x2 @3 b& i  F
  34. }4 v3 S8 I$ |1 I5 V( G
  35. }
复制代码

$ e3 _! t0 R# g' k& J- j4 K! v
1 `; g6 X4 G2 L1 I+ i- `1 L) x

评分

参与人数 1 ST金币 +50 收起 理由
STMCU + 50 赞一个!

查看全部评分

赞 1 收藏 2 评论3 发布时间:2020-3-6 17:02

举报

3个回答
飞跃-344154 回答时间:2020-3-10 21:22:25
8 J. D4 X& F8 _( \, ?0 t* l
写的不错,互支持一下。已点。
5 q* Q4 B( V2 R9 z1 U, E; {5 r( X
2 W/ I" D$ _, |) _" u- e【STM32CubeMX】工欲善其事必先利其器之最强四大技巧
2 ]+ P/ j9 p6 ehttps://www.stmcu.org.cn/module/forum/thread-623621-1-1.html
网络孤客 回答时间:2020-3-11 09:08:22
如何设置多个工程用同一个位置的库?
5 G+ f9 W; z+ W! w  r6 P' \每个工程都拷一堆库,太浪费空间了,想把库统一放在工程外同一个位置。
mangge2020-2538 回答时间:2020-3-16 23:27:44
这个软件功能强大,使用方便。但是这个可以生成一个初始化好了的代码后,剩下的用库做功能实现就抓瞎了。比如我生成了定时器PWN输出的初始化代码,用户代码怎么用库函数实现启动定时器PWM输出、怎么调节PWN的脉宽、怎么停止等等???:

所属标签

相似技术帖

官网相关资源

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