关于STM32中断库函数写法

发布者:数字冒险最新更新时间:2021-10-11 来源: eefocus关键字:STM32  中断 手机看文章 扫描二维码
随时随地手机看文章

在STM32中中断的使用非常的频繁,其中EXTI 线 0~15:对应外部 IO 口的输入中断。


STM32F4 的 IO 口外部中断函数只有 7 个,分别为:

EXPORT EXTI0_IRQHandler

EXPORT EXTI1_IRQHandler

EXPORT EXTI2_IRQHandler

EXPORT EXTI3_IRQHandler

EXPORT EXTI4_IRQHandler

EXPORT EXTI9_5_IRQHandler

EXPORT EXTI15_10_IRQHandler

中断线 0-4 每个中断线对应一个中断函数,中断线 5-9 共用中断函数 EXTI9_5_IRQHandler,中

断线 10-15 共用中断函数 EXTI15_10_IRQHandler。

配置中断分组nvic.c,也就是设置好中断线与GPIO口的映射关系。


#include


#include "stm32f4xx.h"


void EXTI_nvic_init(void)

{

    NVIC_InitTypeDef   NVIC_InitStructure;

  

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;//抢占优先级0

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//子优先级2

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道

    

    NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;//外部中断10-15

    

    NVIC_Init(&NVIC_InitStructure);//配置

   

    NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;//外部中断4

    

    NVIC_Init(&NVIC_InitStructure);//配置    

    

    NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;//外部中断5-9

    

    NVIC_Init(&NVIC_InitStructure);//配置        

    

}


static void (*_call_4[5])(void);

void EXTI4_Register_Call(unsigned int line,void (*fun)(void)) 

{

  if (line & EXTI_Line0) _call_4[0] = fun;

  if (line & EXTI_Line1) _call_4[1] = fun;

  if (line & EXTI_Line2) _call_4[2] = fun;

  if (line & EXTI_Line3) _call_4[3] = fun;

  if (line & EXTI_Line4) _call_4[4] = fun;

}

void EXTI4_IRQHandler(void)

{

  if (EXTI_GetITStatus(EXTI_Line0)) {

    if (_call_4[0] != NULL) _call_4[0] ();

    EXTI_ClearITPendingBit(EXTI_Line0);

  }

  if (EXTI_GetITStatus(EXTI_Line1)) {

    if (_call_4[1] != NULL)_call_4[1] ();

    EXTI_ClearITPendingBit(EXTI_Line1);

  }

  if (EXTI_GetITStatus(EXTI_Line2)) {

    if (_call_4[2] != NULL)_call_4[2] ();

    EXTI_ClearITPendingBit(EXTI_Line2);

  }

  if (EXTI_GetITStatus(EXTI_Line3)) {

    if (_call_4[3] != NULL)_call_4[3] ();

    EXTI_ClearITPendingBit(EXTI_Line3);

  }

  if (EXTI_GetITStatus(EXTI_Line4)) {

    if (_call_4[4] != NULL)_call_4[4] ();

    EXTI_ClearITPendingBit(EXTI_Line4);

  }

}



static void (*_call_5_9[5])(void);

void EXTI9_5_Register_Call(unsigned int line, void (*fun)(void))

{

  if (line & EXTI_Line5) _call_5_9[0] = fun;

  if (line & EXTI_Line6) _call_5_9[1] = fun;

  if (line & EXTI_Line7) _call_5_9[2] = fun;

  if (line & EXTI_Line8) _call_5_9[3] = fun;

  if (line & EXTI_Line9) _call_5_9[4] = fun;

}



void EXTI9_5_IRQHandler(void)

{

   if (EXTI_GetITStatus(EXTI_Line5)) {

    if (_call_5_9[0] != NULL) _call_5_9[0] ();

    EXTI_ClearITPendingBit(EXTI_Line5);

  }

  if (EXTI_GetITStatus(EXTI_Line6)) {

    if (_call_5_9[1] != NULL) _call_5_9[1] ();

    EXTI_ClearITPendingBit(EXTI_Line6);

  }

  if (EXTI_GetITStatus(EXTI_Line7)) {

    if (_call_5_9[2] != NULL) _call_5_9[2] ();

    EXTI_ClearITPendingBit(EXTI_Line7);

  }

  if (EXTI_GetITStatus(EXTI_Line8)) {

    if (_call_5_9[3] != NULL) _call_5_9[3] ();

    EXTI_ClearITPendingBit(EXTI_Line8);

  }

  if (EXTI_GetITStatus(EXTI_Line9)) {

    if (_call_5_9[4] != NULL) _call_5_9[4] ();

    EXTI_ClearITPendingBit(EXTI_Line9);

  }

}


static void (*_call[6])(void);

void EXTI15_10_Register_Call(unsigned int line, void (*fun)(void))

{

  if (line & EXTI_Line10) _call[0] = fun;

  if (line & EXTI_Line11) _call[1] = fun;

  if (line & EXTI_Line12) _call[2] = fun;

  if (line & EXTI_Line13) _call[3] = fun;

  if (line & EXTI_Line14) _call[4] = fun;

  if (line & EXTI_Line15) _call[5] = fun;

}



void EXTI15_10_IRQHandler(void)

{

  if (EXTI_GetITStatus(EXTI_Line10)) {

    if (_call[0] != NULL) _call[0] ();

    EXTI_ClearITPendingBit(EXTI_Line10);

  }

  if (EXTI_GetITStatus(EXTI_Line11)) {

    if (_call[1] != NULL) _call[1] ();

    EXTI_ClearITPendingBit(EXTI_Line11);

  }

  if (EXTI_GetITStatus(EXTI_Line12)) {

    if (_call[2] != NULL) _call[2] ();

    EXTI_ClearITPendingBit(EXTI_Line12);

  }

  if (EXTI_GetITStatus(EXTI_Line13)) {

    if (_call[3] != NULL) _call[3] ();

    EXTI_ClearITPendingBit(EXTI_Line13);

  }

  if (EXTI_GetITStatus(EXTI_Line14)) {

    if (_call[4] != NULL) _call[4] ();

    EXTI_ClearITPendingBit(EXTI_Line14);

  }

  if (EXTI_GetITStatus(EXTI_Line15)) {

    if (_call[5] != NULL) _call[5] ();

    EXTI_ClearITPendingBit(EXTI_Line15);

  }  

}


在这里需要说明一下,固件库还提供了两个函数用来判断外部中断状态以及清除外部状态标志位的函数 EXTI_GetFlagStatus 和 EXTI_ClearFlag, 他们的作用和前面两个函数的作用类似。只是在 EXTI_GetITStatus 函数中会先判断这种中断是否使能,使能了才去判断中断标志位,而EXTI_GetFlagStatus 直接用来判断状态标志位。

下面举个栗子。


void ft6x36_init(void)

{

GPIO_InitTypeDef GPIO_InitStructure;


RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOB时钟


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输出模式

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;//100MHz

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉

GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化


EXTI_InitTypeDef EXTI_InitStructure;


RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG时钟


SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource1);//PE0 连接到中断线0


/* 配置EXTI_Line1 */

EXTI_InitStructure.EXTI_Line = EXTI_Line1;//

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断事件

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发

EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能LINE0

EXTI_Init(&EXTI_InitStructure);//配置

  EXTI4_Register_Call(EXTI_Line1, _touch_irq);


}

void _touch_irq(void)


{

。。。


}

关键字:STM32  中断 引用地址:关于STM32中断库函数写法

上一篇:stm32中断服务函数c语言,STM32中断使用总结——不使用固件库
下一篇:STM32–中断程序总结(库函数)

推荐阅读最新更新时间:2024-11-09 21:02

STM32单片机小Tips 玩转IAR开发STM32
BKP还没有搞完,怎么又换到了RTC上了,因为RTC和BKP有些联系,想不关联还不行呢。 以下是数据手册上有关RTC的介绍: RTC 简介 实时时钟是一个独立的定时器。RTC模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能。修改计数器的值可以重新设置系统当前的时间和日期。 RTC模块和时钟配置系统(RCC_BDCR寄存器)是在后备区域,即在系统复位或从待机模式唤醒后RTC的设置和时间维持不变。 系统复位后,禁止访问后备寄存器和RTC,防止对后备区域(BKP)的意外写操作。执行以下操作使能对后备寄存器和RTC的访问: ● 设置寄存器RCC_APB1ENR的PWREN和BKPEN位来使能电源和后备接口时
[电源管理]
<font color='red'>STM32</font>单片机小Tips 玩转IAR开发<font color='red'>STM32</font>
STM32】模板建立常见错误
1.新建工程的时候编译出现如下错误(MDK4.12 使用v3.4的库) ..\CMSIS\stm32f10x.h(80): error: #35: #error directive: Please select first the target STM32F10x device used in your application (in stm32f10x.h file) 解决方法:双击错误进入出错的地方,在stm32f10x.h处 #if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined(STM32F10X_MD) && !defined (S
[单片机]
【<font color='red'>STM32</font>】模板建立常见错误
STM32的优先级NVIC_PriorityGroupConfig的理解
STM32的优先级NVIC_PriorityGroupConfig的理解及其使用M3定义8位STM32只使用4位 写作原由:因为之前有对stm32 优先级做过研究,但是没时间把整理的东西发表,最近项目需要2个串口,但是不是两个串口同时使用,只是随机使用其中一个,程序对2个串口的优先级需要配置; 此文思路:“中断优先级”思维导图-- 关键要点--- 结合图和要点相关程序应用例程讲解; 我们先来看ST公司的一张图: 我自己依据此图理解,应用思维导图画了一张方便理解:(如果看不清可通过ctrl+鼠标滑轮 放大看;) 前提条件1:组别优先顺序(第0组优先级最强,第4组优先级最弱):NVIC_PriorityGroup_0 N
[单片机]
<font color='red'>STM32</font>的优先级NVIC_PriorityGroupConfig的理解
程序结构理解(1) 以stm32为例
程序中的几个段理解 有些技术文章中会直接使用RO,请注意区分RO和RO-data的区别。 Code:即代码域,它指的是编译器生成的机器指令。 RO_data:ReadOnly data,即只读数据域,它指程序中用到的只读数据,全局变量,例如C语言中const关键字定义的全局变量就是典型的RO-data。 RW_data:ReadWrite data,即可读写数据域,它指初始化为“非0值”的可读写数据,程序刚运行时,这些数据具有非0的初始值,且运行的时候它们会常驻在RAM区,因而应用程序可以修改其内容。例如全局变量或者静态变量,且定义时赋予“非0值”给该变量进行初始化。 ZI_data:ZeroInitialie data
[单片机]
程序结构理解(1) 以<font color='red'>stm32</font>为例
STM32学习笔记:单片机按键单击、双击、长按功能实现
由于项目产品的需要,只能设置一个按键,但是需要实现短按(即单击)切换工作模式、长按开关机、双击暂停等复用功能。下图是三种情况下的按键波形。按键未按下时是高电平,按下去是低电平。按键单击时,判断时间门槛设置为50~2000ms;长按门槛为持续按下2000ms。双击可以视为时间间隔很短的俩次有效单击,从第一次单击上升沿到第二次单击上升沿延时门槛为100~500ms。 //按键按下去会出现下降沿,设置按键IO口所在的外部端口为下降沿触发中断。void EXTIX_Init(void) { EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure;
[单片机]
<font color='red'>STM32</font>学习笔记:单片机按键单击、双击、长按功能实现
STM32自学笔记——看门狗
STM32的看门狗有俩个 WWDG和IWDG 两者最大的区别就是IWDG只有一个喂食下限而WWDG顾名思义窗户必须在一个范围内喂食才能保证不会触发复位 一.IWDG(独立看门狗) 1) 取消寄存器写保护( 向 IWDG_KR 写入 0X5555)通过这步,我们取消 IWDG_PR 和 IWDG_RLR 的写保护,使后面可以操作这两个寄存器, 设置 IWDG_PR 和 IWDG_RLR 的值。 这在库函数中的实现函数是: IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); 1 这个函数非常简单, 顾名思义就是开启/取消写保护,也就是使能/失能写权限。 2) 设置独立看门狗的预分频
[单片机]
在Mac OS X中搭建STM32开发环境(3)
在上两篇文章中,我们先后编译和安装了ST-Link2和交叉编译工具,在大家确认安装成功以后,可以做一个小Demo来测试一下是否成功。 (三)Demo (1)首先下载我做好的工程文件 http://pan.baidu.com/s/1hq9jU9e (如果分享链接失效,请联系我QQ:291402127),下载完成后,解压到你的用户文件夹(~/)中,目录结构如下: 在这里,我已经给大家编译好了,main.bin就是已经编译好的文件,大家可以直接烧写。 (2)手动编译 cd到stm32f4-discovery文件夹中,运行 make clean 清理编译成功的文件。 然后运行 make 编译过程中应该会出现以下信息: 完成
[单片机]
在Mac OS X中搭建<font color='red'>STM32</font>开发环境(3)
4.中断处理流程分析
在CPU工作的 过程中,经常需要与外设进行交互,交互的方式包括 轮询方式 和 中断方式 。 轮询方式: CPU不断地查询设备的状态。该方式实现比较简单,但是CPU的利用率很低,不适合多任务的系统。 中断方式: CPU告知硬件开始一项工作之后,就去做别的事去了,当硬件完成了该项任务后,向CPU发送一个信号,告知CPU它已经完成了这项工作了。 中断处理的流程: 1.中断生命周期: 串口中断实例: 中断的周期: 上面可以看到中断的流程包括:1.中断源。 2.中断控制器。3.CPU相应。 2.中断源 在中断的生命周期中,中断源的作用是负责产生中断信号。每个种开发板所支持的中断源的个数不尽相同: 3.中断过滤 下面是
[单片机]
4.<font color='red'>中断</font>处理流程分析
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved