完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
理论篇
引入—什么是中断? 通俗的说:比如我正在写博客,老板突然给我一个任务,我暂停的写博客,转而把老板布置的任务完成之后,再继续写博客,这个过程就可以理解成中断。 百度引用:‘中断是指CPU在处理某一件事A时,发生了另一件事B,请求CPU迅速去处理(这个过程是“中断发生”);此时,CPU暂时停止当前的A事件(这个过程是“中断响应”),转去处理B事件(这个过程是“中断服务”);待CPU将B事件处理完毕后,再回到事件A被中断打断的地方继续处理事件A(这个过程是“中断返回”)。这一过程,称之为中断。’ 深入理解_线程的概念 我认为要想理解中断的概念,作为一个工科生,还应该理解线程的概念 线程:程序运行流的最小单元,一个程序是有一个或多个线程组成。 你可以理解成线程就是单片机执行的一个任务,比如,流水灯、读取发送某一个传感器的数据。但是我们平时写的单片机程序一般就是单线程的,就是单片机一个 多线程编程:如果你还是个小白,可以简单的理解我们使用的简单的单片机就只能执行一个任务,但是后面通过系统的学习你还会知道,就算是单线程的话,单片机也可以分时“执行多个任务”,这里是借助了计算机实现多线程的编程方法(比如一边播放视频一边听音乐,它可以先执行听音乐的任务,当视频的下一帧到,它先把音乐的任务暂停,保存这个任务所有的变量,执行播放视频到任务,然后再把播放视频的任务暂停,执行播放音乐的任务,不断地循环下去,另外你还要知道单片机的执行速度是非常快滴,快到你根本分辨不出来中间有卡顿。所以就会认为任务同时做了两件事) 这里可能有很多人想,现在的很多电子设备都是几核几线程的(多核、线程、进程、多线程的理解这里就不多讲了),多个CPU实现了并行运行方式,属于真正的多线程,但是多个CPU的控制方案成本几乎成倍的增加,而且要是实现多个CPU之间的通讯花费的实践较长,并且干扰影响较大。 中断源、中断任务、中断返回: 总结起来,就是你需要知道中断就是单片机处理任务A时,发生了触发中断的条件停下来执行另一个任务B,触发中断的条件就属于中断源,任务B就是中断任务(中断服务函数)。当中断任务执行完成后中断返回,在回到任务A中断的地方继续处理任务A。 中断优先级 为使系统能及时响应并处理发生的所有中断,系统根据引起中断事件的重要性和紧迫程度,硬件将中断源分为若干个级别,称作中断优先级。百度百科 这里再举一个简单的例子:仍然是我正在写博客,老板给我发了一个任务A,但是同时老婆也给我一个任务B,两个任务同时到达,我该先执行哪一个呢?当然先执行老婆的任务B了,然后再执行老板的任务A,再完成之后在继续写我的博客。在这里执行老婆的任务B就比执行老板任务A的中断优先级级别高。但是我要是正在执行老婆B的任务,这个时候老板的任务A过来了,这个时候我会继续执行老婆的任务B,也是因为老板的任务A没有老婆B的任务优先级高,这里 老婆任务 > 老板任务 > 写博客任务 所以多级中断的处理原则:当多级中断同时发生时,CPU按照由高到低的顺序响应。高级中断可以打断低级中断处理程序的运行,转而执行高级中断处理程序。当同级中断同时到时,则按位响应。 STM32的抢占优先级、响应优先级、NVIC 的优先级组 这里转自部分 https://blog.csdn.net/qlexcel/article/details/78841296 STM32 的中断向量具有两个属性,一个为抢占属性,另一个为响应属性,其属性编号越小,表明它的优先级别越高。 抢占属性:是指打断其他中断的属性,即因为具有这个属性会出现嵌套中断(在执行中断服务函数A 的过程中被中断B 打断,执行完中断服务函数B 再继续执行中断服务函数A),抢占属性由NVIC_IRQChannelPreemptionPriority 的参数配置。 响应属性:应用在抢占属性相同的情况下,当两个中断向量的抢占优先级相同时,如果两个中断同时到达, 则先处理响应优先级高的中断, 响应属性由NVIC_IRQChannelSubPriority 参数配置。 NVIC 的优先级组:在配置优先级的时候,还要注意一个很重要的问题,即中断种类的数量。NVIC 只可以配置16 种中断向量的优先级,也就是说,抢占优先级和响应优先级的数量由一个4 位的数字来决定,把这个4 位数字的位数分配成抢占优先级部分和响应优先级部分。 定时器中断、外部中断、串行口发送或接受中断 这些中断事件主要根据中断源不同划分。 定时器中断是你需要定时的时间A ms到了,会产生定时器中断,执行A ms后的中断内容。主要执行定时完成的任务。属于片内中断。 外部中断是中断源来自单片机的外部,比如61单片机的P3.2引脚检测到了跳变沿,接着执行外部中断任务。主要执行由外部因素影响的任务。属于片外中断。 串行口发送或接受中断是在串行口有接收到数据执行的中断任务。主要接收串行口的数据。属于片内中断。 实战篇 这里通过一个51单片机的外部中断程序来和STM32F1的中断程序加深对中断的理解,定时器中断、串口中断在以后的文章里会介绍到。这里要知道51单片机只有P3.2和P3.3引脚的低电平或下降沿信号中断。而STM32每个引脚都可以。。。/可怕不,差距。 注意51单片机一共支持5个中断源,其中2个外部中断源,3个内部中断源 (1)外部中断0,由INT0(P3.2引脚)输入。 (2)外部中断1,由INT1(P3.3引脚)输入。 (3)定时/计数器0溢出中断(T0)请求。 (4)定时/计数器0溢出中断(T1)请求。 (5)串行口发送/接收中断请求。 这里使用论坛51单片机中断学习知识点总结中的代码修改解释 原文:https://blog.csdn.net/whalefall/article/details/79900817 1、设置中断触发方式,即IT0=1或0,IT1=1或0 当IT0=0时,为电平触发方式。当IT0=1时,为边沿触发方式(下降沿有效)。 2、开对应的外部中断,即EX0=1或EX1=1; 外部中断0允许位或外部中断1允许位;; 3、开总中断,即EA=1; 4、等待外部设备产生中断请求,即通过P3.2,P.3.3口连接外部设备产生中断 5、中断响应,执行中断服务函数 eg. 外部中断0实验 * 实现现象:下载程序后按下K3按键可以对D1小灯状态取反。 #include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器 typedef unsigned int u16; //对数据类型进行声明定义 typedef unsigned char u8; ***it k3=P3^2; //定义独立按键K3 ***it led=P2^0; //定义P20口是led void delay(u16 i) { while(i--); } void Int0Init() { //设置INT0,外部中断0 IT0=1; //跳变沿出发方式(下降沿) EX0=1; //打开INT0的中断允许。 EA=1; //打开总中断 } void main() { Int0Init(); // 设置外部中断0 while(1); //这里系统就是不断死循环,如果有中断请求,执行中断程序,然后继续死循环。 } void Int0() interrupt 0 //外部中断0的中断函数 { delay(1000); //延时消抖 if(k3==0) { led=~led; } } STM32的每个IO口大可以作为中断输入。但是需要设置IO 口与中断线的映射关系,这里内部的工作原理感兴趣的可以查阅芯片手册, 这里附上正点原子额开发指南的部分如下 1) 初始化 IO 口为输入。 这一步设置你要作为外部中断输入的 IO 口的状态,可以设置为上拉/下拉输入,也可以设置为浮空输入,但浮空的时候外部一定要带上拉,或者下拉电阻。否则可能导致中断不停的触发。在干扰较大的地方,就算使用了上拉/下拉,也建议使用外部上拉/下拉电阻,这样可以一定程度防止外部干扰带来的影响。 2)开启 IO 口复用时钟,设置 IO 口与中断线的映射关系。 STM32 的 IO 口与中断线的对应关系需要配置外部中断配置寄存器 EXTICR,这样我们要先开启复用时钟,然后配置 IO 口与中断线的对应关系。才能把外部中断与中断线连接起来。 3)开启与该 IO 口相对的线上中断/事件,设置触发条件。 这一步,我们要配置中断产生的条件, STM32 可以配置成上升沿触发,下降沿触发,或者任意电平变化触发,但是不能配置成高电平触发和低电平触发。这里根据自己的实际情况来配置,同时要开启中断线上的中断。这里需要注意的是:如果使用外部中断,并设置该中断的 EMR位的话,会引起软件仿真不能跳到中断,而硬件上是可以的。而不设置 EMR,软件仿真就可以进入中断服务函数,并且硬件上也是可以的。建议不要配置 EMR 位。 4)配置中断分组( NVIC),并使能中断。 这一步,我们就是配置中断的分组,以及使能,对 STM32 的中断来说,只有配置了 NVIC的设置,并开启才能被执行,否则是不会执行到中断服务函数里面去的。 5)编写中断服务函数。 这是中断设置的最后一步,中断服务函数,是必不可少的,如果在代码里面开启了中断,但是没编写中断服务函数,就可能引起硬件错误,从而导致程序崩溃!所以在开启了某个中断后,一定要记得为该中断编写服务函数。在中断服务函数里面编写你要执行的中断后的操作。 //外部中断 0 服务程序 void EXTI0_IRQHandler(void) { delay_ms(10); //消抖 if(WK_UP==1) //WK_UP 按键 { LED0=!LED0;; } EXTI->PR=1<<0; //清除 LINE0 上的中断标志位 } //外部中断初始化程序 //初始化 PA0 为中断输入. void EXTIX_Init(void) { KEY_Init(); Ex_NVIC_Config(GPIO_A,0,RTIR); //上升沿触发 MY_NVIC_Init(2,3,EXTI0_IRQn,2); //抢占 2,子优先级 3,组 2 } int main(void) { Stm32_Clock_Init(9); //系统时钟设置 delay_init(72); //延时初始化 LED_Init(); //初始化与 LED 连接的硬件接口 EXTIX_Init(); //初始化外部中断输入 LED0=0; //先点亮红灯 while(1) { printf("OKrn"); delay_ms(1000); } } //实验结果就是按下KEY0控制DS0开关,CPU不断地执行主函数里的while(1)中程序,每隔一秒种打印一个OK, //当有外部中断时,进入反转LED的中断服务程序。执行完之后继续执行主函数里的死循环。 |
|
|
|
只有小组成员才能发言,加入小组>>
2517 浏览 0 评论
1098浏览 2评论
709浏览 1评论
460浏览 0评论
201浏览 0评论
345浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-26 20:34 , Processed in 1.317698 second(s), Total 82, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号