STM32F103外部中断编程
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外部中断编程的更多相关文章
- stm32中断优先级管理与外部中断编程
stm32中断优先级管理与外部中断编程 中断优先级管理 外部中断编程 官方示例程序 exti.h #ifndef __EXTI_H #define __EXIT_H #include "sy ...
- [STM32F103]外部中断
① 初始化IO口为输入. GPIO_Init(); ② 开启IO口复用时钟. RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); ③ 设置IO口与中 ...
- STM32f103之外部中断
一.背景 有个需求,IO口检测上升沿,然后做相应的动作.在此记录STM32F103的外部中断结构及配置方法, 以备下次快速上手使用. 有许多不太明白,又是老司机(:-D)帮忙,真的是站在别人的肩膀上会 ...
- 嵌入式外部中断控制编程方法论—比較CC2541(51核)和S5PV210(ARM核)
这是一篇阐述怎样对嵌入式SOC外部中断进行控制编程的方法论文章.希望读者理解本篇文章后.能够具备对市场上全部已经面世和将来面世的嵌入式芯片的外部中断进行控制编程的能力. 笔者原创的技术分享一直都恪守下 ...
- (stm32f103学习总结)—stm32外部中断
一.外部中断介绍 1.1 EXTI简介 EXTI简介 STM32F10x外部中断/事件控制器(EXTI)包含多达 20 个用于产生事 件/中断请求的边沿检测器.EXTI的每根输入线都可单独进行配置,以 ...
- stm32寄存器版学习笔记03 外部中断
stm32的每个I/O口都可以作为中断输入,要把I/O口设置为外部中断输入,必须将I/O口设置为上拉/下拉输入 或 浮空输入(但浮空的时候外部一定要带上拉或下拉电阻,否则可能导致 中断不停的触发),干 ...
- STM32 GPIO外部中断总结
一.STM32中断分组: STM32 的每一个GPIO都能配置成一个外部中断触发源,这点也是 STM32 的强大之处.STM32 通过根据引脚的序号不同将众多中断触发源分成不同的组,比如:PA0,PB ...
- ok6410按键中断编程,linux按键裸机
6410按键中断编程 一.流程分析 外部中断控制寄存器(s3c6410x 359页) 1.EINTxCONy: 外部中断组x的第y个控制器.这个就是设置中断的触发方式.有5种触发方式. 2.EINT ...
- 单片微机原理P2:80C51外部中断与定时器系统
0. 外部中断 书上的废话当然是很多的了,对于中断我想大家应该早就有一个很直观的认识,就是"设置断点,执行外部外码,然后返回断点"这样的三个过程.中断给系统提供了一个良好的响应模式 ...
随机推荐
- Swift 与 JSON 数据 浅析
转载自:http://www.cnblogs.com/theswiftworld/p/4660177.html 我们大家平时在开发 App 的时候,相信接触最多的就是 JSON 数据了.只要你的 Ap ...
- Android中的对话框AlertDialog使用技巧合集-转载
Android中的对话框AlertDialog使用技巧合集 文章来自:http://blog.csdn.net/blue6626/article/details/6641105 今天我用自 ...
- HDU1874 最短路 SPFA
最短路 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 24 Solved: 17 [Submit][Status][Web Board] Descr ...
- Android平台设计规范整理(尺寸+组成元素+字体+滑块)
转自:http://www.ui.cn/project.php?id=12394
- 用cas来实现php的单点登陆
最近项目中需要做单点登录,客户端包含Java.ruby和PHP,java有几个应用程序,php是discuz+supesite+ucenter,配置步骤如下: 1.cas服务端:下载地址:http:/ ...
- MVC 使用Jquery的$.post传递参数
MVC中,如果要使用 $.post 给 COntroller 传递参数,需要类实现 属性 get set,这样才行
- Chapter 1 First Sight——14
I parked in front of the first building, which had a small sign over the door reading front office. ...
- 迄今最安全的MySQL?细数5.7那些惊艳与鸡肋的新特性(上)【转载】
转自: DBAplus社群 http://www.toutiao.com/m5762164771/ 迄今最安全的MySQL?细数5.7那些惊艳与鸡肋的新特性(上) - 今日头条(TouTiao.com ...
- java集合框架工具类Collections,集合的操作
1 import java.util.*; public class asList { public static void main(String args[]) { // int arr[] = ...
- getHibernateTemplate()
getHibernateTemplate 前提条件:你的类必须继承HibernateDaoSupport 一: 回调函数: public List getList(){ return (List ...