STM32-CubeMX学习使用记录4-外部中断的使用

目录

1.STM32中断系统介绍

2.STM32_HAL库中断函数

3.CubeMX配置及应用


1.STM32中断系统介绍

        1.STM32的NVIC(嵌套向量中断控制器)有82个可屏蔽中断(可以设置优先级)和13个系统中断

        2.NVIC采用4位二进制数来设置中断优先级,分为抢占优先级和次优先级两段,中断的数字越小,代表中断的优先级越高。

        分段:

抢占优先级    次优先级
 0位4位
1位3位
2位2位
3位1位
4位0位

          一般只用抢占优先级。

        3. (1)如果抢占优先级与次优先级相同则谁先发生谁就先执行

           (2)抢占优先级的中断可以打断正在执行的底抢占优先级的中断函数

         (3)如果抢占优先级相同,则高次优先级的中断不能打断正在执行的底次优先级的中断函数

        4.  外部中断框图

        过程:首先,框图中的20是代表着有20根线,互联型产品有20根中断线(如F107),其他产品有19中断根线(如F103)。寄存器连接到总线上,受cpu控制,当我们设置中断触发类型是上升沿触发,EXTI中断线选择1时(比如选择PA1),上升沿触发选择寄存器对应位就会置 “1”,代表允许对应中断线上升沿触发,边沿检测电路检测到上升沿时就会输出高电平,经过或门输出高电平,请求挂起寄存器对应位被置1,同时由于中断屏蔽寄存器已经设置了对应中断线的中断,对应位置1,经过与门输出高电平给NVIC中断控制器,接着运行中断处理函数。对应寄存器的介绍可以查看数据手册 9.2

        除此之外,事件屏蔽寄存器是外设自行控制,与边沿检测电路和上下降沿触发选择寄存器配合输出到脉冲发生器。软件中断事件寄存器是选择软件触发中断。

        5. EXTI_0 - EXTI15,这16根中断线,每根中断线只能选择多个端口中的一个,不可共用。例如选择PA0为EXTI0的中断输入线,则PB0不能作为中断输入线

        6.不是所有的中断线都有自己的ISR中断函数,例如EXTI0-EXTI4,都有自己对应的中断函数EXTIx_IRQHandle,但是EXTI5-EXTI9,共用一个ISR中断函数EXTI9_5_IRQHandle,EXTI10-EXTI15,共用一个ISR中断函数EXTI15_10_IRQHandle

        7. EXTI16-EXTI22连接的是外设事件信号,这七个中断线都有自己对应的ISR中断函数。


2.STM32_HAL库中断函数

       点击STM32f1xx_HAL_Cortex.h查看NVIC配置函数,这些在CubeMx中是配置好的,知道就好,标准库的话这些得自己初始化。

        2.1 void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup);

                设置优先级组别

                PriorityGroupNVIC_PRIORITYGROUP_0  : 0bit 抢  4bit 次

                                        NVIC_PRIORITYGROUP_1 :   1bit 抢  3bit 次

                                        NVIC_PRIORITYGROUP_2 :  2bit 抢  2bit 次

                                        NVIC_PRIORITYGROUP_3 : 3bit 抢  1bit 次

                                        NVIC_PRIORITYGROUP_4 : 4bit 抢  0bit 次

        2.2 void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority);

               设置指定中断的抢占优先级和次优先级

                IRQn :在STM32f103xb.h中有M3内核中段和外部中断,右键跳转

                PreemptPriority :抢占优先级    0- 15  根据优先级组别来写

                SubPriority :次优先级  0 - 15 根据优先级组别来写

        2.3 void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)

                使能指定中断

                 IRQn :在STM32f103xb.h中有M3内核中段和外部中断,右键跳转

        2.4 void HAL_NVIC_DisableIRQ(IRQn_Type IRQn);

                失能指定中断

                IRQn :在STM32f103xb.h中有M3内核中段和外部中断,右键跳转

        2.5 void HAL_NVIC_SystemReset(void);

                复位mcu

        2.6 uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb)

                初始化系统定时器及其中断,并启动系统滴答定时器,用于初始化

                TicksNumb中断间隔,中断触发时间  

                一般:HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)

                SystemCoreClock :系统时钟 比如72MHZ     uwTickFreq  :中断间隔 比如 1 = 1ms  

                该函数在HAL_Init()中和SystemClock_Config()都初始化过,但是要注意,在SystemClock_Config中才是最终确定的SystemClock的中断间隔。

                具体看:【STM32】HAL库-系统滴答定时器SysTick_systick hal-CSDN博客

        点开stm32f1xx_hal_gpio.h可以查看与外部中断有关的函数,这些CubeMx自己配置好了,可以不用管,了解功能即可。

 

#define __HAL_GPIO_EXTI_GET_FLAG(__EXTI_LINE__) (EXTI->PR & (__EXTI_LINE__))

        宏定义函数,该函数是检查是否设置了指定的EXTI行标志。

        __EXTI_LINE__:GPIO_PIN_x         x:(0-15)

#define __HAL_GPIO_EXTI_CLEAR_FLAG(__EXTI_LINE__) (EXTI->PR = (__EXTI_LINE__))

        宏定义函数,清除EXTI的行挂起标志 , 在ISR中断函数中用该函数清除挂起标志位(就是上面框图中的请求挂起寄存器的标志位)

        __EXTI_LINE__:GPIO_PIN_x         x:(0-15)

#define __HAL_GPIO_EXTI_GET_IT(__EXTI_LINE__) (EXTI->PR & (__EXTI_LINE__))  

#define __HAL_GPIO_EXTI_CLEAR_IT(__EXTI_LINE__) (EXTI->PR = (__EXTI_LINE__))

与上面的两个函数功能相同。 

        最后:

#define __HAL_GPIO_EXTI_GENERATE_SWIT(__EXTI_LINE__) (EXTI->SWIER |= (__EXTI_LINE__))
        宏定义函数,在选定的EXTI行上生成软件中断 ,就是开启软件中断,很少用。

          __EXTI_LINE__:GPIO_PIN_x         x:(0-15)

最后:打开stm32f1xx_hal_gpio.h这两个是比较重要的函数,其实就是一个函数。

void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
 这个函数用到了上面的两个宏定义函数一个是判断是否触发外部中断,一个是清楚挂起标志位。然后进入HAL_GPIO_EXTI_Callback(GPIO_Pin)这个函数,也就是第二个函数。

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);---中断回调函数

这个函数是一个_weak弱函数,所以可以自己重新写一个一样的函数,就只是把_weak去掉,然后自己写中断函数的内容。

配置完CubeMX后要做的就是写这个中断函数内容。


3.CubeMX配置及应用

        实验:使用按键来控制led灯的亮灭

        使用PB0作为KEY,使用PC13作为LED,时钟选择HSE

        

注意:如果使用swd进行调试下载,千万别忘了把Debug选择swd,否则将没配置SWD的程序下进去后再次下载就会找不到下载器了,真遇到这种情况时,如果自己的板子上留出了Boot0和Boot1的引脚,用跳帽将Boot0置1再下载:

点击NVIC修改优先级:

这里把系统时钟的优先级调高了,因为中断中要使用延时函数,不调高的话会卡死。

GPIO配置根据自己的硬件来:

时钟树选择72MHZ

点击生成代码。

提示:如果想基于自己上次的工程模板创建CubeMX工程,可以点击该选项,新创建文件夹修改一下名字即可

打开keil后,找到stm32f1xx_it.c打开

找到:

打开HAL_GPIO_EXTI_IRQHandler(KEY1_Pin) 函数中已经写好了清楚标志,所以只写中断内容就好了。

 所以找个位置把HAL_GPIO_EXTI_Callback(GPIO_Pin)再写一遍就好了

我选择了在gpio.c中复写。

这样按键按下一次led就会改变一次状态 ,一直按着不变。

江涛带你玩STM32-CubeMX红外NEC解码实战(上)--外部中断方式。 NEC红外协议是一种常见的红外信号通信协议,利用这个协议我们可以实现遥控器对单片机的控制。在STM32开发中,可以使用外部中断方式来实现NEC红外码的解码。 首先,我们需要在CubeMX中配置外部中断引脚。选择对应的GPIO引脚,将其配置为外部中断输入模式。然后将中断触发方式设置为上升沿触发,这样当红外接收模块接收到红外信号时,引脚上的电平会从低电平跳变到高电平,触发外部中断。 接下来,我们在代码中初始化外部中断使用HAL库提供的函数HAL_GPIO_Init()初始化GPIO引脚。然后使用HAL库提供的函数HAL_NVIC_SetPriority()设置中断优先级,通过HAL_NVIC_EnableIRQ()使能中断。 然后,我们需要编写中断处理函数。在中断处理函数中,我们首先可以通过读取GPIO引脚的电平状态来判断是否收到了红外信号。然后可以使用定时器计数器来计算红外信号的时长,根据时长判断是0还是1,进而解码出红外码。可以使用计时器中断来实现时长的计算,并将计算结果保存在一个数组中,用于后续的红外码解析。 最后,我们可以通过串口或者其他方式将解码后的红外码输出,在串口助手上看到红外码的内容。 总结一下,使用STM32-CubeMX外部中断方式实现NEC红外码解码实战的步骤包括配置外部中断引脚、初始化外部中断、编写中断处理函数、计算红外信号的时长并解码出红外码、输出解码后的红外码。通过这种方式,我们可以通过遥控器来控制单片机的各种功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值