小白学习STM32(一)(基于cubemx+MDK)外部中断

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个分组:

优先级分组 抢占优先级占的位数 子优先级占的位数
NVIC_PriorityGroup_0 0 bit 4 bit
NVIC_PriorityGroup_1 1 bit 3 bit
NVIC_PriorityGroup_2 2 bit 2 bit
NVIC_PriorityGroup_3 3 bit 1 bit
NVIC_PriorityGroup_4 4 bit 0 bit

再次强调一下,这5种中断分组规则是人为的,用哪种规则,之后设置具体的优先级时对应就行,STM32默认使用的规则是 NVIC_PriorityGroup_0 。
STM32 的CPU判断优先级的方法如下:

先判断抢占优先级,数字越小,优先级越高;
若抢占优先级相同,判断子优先级,同样,数字越小,优先级越高


基于STM32CubeMX的外部中断设计步骤

  1. 在STM32CubeMX中指定引脚,配置中断初始化参数, 选择GPIO引脚的功能,设置中断信号触发条件,使能NVIC对应的中断通道。

  2. 重写该I/O引脚对应的中断回调函数。


    具体实现步骤

    1. 新建工程

      • 搜索芯片型号
      • 选择芯片
      • 创建工程
    2. 设置RCC

      • 1点击RCC
      • 2高速时钟(HSE)选择外部晶振
      • 3软件自动配置管脚
        小白学习STM32(一)(基于cubemx+MDK)外部中断
    3. GPIO初始化

      LED :GPIO_OUTPUT(输出模式)

      按键 :GPIO_EXITx(外部中断模式)

      • 点击对应管脚
      • 设置对应模式

      GPIO的各种模式设置

小白学习STM32(一)(基于cubemx+MDK)外部中断

  + GPIO output level   引脚电平设置   高/低
  + GPIO mode   GPIO模式     推挽输出/开漏输出
  + GPIO Pull-up/Pull-dowm   上拉下拉电阻      上拉电阻/下拉电阻/无上拉或下拉
  + Maxinum output speed   引脚速度设置   低速/中速/高速
  + User Label    用户标签   给引脚设置名称  如LED0

  ==GPIO_EXIT的六种模式==

小白学习STM32(一)(基于cubemx+MDK)外部中断

  1. 设置NVIC(嵌套向量中断控制器)

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传小白学习STM32(一)(基于cubemx+MDK)外部中断

    • 1点击NVIC2 勾选EXIT Line
    • 2 interrupt 和 EXIT Line[15:12] interrupt 使能中断)
  2. 时钟源设置
    小白学习STM32(一)(基于cubemx+MDK)外部中断

    • 1选择外部时钟HSE 8MHz
    • 2PLL锁相环倍频9倍
    • 3系统时钟来源选择为PLL
    • 4设置APB1分频器为 /2
  3. 项目文件设置


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也可以)

小白学习STM32(一)(基于cubemx+MDK)外部中断

使用JLINK调试STM32

小白学习STM32(一)(基于cubemx+MDK)外部中断

  1. 左边第一个按键时进入调试
  2. 第二个是设置断点
    小白学习STM32(一)(基于cubemx+MDK)外部中断
    如图所示,在中断进入函数设置一个断点

小白学习STM32(一)(基于cubemx+MDK)外部中断

先选择JATG模式进行调试,频率为5Mhz,后面设置断点后进入调试,点击RUN(F5),则会出现如图所示的BUG
小白学习STM32(一)(基于cubemx+MDK)外部中断
这是因为在使用cubemx时没有设置SYS导致的,SYS默认是(No Debug模式)

小白学习STM32(一)(基于cubemx+MDK)外部中断

将其设置为Serial Wire模式然后生成工程,进入调试后仍发现上述错误存在,我在网上查找后发现是在stm32f1xx_hal_msp.c第79行代码,此代码的存在禁用了jtag,将其注释掉

小白学习STM32(一)(基于cubemx+MDK)外部中断

切记注释后将程序再次烧录进板子里(重新编译就不用我说了吧)

上一篇:【rt-thread】构建自己的项目工程 -- 初始篇


下一篇:STM32 cubemx 开发系列文章(一)认识cubemx