STM32
直播中

jackhui

12年用户 1139经验值
私信 关注
[问答]

STM32的外部中断EXTI该怎样去操作呢

STM32的外部中断EXti该怎样去操作呢?
怎么用jlink去调试stm32呢?有哪些需要注意的事项?

回帖(1)

王兰英

2021-11-18 11:10:29
  STM32的外部中断
  本人最近在学习stm32(基于cubemx),写下这篇博客希望自己能养成做笔记的习惯,同时也是锻炼自己写博客的能力,希望大家不吝赐教,大佬们指出我的问题,hhhhh。本篇博客最后写到了怎么用jlink调试stm32以及其中的坑,希望能帮到需要的朋友。大家一起冲冲冲,我们开始吧!
  外部中断EXTI是STM32微处理器实时处理外部事件的一种机制,由于中断请求主要来自GPIO端口的引脚,所以称为外部中断。
  STM32F013微处理器有19个能产生事件/中断请求的边沿检测器,每个输入线可以独立地配置成输入类型(脉冲或挂起)和对应的触发事件(上升沿、下降沿或双边沿触发),也可以独立地屏蔽。
  EXTI0~EXTI15:GPIO端口引脚。
  EXTI16:PVD输出,可编程电压监测。
  EXTI17:RTC闹钟。
  EXTI18:USB唤醒。
  EXIT0的连接引脚是: PA0~PG0,即每个端口组的0号引脚
  NVIC
  NVIC全称Nested vectored interrupt controller,即嵌套向量中断控制器,用来决定中断的优先级。
  NVIC在 ARM Conrtex-M 内核中,用一个 8 位的寄存器来配置,总共可以配置28=25628=256 2^8=25628=256级中断,但是 ST 公司在生产 STM32 的时候,发现一个小小的单片机根本用不了这么多,纯属浪费,所以将该寄存器的低 4 位全部置0,只使用高 4 位来配置,这样一来 STM32 就只有24=1624=16 2^4=1624=16级中断啦。
  简化为16级中断后,ST发现 STM32 内部这么丰富的外设,还是不方便配置,干脆人工给这4位来个分组,划分出了5个分组:
  再次强调一下,这5种中断分组规则是人为的,用哪种规则,之后设置具体的优先级时对应就行,STM32默认使用的规则是 NVIC_PriorityGroup_0 。
  STM32 的CPU判断优先级的方法如下:
  先判断抢占优先级,数字越小,优先级越高;
  若抢占优先级相同,判断子优先级,同样,数字越小,优先级越高
  基于STM32CubeMX的外部中断设计步骤
  在STM32CubeMX中指定引脚,配置中断初始化参数, 选择GPIO引脚的功能,设置中断信号触发条件,使能NVIC对应的中断通道。
  重写该I/O引脚对应的中断回调函数。
  具体实现步骤:
  新建工程
  搜索芯片型号
  选择芯片
  创建工程
  设置RCC
  1点击RCC
  2高速时钟(HSE)选择外部晶振
  3软件自动配置管脚
  
  GPIO初始化
  LED :GPIO_OUTPUT(输出模式)
  按键 :GPIO_EXITx(外部中断模式)
  点击对应管脚
  设置对应模式
  GPIO的各种模式设置
  
  + GPIO output level 引脚电平设置 高/低
  + GPIO mode GPIO模式 推挽输出/开漏输出
  + GPIO Pull-up/Pull-dowm 上拉下拉电阻 上拉电阻/下拉电阻/无上拉或下拉
  + Maxinum output speed 引脚速度设置 低速/中速/高速
  + User Label 用户标签 给引脚设置名称 如LED0
  ==GPIO_EXIT的六种模式==
  
  设置NVIC(嵌套向量中断控制器)
  [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
  
  1点击NVIC2 勾选EXIT Line
  2 interrupt 和 EXIT Line[15:12] interrupt 使能中断)
  时钟源设置
  
  1选择外部时钟HSE 8MHz
  2PLL锁相环倍频9倍
  3系统时钟来源选择为PLL
  4设置APB1分频器为 /2
  项目文件设置
  MDK外部中断的设置
  随后我们可以在stm32f1xx_it.c中看到我们所配置的中断服务函数 并且可以看到gpio的初始化分到了gpio.c里面,并且里面有一个函数
  HAL_GPIO_EXTI_IRQHandler();
  void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
  { /* EXTI line interrupt detected */
  if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)
  {
  __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
  HAL_GPIO_EXTI_Callback(GPIO_Pin);
  }
  }
  上述代码中可以看到,在该函数中首先读取了一下中断寄存器,确认该中断是否发生,确认之后又调用了一个函数,并将接收到的参数 GPIO_Pin 继续传给该函数
  HAL_GPIO_EXTI_Callback()
  该函数称为EXIT中断的回调函数,用来处理所有发生的EXIT中断事件
  往下看这个回调函数定义的时候使用了__weak修饰符,使用_weak进行了弱定义,所以用户可以再次定义该函数,并且这个note写的非常清楚:这个函数不应该被改变,如果需要使用回调函数,请重新在用户文件中实现该函数。我们需要重新定义这个函数。编辑在gpio.c(或者main.c也可以)
  
  使用JLINK调试STM32
  
  左边第一个按键时进入调试
  第二个是设置断点
  
  如图所示,在中断进入函数设置一个断点
  
  先选择JATG模式进行调试,频率为5Mhz,后面设置断点后进入调试,点击RUN(F5),则会出现如图所示的BUG
  
  这是因为在使用cubemx时没有设置SYS导致的,SYS默认是(No Debug模式)
  
  将其设置为Serial Wire模式然后生成工程,进入调试后仍发现上述错误存在,我在网上查找后发现是在stm32f1xx_hal_msp.c第79行代码,此代码的存在禁用了jtag,将其注释掉
  
  切记注释后将程序再次烧录进板子里(重新编译就不用我说了吧)。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分