STM32F103外部中断编程

    中断,顾名思义就是停下手头的活,去干另外一件急活,干完急活然后回来继续干手头的活。

单片机和人一样,有时候也有更急的程序需要执行,执行完之后再回来执行之前正在执行的程序。今天就来试试如何让单片机中断当前任务,执行其他任务。

先看看我的实验板上做外部中断要用的资源:


        如上图,板子的下面有三个独立按键,右下边有三个贴片的LED,其中这两部分的电路图如下图所示:

1、独立按键电路:


由上图可知,三个独立按键分别接在STM32的PB7、PB8、PB9引脚上。

2、LED电路:
由上图可知,三个LED分别接在STM32的PC1,、PC3、PC13引脚上,

我们规划是当按下按键K2的时候,就让灯D2闪烁一会儿。这时候K2就是外部中断,当按下后,触发中断服务函数,灯D2闪烁的程序就是中断服务函数。

现在打开Keil V5进行编程:

先在Manage Run-time Environment界面勾选以下选项:

勾选完成后,就开始进行编程:

1、中断初始化函数的编写:

void Exit_Configuration(void)

{

/*

*定义结构体

*/

EXTI_InitTypeDef  EXTI_InitStructure;

GPIO_InitTypeDef  GPIO_InitStructure;

NVIC_InitTypeDef  NVIC_InitStructure;

/*

*时钟配置(要打开AFIO时钟)

*/

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO,ENABLE);

/*

*外部中断使用的GPIO的配置使用PB口的9引脚

*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOB, &GPIO_InitStructure);

/*

*外部中断使用的GPIO引脚也就是PB口的9引脚连接到EXTILine9

*/

GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource9);

/*

*配置外部中断

*/

EXTI_InitStructure.EXTI_Line    =EXTI_Line9;

EXTI_InitStructure.EXTI_Mode    = EXTI_Mode_Interrupt;

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;

EXTI_InitStructure.EXTI_LineCmd = ENABLE;

EXTI_Init(&EXTI_InitStructure);

/*

*配置NVIC

*/

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

2、中断初始化函数写好了之后,就要编写中断服务函数了:

void EXTI9_5_IRQHandler(void)

{

u16 aa=10;

if(EXTI_GetITStatus(EXTI_Line9)!=RESET){

//初始化灯所在的GPIO

GPIO_InitTypeDef  GPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIOC, &GPIO_InitStructure);

//通过循环让灯闪烁

while (aa){

GPIO_SetBits(GPIOC,GPIO_Pin_3);

delay_us(100000);

GPIO_ResetBits(GPIOC,GPIO_Pin_3);

delay_us(100000);

aa--;

}

//清除中断标志

EXTI_ClearITPendingBit(EXTI_Line9);

//使灯的状态为灭

GPIO_SetBits(GPIOC,GPIO_Pin_3);

}

}

3、当然延时函数的实现使用的是系统滴答定时器,函数实现如下:

/*******************************************************************************

* 函 数 名         : delay_us

* 函数功能 : 延时函数,延时us

* 输    入         : i

* 输    出         : 无

*******************************************************************************/

void delay_us(u32 i)

{

u32 temp;

SysTick->LOAD=9*i; //设置重装数值, 72MHZ时

SysTick->CTRL=0X01; //使能,减到零是无动作,采用外部时钟源

SysTick->VAL=0;   //清零计数器

do

{

temp=SysTick->CTRL;   //读取当前倒计数值

}

while((temp&0x01)&&(!(temp&(1<<16)))); //等待时间到达

SysTick->CTRL=0; //关闭计数器

SysTick->VAL=0; //清空计数器

}

4、以上都完成后我们就可以编写main函数了,main函数非常简单,只要初始化外部中断,然后就可以空循环等待中断。当然在正常项目中主程序一般不会空循环。main函数如下;

int main(){

Exit_Configuration();

while(1)

{

;

}

}

当程序编写完成之后我们下载到板子上进行试验,按下按键Key2,发现灯并没有像我们想象的那样闪烁,为什么呢?回头查看程序:

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;这句的意思在官方库函数文档中的解释是:


也就是说可以设置中断为上升沿中断还是下降沿中断还是上升沿和下降沿都产生中断。回头看看我们的硬件电路:


PB9通过一个按键接地,也就是当按键按下去之后,PB9的输入电平为低电平,而原本我们程序中初始化GPIO的语句如下:

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO的模式配置是浮空输入,这时候没有信号输入的时候相当于是低电平,而我们再按下按键的时候,仍然是低电平,所以并没有产生上升沿或者下降沿,这样的话我们就需要对电路进行修改,怎么修改呢,在PB9上连接一个大的电阻连接到VCC,这样当按键没有按下去的时候,PB9输入高电平,当按键按下去之后,PB9输入低电平,相当于触发了外部中断。这个我们添加的电阻,就是上拉电阻,在我之前的电子元器件的使用之电阻的使用中有讲解。

通过以上的操作就可以看到,当你按下按键之后,灯如你所愿的闪烁起来了。这就是STM32的外部中断使用过程。

总结:

要使用STM32的外部中断,需要以下几个步骤:

1、使用RCC_APB2PeriphClockCmd()函数配置时钟

2、使用GPIO_EXTILineConfig()函数连接中断产生的引脚

3、使用EXTI_Init(  )函数配置外部中断

4、使用NVIC_Init()配置中断优先级等

5、编写中断服务函数EXTI9_5_IRQHandler()

其中大家可能会疑惑,中断服务函数的名字中的9_5是什么意思呢?

PxN管脚共用外部中断线EXTIN和外部中断向量EXTIN_IRQn和中断服务程序入口EXTIN_IRQHandler,其中[9...5]共用EXTI9_5_IRQn和EXTI9_5_IRQHandler、[15...10]共用EXTI15_10_IRQn和EXTI15_10_IRQHandler,这样的话不管我们用PA9还是PB9,都是用EXTI9_5_IRQHandler这个函数。


从上面这张图可以看出上面讲的是什么意思了

而EXTI9_5_IRQn用在什么地方呢?大家返回去看配置NVIC的程序:

        NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;

 如果觉得有用,请关注微信公众号:


 

 

STM32F103外部中断编程的更多相关文章

  1. stm32中断优先级管理与外部中断编程

    stm32中断优先级管理与外部中断编程 中断优先级管理 外部中断编程 官方示例程序 exti.h #ifndef __EXTI_H #define __EXIT_H #include "sy ...

  2. [STM32F103]外部中断

    ① 初始化IO口为输入. GPIO_Init(); ② 开启IO口复用时钟. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); ③ 设置IO口与中 ...

  3. STM32f103之外部中断

    一.背景 有个需求,IO口检测上升沿,然后做相应的动作.在此记录STM32F103的外部中断结构及配置方法, 以备下次快速上手使用. 有许多不太明白,又是老司机(:-D)帮忙,真的是站在别人的肩膀上会 ...

  4. 嵌入式外部中断控制编程方法论—比較CC2541(51核)和S5PV210(ARM核)

    这是一篇阐述怎样对嵌入式SOC外部中断进行控制编程的方法论文章.希望读者理解本篇文章后.能够具备对市场上全部已经面世和将来面世的嵌入式芯片的外部中断进行控制编程的能力. 笔者原创的技术分享一直都恪守下 ...

  5. (stm32f103学习总结)—stm32外部中断

    一.外部中断介绍 1.1 EXTI简介 EXTI简介 STM32F10x外部中断/事件控制器(EXTI)包含多达 20 个用于产生事 件/中断请求的边沿检测器.EXTI的每根输入线都可单独进行配置,以 ...

  6. stm32寄存器版学习笔记03 外部中断

    stm32的每个I/O口都可以作为中断输入,要把I/O口设置为外部中断输入,必须将I/O口设置为上拉/下拉输入 或 浮空输入(但浮空的时候外部一定要带上拉或下拉电阻,否则可能导致 中断不停的触发),干 ...

  7. STM32 GPIO外部中断总结

    一.STM32中断分组: STM32 的每一个GPIO都能配置成一个外部中断触发源,这点也是 STM32 的强大之处.STM32 通过根据引脚的序号不同将众多中断触发源分成不同的组,比如:PA0,PB ...

  8. ok6410按键中断编程,linux按键裸机

    6410按键中断编程 一.流程分析 外部中断控制寄存器(s3c6410x  359页) 1.EINTxCONy: 外部中断组x的第y个控制器.这个就是设置中断的触发方式.有5种触发方式. 2.EINT ...

  9. 单片微机原理P2:80C51外部中断与定时器系统

    0. 外部中断 书上的废话当然是很多的了,对于中断我想大家应该早就有一个很直观的认识,就是"设置断点,执行外部外码,然后返回断点"这样的三个过程.中断给系统提供了一个良好的响应模式 ...

随机推荐

  1. Android----->多线程的实现Thread、IntentService的运用

    首先建立一个Intent.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout x ...

  2. HDU 4828 Grids(卡特兰数+乘法逆元)

    首先我按着我的理解说一下它为什么是卡特兰数,首先卡特兰数有一个很典型的应用就是求1~N个自然数出栈情况的种类数.而这里正好就对应了这种情况.我们要满足题目中给的条件,数字应该是从小到大放置的,1肯定在 ...

  3. 转:浅谈手机app测试注意点

    现在我们测试时,开发会先在本地机上打好测试包,自己安装,轮完一轮,开发修改好后,再打一个包.以下是功能测试时需要注意的点: 1.登录 ●登录用户名和密码错误时,界面有提示信息 ●用户主动退出登录后,下 ...

  4. oracle 管理

    1.管理数据的用户主要是:sys和system. 区别:(1)sys所有oracle的数据字典的基表和视图都存放在sys用户中,这些基表和视图对于oracle是至关重要的,由数据库自己维护,任何用户都 ...

  5. Mysql笔记3数据库基本操作

    1 创建数据库 create database 数据名称 default character set 编码; 2查看常用的编码校验规则 mysql> show character set; 3删 ...

  6. Windows API 之 CreateThread、GetExitCodeThread(未完)

    GetExitCode Retrieves the termination status of the specified thread. BOOL WINAPI GetExitCodeThread( ...

  7. C++调用java

    摘要: 1 java类生成c头文件和库文件 2 对于c/c++程序,启动时先启动jvm,然后获得对应的java类的对象和方法.然后正常使用. 最近正在做一个C/C++调用java的程序,这里说的调用j ...

  8. C#入门经典第八章面向对象编程-3-Windows应用程序中的OOP

    实例一:使用对象.代码如下: 首先从工具箱中拖一个按钮,并添加事件. private void button2_Click(object sender, EventArgs e) {//按钮的Butt ...

  9. HDU 2087 剪花布条(KMP基础应用)

    KMP基础,注意输入 #include<cstdio> #include<cstring> #include<iostream> using namespace s ...

  10. PAT (Advanced Level) 1071. Speech Patterns (25)

    简单题. #include<cstdio> #include<cstring> #include<cmath> #include<vector> #in ...