第5章 中断服务程序设计
- 格式:doc
- 大小:350.00 KB
- 文档页数:13
第5章MCS-51单片机的中断系统【例5-1】设允许外部中断0和串行口中断,禁止其它中断源的中断申请。
试根据假设条件设置IE的相应值。
解:⑴用位操作指令来编写如下程序段:SETB EX0 ;允许外部中断0中断SETB ES ;允许串行口中断CLR EX1 ;禁止外部中断1中断CLR ET0 ;禁止定时器/计数器T0中断CLR ET1 ;禁止定时器/计数器T1中断SETB EA ;CPU开中断⑵用字节操作指令来编写:MOV IE, #91H【例5-2】设置中断优先级控制寄存器IP的初始值,使得8031的2个外中断请求为高优先级,其它中断请求为低优先级。
解:⑴用位操作指令SETB PX0;2个外中断为高优先级SETB PX1CLR PS ;串行口、2个定时器为低优先级中断CLR PT0CLR PT1⑵用字节操作指令MOV IP,#05H【例5-3】假设允许外部中断0中断,并设定它为高级中断,其它中断源为低级中断,采用跳沿触发方式。
在主程序中可编写如下程序段:SETB E A ;EA位置“1”,CPU开中断SETB E X0 ;EX0位置“1”,允许外部中断0产生中断SETB P X0 ;PX0位置“1”,外部中断0为高级中断SETB I T0 ;IT0位置“1”,外部中断0为跳沿触发方式【例5-4】根据图5-9的中断服务程序流程,编写出中断服务程序。
假设现场保护只需要将PSW寄存器和累加器A的内容压人堆栈中保护起来。
解一个典型的中断服务程序如下:INT: CLR E A ;CPU关中断PUSH PSW ;现场保护PUSH ASETB E A ;CPU开中断中断处理程序段CLR E A ;CPU关中断POP A ;现场恢复POP PSWSETB E A ; CPU开中断RETI ;中断返回,恢复断点上述程序有几点需要说明的是:⑴本例的现场保护假设仅仅涉及到PSW和A的内容,如果还有其它的需要保护的内容,只需要在相应的位置再加几条PUSH和POP指令即可。
一、介绍嵌入式系统中设计中断服务程序的背景及重要性嵌入式系统是一种特殊的计算机系统,它通常被用于嵌入在其他设备中,用来控制设备的运行和功能。
在嵌入式系统中,中断服务程序是一个非常重要的组成部分。
中断是一种机制,可以在系统执行某个任务的过程中,暂时中止当前任务的执行,转而去执行另一个任务。
中断服务程序是为了响应中断事件而设计的程序,它负责在中断发生时保存当前状态、执行相应的处理程序、然后恢复之前的状态,让被中断的任务能够继续执行。
二、中断服务程序的设计原则在设计嵌入式系统中的中断服务程序时,有一些基本的原则需要遵循,以保证系统的稳定性和可靠性。
1. 可重入性中断服务程序必须是可重入的。
这意味着这个程序可以在其中断的情况下被再次调用,而不会导致不可预测的错误。
这是因为在中断处理过程中,有可能会再次收到同样的中断信号。
如果中断服务程序不是可重入的,那么当它正在执行时再次被调用,就会发生错误。
2. 快速响应中断服务程序必须能够迅速响应中断事件。
在某些情况下,中断的响应时间对系统的性能和稳定性有很大影响。
设计中断服务程序时需要尽量减少其执行时间,以确保系统能够及时处理中断事件。
3. 最小化对全局变量的使用中断服务程序应尽量避免使用全局变量。
这是因为在中断服务程序执行过程中,有可能会发生并发访问全局变量的情况,从而导致数据一致性问题。
为了避免这种情况,可以在中断服务程序中使用局部变量或者禁止中断的方式来保护全局变量。
4. 合理的优先级在设计中断服务程序时,还需要考虑中断的优先级。
不同的中断事件可能有不同的优先级,需要根据实际情况来进行合理的设置。
这样可以确保系统能够在不同的中断事件发生时能够按照一定的顺序来处理。
5. 状态保存和恢复在中断服务程序中,需要及时保存当前任务的状态,以便在处理完中断事件后能够恢复到之前的状态并继续执行。
这也是中断服务程序的一个重要功能,需要在设计中充分考虑。
6. 可靠性和稳定性在设计中断服务程序时,需要考虑系统的可靠性和稳定性。
第五章 中断系统5. 1 输入/输出数据的传输控制方式一、输入/输出的一般概念1.引言输入/输出是微机系统与外部设备进行信息交换的过程。
输入/输出设备称为外部设备,与存储器相比,外部设备有其本身的特点,存储器较为标准,而外部设备则比较复杂,性能的离散性比较大,不同的外部设备,其结构方式不同,有机械式、电动式、电子式等;输入/输出的信号类型也不相同,有数字信号,也有模拟信号;有电信号,也有非电信号;输入/输出信息的速率也相差很大。
因此,CPU与外部设备之间的信息交换技术比较复杂。
CPU与外设之间的信息交换,是通过它们之间接口电路中的I/O端口来进行的,由于同一个外部设备与CPU之间所要传送的信息类型不同,方向不同,作用也不一样(例如数据信息、状态信息、控制信息、输入/输出等),所以接口电路中可以设置多个端口来分别处理这些不同的信息。
2.输入/输出端口的寻址方式微机系统采用总线结构形式,即通过一组总线来连接组成系统的各个功能部件(包括CPU、内存、I/O端口),CPU、内存、I/O端口之间的信息交换都是通过总线来进行的,如何区分不同的内存单元和I/O 端口,是输入/输出寻址方式所要讨论解决的问题。
根据微机系统的不同,输入/输出的寻址方式通常有两种形式:(1).存储器对应的输入、输出寻址方式这种方式又称为存储器统一编址寻址方式或存储器映象寻址方式。
方法:把外设的一个端口与存储器的一个单元作同等对待,每一个I/O 端口都有一个确定的端口地址,CPU与I/O端口之间的信息交换,与存储单元的读写过程一样,内存单元与I/O端口的不同,只在于它们具有不同的的地址。
优点:①CPU对I/O端口的读/写操作可以使用全部存储器的读/写操作指令,也可以用对存储器的不同寻址方式来对I/O端口中的信息,直接进行算术、逻辑运算及循环、移位等操作。
②内存与外设地址的分配,可以用统一的分布图。
③不需要专门的输入、输出操作指令。
缺点:1 内存与I/O端口统一编址时,在地址总线根数一定的情况下,使系统中实际可以直2 接寻址的内存单元数减少。
单片机中断程序设计中断是单片机控制器(MCU)中重要的功能之一,它是单片机与外部硬件设备通信处理的一种方式。
在中断的处理中,当发生某一事件时,单片机立即停止正在运行的程序,然后调用该事件对应的中断服务程序。
当该中断服务程序执行完毕后,重新回到原来被中断的程序中继续运行。
在单片机的中断程序设计中,中断向量表是一个重要的概念,在这篇文章中我们将介绍单片机中断程序设计的基本流程和一些注意事项。
一、中断服务程序的编写在单片机中断程序设计中,中断服务程序通常在程序中单独定义。
中断服务程序的名称是由中断号决定的,例如INT0中断对应的中断服务程序的名称为INT0_ISR。
它的基本格式如下:```void interrupt ISR名称(void){中断服务程序的代码语句}```中断服务程序通常会进行一些操作,以处理中断触发时的事件。
例如,当从串口接收到数据时,中断服务程序需要读取接收缓冲区中的数据并处理。
二、中断优先级分配当多个中断同时发生时,如何处理中断事件是一个需要考虑的问题。
单片机中可以通过设置中断优先级实现多个中断间的优先级分配。
当多个中断发生时,单片机会按中断优先级从高到低的顺序进行处理。
在实际应用中,需要根据具体的应用需求进行中断优先级的分配设置。
三、中断向量表中断向量表是一个非常重要的概念,在单片机中,每一个中断都与中断向量表中的一个向量地址相对应。
当中断事件发生时,MCU会自动跳转到对应的向量地址,从而执行相应的中断服务程序。
中断向量表通常存储在单片机的程序存储器中,其结构体如下:```//中断向量表结构体struct interrupt_Vector_Table{void interrupt (*int0_isr)();void interrupt (*int1_isr)();void interrupt (*int2_isr)();//...其他中断服务程序的指针};//中断向量表在程序存储器中的地址#define INTERRUPT_VECTOR_ADDRESS 0x0000//中断向量表变量定义interrupt_Vector_Table __at (INTERRUPT_VECTOR_ADDRESS)interrupt_Vector_Table_content;```需要注意的是,有些单片机包含了一个默认的中断向量表,其中会包括一些通用的中断服务程序。
第5章中断服务程序设计中断服务程序(ISR)是嵌入式应用系统获取各种事件的基本手段,而“事件”是实时性问题的讨论基础和时间计算的起点。
ISR的设计质量直接影响到系统的实时性指标和操作系统的工作效率。
只要没有关中断,中断服务程序可以中断任何任务的运行,可将中断服务程序可成比最高优先级(0级)还高的“任务”。
5.1中断优先级安排原则中断源是系统及时获取异步事件的主要手段,其优先级安排原则如下:●紧迫性:触发中断的事件允许耽误的时间越短,设定的中断优先级就越高。
●关键性:触发中断的事件越关键(重要),设定的中断优先级就越高。
●频繁性:触发中断的事件发生越频繁,设定的中断优先级就越高。
●快捷性:ISR处理越快捷(耗时短),设定的中断优先级就越高。
中断服务程的功能应尽量简单,只要将获取的异步事件通信给关联任务,后续处理由关联任务完成。
5.2不受操作系统管理的中断服务程序正常情况下,ISR应受操作系统的管理,因很多任务是靠ISR触发的。
但在两种情况下ISR不受操作系统管理:①没有必要;②操作系统没有对该ISR进行管理。
实时操作系统uC/OS-Ⅱ移植到ARM7体系的CPU上时,没有对FIQ进行处理,即FIQ 是不受操作系统管理的。
选用FIQ来响应实时性要求最高的高速采样操作是一个有效措施,保护现场的工作量很小(FIQ专有的8个寄存器不需要保护)。
在工程模板的系统启动文件Startup.s中,已经把汇编代码部分处理好,用户只需要用C 语言编写快速中断服务函数FIQ_Exception()即可,不需考虑保护现场和恢复现场的问题。
程序:Startup.s中队FIQ的处理Reset ;异常向量表LDR PC,ResetAddr ;跳转到复位入口地址LDR PC,UndefinedAddrLDR PC,SWI_Addr ;跳转到软件中断入口地址LDR PC,PrefetchAddrLDR PC,DataAbortAddrDCD 0xb9205f80LDR PC,[PC,#-0xff0] ;跳转到向量中断入口地址(向量中断控制器)LDR PC,FIQ_Addr ;跳转到快速中断入口地址ResetAddr DCD ResetInitUndefinedAddr DCD UndefinedSWI_Addr DCD SoftwareInterruptPrefetchAddr DCD PrefetchAbortNouse DCD 0IRQ_Addr DCD 0FIQ_Addr DCD FIQ_Handler ;快速中断服务程序入口地址FIQ_Handler ;快速中断服务程序STMFD SP!,{R0-R3,LR} ;保护现场HL FIQ_Exception ;调用C语言编写的快速中断服务函数LDMFD SP!{R0-R3,LR} ;恢复现场SUBS PC,LR,#4 ;中断返回由于没有操作系统介入,FIQ的ISR无法与关联任务进行通信,所获取的信息不能及时得到关联任务的处理,故只能以原始形式保存在一个缓冲区内,等待以后进行离线处理。
典型的例子是高速数据采集系统。
由于使用FIQ方式进行采样,其ISR不受操作系统管理,所以只能用“使能中断源”和“关闭中断源”来控制采样过程。
这是需要设置一个采样任务来控制采样过程。
其代码结构如下程序。
程序:高速采样任务函数结构void TaskSamp(void *pdata) //高速采样任务函数{进行相关设置;while(1) //无限循环{等待启动信号’进行准备工作;使能采样中断;等待结束信号;停止采样中断;数据预处理;输出采样数据块;}}实验:将定时器1设置为FIQ,在FIQ中进行快速采样。
采样过程由采样任务进行控制,而采样任务本身由操作者通过按键进行控制,每次采样过程进行200次连续采样,采样周期为50us。
高速采样的程序流程图如图5-1所示,程序代码如下。
(a)按键任务(b)采样任务(c)FIQ图5-1 高速采样的程序流程图程序:高速采样示例#include “config.h”//文件config.h包含了includes.h和一些系统配置文件#define KEY (1<<20) //P0.20为按键控制I/0#define TaskStk 100 //定义任务堆栈长度OS_STK TaskKeyStk[TaskStk] //定义按键任务的堆栈OS_STK TaskSampStk[TaskStk]; //定义采样任务的堆栈void TaskKey(void *pdata); //声明按键任务,因为这段代码在创建它的主函数//后面void TaskSamp(void *pdata); //声明采样任务,因为这段代码在创建它的按键任务//函数的后面INT16U Samp[200]; //保存采样结果的数组INT8U count=0; //采样次数计数器void Show(INT16U *a,INT16U n) //显示波形函数{INT16U I;GUI_ClearSCR(); //清屏for(i=0;i<n;i++) //显示波形GUI_Point(i,240-a[i]*/300/3000,RED); //高度240点相当于3000mV}int main(void) //将main()函数设置为整型是为了防止编译警告{OSInit();OSTaskCreat(TaskKey,(void *)0,&TaskKeyStk[TaskStk-1],4); //创建按键任务OSStart();return 0;}void TaskKey(void *pdata) //按键任务{pdata=pdata;TargetInit(); //系统电路初始化GUI_Initalize(); //初始化LCD(液晶屏)PINSEL1=0x00400000; //设置P0.27连接到AINO//进行ADC模块设置,其中x<<n表示第n位设置为x(若x位超过一位,则向高位顺延)ADCR=(1<<0) | //SEL=1,选择通道0((Fpclk/1000000-1)<<8) | //即转换时钟为1Mhz(0<<16) | //BURST=0.软件控制转换操作(0<<17) | //CLKS=0,使用11clock转换(1<<21) | //PDN=1,正常工作模式(非掉电转换模式)(0<<22) | //TEST1:0=00,正常工作模式(非测试模式)(1<<24) | //START=1,直接启动ADC转换(0<<27) | //EDGE=0,引脚下降沿触发转换T1IR=0xffffffff; //复位中断源T1TC=0x00; //初始化定时器1T1PR=0x00; //设置定时器1的分频器(不分频)T1TCR=0x01; //使能定时器1T1MCR=0x03; //匹配时产生中断并复位定时器1T1MR0=Fpclk/20000; //定时时间为50usVICIntSelect=1<<5; //T1设置为快速中断while(1){OSTimeDly(2); //延时if((IO0PIN&KEY)!=0) continue; //未按键,再延时else //按下按键{while(IO0PIN&KEY) == 0) //等待按键释放{IO0SET=KEY;OSTimerDly(1); //延时}OSTaskCreate(TaskSamp,(void *)0,&TaskSamp[TaskStk-1],2); //创建采样任务}}}void TaskSamp(void *pdata) //高速采样任务{INT8U i; //临时变量INT32U Temp; //临时变量pdata=pdata;count=0; //初始化采样计数器VICIntEnable=1<<5; //打开定时器1的FIQ,开始采样while(1); //等待采样结束{OS_ENTER_CRITICAL(); //关中断i=count; //查询当前完成的采样次数OS_EXIT_CRITICAL(); //开中断if (i>=200) break; //完成预定采样次数,结束查询OSTimeDly(1); //未完成预定采样次数,延时一个时钟节拍继续//查询}for(i=0;i<200;i++) //将采样数据进行预处理,使数据以mV为单位{Temp=3000*Samp[i]; //参考电压为3000mVSamp[i]=(INT16U) (TEMP>>16);}Show(Samp,200); //显示采样信号的波形OSTaskDel(OS_PRIO_SELF); //删除自己}void FIQ_Exception(void) //快速中断服务函数{INT32U ADC_Data;T1IR=0x01; //清除中断源VICVectAddr=0; //通知中断控制器ADC_Data=ADDR; //通过读取ADC结果清除DONE标志位ADCR=(ADCR&0Xffffff00)|0x01|(1<<24); //切换通道并进行第一次转换while(ADDR&0x80000000)==0); //等待转换结束ADCR=ADCR|(1<<24); //再次启动转换while(ADDR&0x80000000)==0); //等待转换结束Samp[count]=(INT16U)(ADDR&0x0000FFFF); //读取并保存转换结果count++; //调整采样计数器if(count==200) VICIntEnClr=1<<5; //完成采样次数,关闭FIQ5.3 受操作系统管理的中断服务程序中断服务程序的结构受实时操作系统管理的ISR与不受实时操作系统管理的ISR有很大区别,体现在以下3个阶段。
①入中断:除了保护现场外,还需要调用“进入中断”服务函数。
②行功能代码:完成ISR的实质功能的代码外,还包含了对系统通信服务函数的调用,使关联任务得到同步信号或Ⅱ数据,从而进入就绪状态,但在ISR中不容许调用延时函数和可能被挂起系统服务函数。
③退出中断:执行“退出中断”流程。
必须将ISR中与具体功能无关的代码剥离出来,作为实时操作系统内核的一部分,提供给实时操作系统的用户。
实时操作系统uc/OS-Ⅱ移植到ARM7体系的CPU上时,这部分代码用一个汇编宏实现(移植文件IRQ.inc),并提供C语言接口,用户只需要用C语言编写ISR的功能代码即可。