嵌入式-中断实验

合集下载

嵌入式中断实验报告心得

嵌入式中断实验报告心得

一、实验背景随着物联网、智能制造等领域的快速发展,嵌入式系统在各个行业中扮演着越来越重要的角色。

中断技术作为嵌入式系统的重要组成部分,对于提高系统的实时性、可靠性和响应速度具有重要意义。

为了更好地掌握中断技术,我进行了嵌入式中断实验,以下是我对实验的心得体会。

二、实验目的1. 理解中断的概念、作用及中断处理流程;2. 掌握嵌入式系统中断的配置方法;3. 学会编写中断服务程序;4. 通过实验验证中断技术的应用效果。

三、实验内容1. 硬件环境:嵌入式开发板、仿真器、连接线等;2. 软件环境:嵌入式操作系统、集成开发环境、仿真器驱动程序等;3. 实验步骤:(1)搭建实验环境,包括硬件连接和软件配置;(2)配置中断源,如GPIO、定时器等;(3)编写中断服务程序,实现中断响应和处理;(4)通过仿真器观察实验效果,验证中断技术。

四、实验心得1. 理解中断原理在实验过程中,我首先学习了中断的基本概念和作用。

中断是指当外部事件发生时,系统暂停当前执行的任务,转而执行中断服务程序,处理外部事件。

通过实验,我明白了中断处理流程,包括中断请求、中断响应、中断处理和中断返回等环节。

2. 中断配置方法在实验中,我学习了如何配置中断源。

以GPIO为例,首先需要设置GPIO引脚为中断模式,然后配置中断触发方式(上升沿、下降沿或双边沿触发),最后设置中断优先级。

通过实验,我掌握了中断配置方法,为后续应用中断技术打下了基础。

3. 编写中断服务程序中断服务程序是中断处理的核心,我通过实验学会了编写中断服务程序。

在编写过程中,需要注意以下几点:(1)保护现场:在中断服务程序开始执行前,需要保存当前CPU状态,如寄存器值等;(2)处理中断:根据中断类型,执行相应的处理逻辑;(3)恢复现场:在中断服务程序执行完毕后,需要恢复CPU状态,以便继续执行被中断的任务。

4. 实验效果验证通过仿真器观察实验效果,我发现中断技术能够有效地提高系统的响应速度和实时性。

嵌入式- 按键中断实验

嵌入式- 按键中断实验

按键中断实验实验目的:1掌握IO口的使用2掌握中断处理程序编写3掌握按键中断的使用实验器材:Sinosys-EA2440实验箱PC机实验原理:在SinoSys-EA2440a中,已经将EINT0、EINT2、EINT19、EINT11作为外部中断源和开发板上位号为SW1、SW2、SW3、SW4的这四个小按键相连,中断按钮的连接图如图1.1:1.1中断按钮结构电路在SinoSys-EA2440a 中,已将EINT0、EINT2、EINT19、EINT11 作为外部中断源和开发板上位号为SW1、SW2、SW3、SW4 的这四个小按键相连,其中,EINT0、EINT2、EINT11、EINT19 分别和GPF0、GPF2、GPG3、GPG11 复用,当GPFCON[5:4]=10、GPFCON[1:0]=10、GPGCON[7:6]=10、GPGCON[23:22]=10 时,I/O 为中断方式。

通过寄存器的控制,可以达到开启中断和控制中断的目的。

实验总结:将4个按键端口设置成EINT0、EINT2、EINT11、EINT19模式。

rGPGCON = rGPGCON & (~((3<<22)|(3<<6))) | ((2<<22)|(2<<6)) ;rGPFCON = rGPFCON & (~((3<<4)|(3<<0))) | ((2<<4)|(2<<0)) ;通过EXTINT寄存器对外部中断触发方式进行设置,这里设置下降沿触发。

rEXTINT0 &= ~(6|(6<<8));rEXTINT0 |= (0|(0<<8));// EINT0、EINT2rEXTINT1 &= ~(7<<12);rEXTINT1 |= (0<<12); // EINT11rEXTINT2 &= ~(0xf<<12);rEXTINT2 |= (0<<12); // EINT19对外部中断挂起寄存器清零,对外部中断屏蔽寄存器时能,同时设置中断服务程序的地址,将中断挂起寄存器清零,开启中断。

嵌入式系统实验2中断实验

嵌入式系统实验2中断实验

中南大学嵌入式系统实验(二)中断实验学院:**************专业班级:*********姓名:*************学号:*************中断实验一.实验目的1.熟悉arm开发板中断原理。

并产生中断。

2.了解快速中断和普通中断。

编写嵌套中断实验。

二.实验器材PC机一台,周立功开发板一块三.实验原理EasyARM2103开发板提供了4个绿色发光二极管用作显示,电路如图1.1所示。

显示电路采用了灌电流的方式来驱动发光二极管,由于微控制器LPC2103 I/O口提供的灌电流大于其拉电流,采用此驱动方式可以保证二极管发光的亮度。

1.1Led电路原理四. 实验原理ARM体系的CPU有7种工作模式,可以通过软件来进行模式切换,或者发生各类中断、异常进行相应模式。

CPU可以识别两种类型中断,正常中断(IRQ)和快速响应中断(FIQ)状态寄存器的PSR中F和R位决定是中断的启闭。

为了使能中断,必须将PSR中F或R位清零,并且中断屏蔽寄存器相应位也要清零。

ARM中断分为子中断源和一般中断源,子中断源多了两个寄存器SUBRCPN(标识子中断源是否发生)INTSUBMSK(屏蔽子中断源)。

ARM中断发生过程如下:1.如果为子中断源,则SUBSRCPND寄存器相应位置1,然后根据子中断源屏蔽寄存器(INTSUBMSK)的设置来判断该中断是否被屏蔽,如未屏蔽,则在SRCPND寄存器相应位置1。

2.如果为非子中断则直接在SRCPND寄存器相应位置1。

3.如果INTMOD寄存器中该中断被设置为FIQ快速中断(相应位置1),即该中断立即执行。

如不是,则判断INTMSK寄存器中该中断是否被屏蔽,如未屏蔽,则进入中断优先仲裁器进行中断优先设置(PRIORITY寄存器)经过中断优先仲裁后,最高优先级的中断在INTPND寄存器中相应位置1(同一时间,此寄存器只有一位置1),INTOFFSET寄存器值用来表示INTPND寄存器置1位(即INTPND 寄存器中位[x]为1时,INTOFFSET寄存器值为x,可以用它确定是什么中断。

嵌入式技术及应用实验中断实验报告

嵌入式技术及应用实验中断实验报告

实验步骤与结果分析1、建立工程1)、在工程文件中包含如下文件(int、doc、user、lib、start)2)、选择STM32F103VB芯片3)、分别添加如下文件2、运行过程(1) 使用Keil uVision3 通过ULINK仿真器连接EduKit-M3实验平台,打开实验例程NVIC_test子目录下的NVIC.Uv2例程,编译链接工程;(2) 点击MDK 的Debug菜单,选择Start/Stop Debug Session项或Ctrl+F5键,远程连接EduKit-M3实验平台并下载调试代码到目标系统的RAM中;(3) 程序正常启动运行后,会有以下结果:当第一次发生EXTI9 中断后(按下EduKit-M3实验平台上Key按钮),SysTick 中断的优先级比EXTI0中断优先级高。

因此当EXTI0中断发生时(按下Wakeup按钮),将先执行主要程序代码分析/* Configure one bit for preemption priority */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);主从优先级的选择Group_1,有先占优先级1位,从优先级3位//配置一个比特为抢占优先级/* Enable the EXTI0 Interrupt */ //使能EXTI0中断NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQChannel;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PreemptionPriorityValue;主优先级的选择PreemptionPriorityValueNVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//从优先级等于0.NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);/* Enable the EXTI9_5 Interrupt */ //使能EXTI9_5中断NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//EXTI9_5主优先级的选择等于0NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//EXTI9_5主优先级的选择等于0NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);/* Configure the SysTick Handler Priority: Preemption priority and sub priority */ //配置SysTick处理程序优先级:抢占优先级和子优先级NVIC_SystemHandlerPriorityConfig(SystemHandler_SysTick, !PreemptionPriorityValue, 0);while (1){if(PreemptionOccured != FALSE)//当PreemptionOccured != FALSE)抢占发生{GPIO_WriteBit(GPIOC, GPIO_Pin_6, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_6)));Delay(0x5FFFF);GPIO_WriteBit(GPIOC, GPIO_Pin_7, (BitAction)(1 -GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_7)));Delay(0x5FFFF);GPIO_WriteBit(GPIOC, GPIO_Pin_8, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_8)));Delay(0x5FFFF);GPIO_WriteBit(GPIOC, GPIO_Pin_9, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_9)));Delay(0x5FFFF);}}void GPIO_Configuration(void){/* Configure PC6, PC7, PC8 and PC9 as output push-pull */ 使能为推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //使能其速度为50MHz GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //使能为推挽输出GPIO_Init(GPIOC, &GPIO_InitStructure);/* Configure GPIOA Pin0 as input floating */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 使能为浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);/* Configure GPIOB Pin9 as input floating */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 使能为推挽输出入GPIO_Init(GPIOB, &GPIO_InitStructure);}GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);/* Configure EXTI Line0 to generate an interrupt on falling edge */ 配置EXTI Line0产生一个中断在下降沿EXTI_InitStructure.EXTI_Line = EXTI_Line0;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);(写不完时,可调整表结构。

嵌入式-中断实验

嵌入式-中断实验

嵌入式-中断实验
嵌入式中断实验是一种用来测试和学习嵌入式系统中断功能的实验。

中断是嵌入式系统中常用的一种机制,用于处理紧急事件或高优先级任务。

通过中断,系统可以立即响应外部事件,中断当前正在执行的任务,执行与中断事件相关的代码,然后返回到原来的任务中继续执行。

在进行中断实验时,通常需要以下步骤:
1. 确定中断源:确定要模拟的中断事件,比如外部输入的触发事件、定时器到达时间等。

2. 配置中断控制器:根据硬件平台和实验要求,配置中断控制器的相应寄存器,使其能够正确地处理中断信号。

3. 编写中断服务程序(ISR):定义一个中断服务程序,用于
处理中断事件。

ISR应当对事件进行必要的处理,然后返回到
原来的任务中。

4. 测试和调试:连接硬件平台,运行实验程序,并进行测试和调试,确保中断功能正常工作。

5. 扩展和优化:根据需要,可以进一步扩展和优化中断功能,比如增加多个中断源,实现优先级控制,提高系统响应速度等。

通过嵌入式中断实验,可以深入了解中断机制的工作原理和应用方法,提高对嵌入式系统的理解和能力。

嵌入式实验4(中断处理程序设计)

嵌入式实验4(中断处理程序设计)

北华航天工业学院《嵌入式系统基础》课程实验报告实验名称编号:实验4 中断处理程序设计作者所在系部:计算机科学与工程系作者所在专业:计算机科学与技术作者所在班级:B09513作者学号:20094051329作者姓名:康建云教师姓名:李建义一、实验内容1.本实验涵盖实验手册《ARM嵌入式系统设计及接口编程实验教程》中的实验9 中断处理程序设计。

2.修改程序,使得当四个中断源中断时分别调用实验二跑马灯实验的实验内容第二项中编写的一个函数,即不同中断将控制四个跑马灯的闪烁顺序。

二、实验要求1.了解ARM处理器中断处理过程。

2.掌握S3C2440下进行中断编程的方法,包括中断设置、中断服务子程序的编写。

3.理解实验手册中的实验9的实验程序。

4.编程实现实验内容中第2项任务。

5.撰写实验报告描述实现上述个要求的情况。

三、实验思路在SinoSys-M3中,已经将EINT0、EINT1、EINT2、EINT19、EINT11作为外部中断源和开发板上位号为SW1、SW2、SW3、SW4的这四个小按键相连。

在实验的过程中,在运行之后,按下开关板上这四个按钮,将触发处理器的四个外部中断,处理器转而去执行相应的中断服务程序,在中断服务程序中,向串口打印中断信息,并输出到开发主机的串口终端工具上。

因为key=1、key=3、key=5、key=7分别对应SW1、SW2、SW3、SW4四个按钮。

所以改程序时只需控制key值在不同值下的灯亮情况即可,修改程序实现跑马灯不同亮的次序并循环五次,所修改的程序如下:四、实验程序static void __irq Key_ISR(void){ int i; U8 key;if(rINTPND==BIT_EINT8_23) {ClearPending(BIT_EINT8_23);if(rEINTPEND&(1<<11)){ Uart_Printf("eint11\n");rEINTPEND |= 1<< 11; }if(rEINTPEND&(1<<19)) {Uart_Printf("eint19\n"); rEINTPEND |= 1<< 19; }}if(rINTPND==BIT_EINT0){//Uart_Printf("eint0\n");ClearPending(BIT_EINT0); } if(rINTPND==BIT_EINT2) {Uart_Printf("eint2\n");ClearPending(BIT_EINT2); }key=Key_Scan();if(key==1)//从左到右依次亮{ for(i=0;i<5;i++){ rGPFDAT=rGPFD AT&0x0F|0xE0;Delay(1000);rGPFDAT=rGPFDAT&0x0F|0xD0;Delay(1000);rGPFDAT=rGPFDAT&0x0F|0xB0;Delay(1000);rGPFDAT=rGPFDAT&0x0F|0x70;Delay(2000); }}if(key==3) //从右到左依次亮{ for(i=0;i<5;i++){ rGPFDAT=rGPFD AT&0x0F|0x70; Delay(1000);rGPFDAT=rGPFDAT&0x0F|0xB0; Delay(1000);rGPFDAT=rGPFDAT&0x0F|0xD0;Delay(1000);rGPFDAT=rGPFDAT&0x0F|0xE0;Delay(2000); }}if(key==5) //从左边两个到右边两个到两边的两个到中间两个依次亮{ for(i=0;i<5;i++){ rGPFDAT=rGPFD AT&0x0F|0xC0; Delay(1000);rGPFDAT=rGPFDAT&0x0F|0x30; Delay(1000);rGPFDAT=rGPFDAT&0x0F|0x90; Delay(1000);rGPFDAT=rGPFDAT&0x0F|0x60; Delay(2000); }}if(key==7) //从中间两个到两边两个到右边的两个到左边两个依次亮{ for(i=0;i<5;i++){rGPFDAT=rGPFDAT&0x0F|0x60; Delay(1000);rGPFDAT=rGPFDAT&0x0F|0x90; Delay(1000);rGPFDAT=rGPFDAT&0x0F|0x30; Delay(1000);rGPFDAT=rGPFDAT&0x0F|0xC0; Delay(2000); }}五、实验结果及实验问题分析1.实验结果更改代码后,分别按下sw1、sw2、sw3、sw4按钮,主函数调用keyscan.c文件,继而调用中断服务子程序,根据相应key==1、key==3、key==5、key==7,按实验要求分别实现了使四个灯的闪烁顺序依次为左1灯亮→左2灯亮-→左3灯亮-→左4个灯亮-→四个灯全灭的中断控制;左4灯亮→左3灯亮-→左2灯亮-→左1个灯亮-→四个灯全灭;左1、2灯亮→左3、4个灯亮-→两边两个灯亮-→中间两灯亮-→四个灯全灭;左3、4灯亮-→左1、2个灯亮-→中间两个灯亮-→两边两个灯亮-→四个灯全灭。

嵌入式中断实验

嵌入式中断实验

实验2.3 外部中断实验一、实验目的如何捕获一个外部中断和 CC2530 捕获外部中断后的处理流程。

在 EBDCC2530 节点板上运行外部中断程序。

二、实验环境硬件:PC 机,EBDCC2530 节点板,USB 接口仿真器。

软件:Windows98/2000/NT/XP,IAR 集成开发环境。

三、实验原理EBDCC2530 节点板上有两个按键:按键 S1、按键 S2。

我们通过查看电路图可以得知,选通按键 S1 的按键是 P2.0,选通按键 S2 的按键式P0.6。

我们以 S2 所对应的 P0.6 引脚所用到的控制寄存器为例,仔细说明控制寄存器中每一位所代表的意义。

其他控制寄存器所代表的意义请查看 CC2530 数据手册。

P0IEN:各个控制口的中断使能,0 为中断禁止,1 为中断使能。

D7 D6 D5 D4 D3 D2 D1 D0 P0.7 P0.6 P0.5 P0.4 P0.3 P0.2 P0.1 P0.0P0INP:设置各个 I/O 口的输入模式,0 为上拉/下拉,1 为三态模式。

D7 D6 D5 D4 D3 D2 D1 D0P0.7模式 P0.6模式P0.5模式P0.4模式P0.3模式P0.2模式P0.1模式P0.0模式PICTL:D0~D3 设置各个端口的中断触发方式,0 为上升沿触发,1 为下降沿触发。

D7 控制 I/O引脚在输出模式下的驱动能力。

选择输出驱动能力增强来补偿引脚 DVDD 的低 I/O 电压,确保在较低的电压下的驱动能力和较高电压下相同。

0 为最小驱动能力增强。

1 为最大驱动能力增强。

D7 D6 D5 D4 D3 D2 D1 D0I/O 驱动能力未用未用未用 P2_0~P2_4P1_4~P1_7P1_0~P1_3P0_0~P0_7IEN1:中断使能 1,0 为中断禁止,1 为中断使能。

D7 D6 D5 D4 D3 D2 D1 D0未用未用端口0 定时器4 定时器3定时器2定时器1DMA传输P0IFG :中断状态标志寄存器,当输入端口有中断请求时,相应的标志位将置 1。

嵌入式- 定时器中断实验

嵌入式- 定时器中断实验

定时器中断实验实验目的:1掌握IO口的使用2掌握中断处理程序编写3掌握定时器的使用实验器材:Sinosys-EA2440实验箱PC机实验原理:S3C2440A 有5 个16 位定时器。

其中定时器0、1、2 和3 具有脉宽调制(PWM)功能。

定时器4 是一个无输出引脚的内部定时器。

定时器0还包含用于大电流驱动的死区发生器。

定时器0 和1 共用一个8位预分频器,定时器2、3 和4 共用另外的8 位预分频器。

每个定时器都有一个可以生成5 种不同分频信号(1/2,1/4,1/8,1/16 和TCLK)的时钟分频器。

每个定时器模块从相应8 位预分频器得到时钟的时钟分频器中得到其自己的时钟信号。

8 位预分频器是可编程的,并且按存储在TCFG0 和TCFG1 寄存器中的加载值来分频PCLK。

定时计数缓冲寄存器(TCNTBn)包含了一个当使能了定时器时的被加载到递减计数器中的初始值。

定时比较缓冲寄存器(TCMPBn)包含了一个被加载到比较寄存器中的与递减计数器相比较的初始值。

这种TCNTBn 和TCMPBn 的双缓冲特征保证了改变频率和占空比时定时器产生稳定的输出。

每个定时器有它自己的由定时器时钟驱动的16 位递减计数器。

当递减计数器到达零时,产生定时器中断请求通知CPU 定时器操作已经完成。

当定时器计数器到达零时,相应的TCNTBn 的值将自动被加载到递减计数器以继续下一次操作。

然而,如果定时器停止了,例如,在定时器运行模式期间清除TCONn 的定时器使能位,TCNTBn 的值将不会被重新加载到计数器中。

TCMPBn 的值是用于脉宽调制(PWM)。

当递减计数器的值与定时器控制逻辑中的比较寄存器的值相匹配时定时器控制逻辑改变输出电平。

因此,比较寄存器决定PWM 输出的开启时间(或关闭时间)。

如图1.1:1.1定时器结构图实验总结:打开Timer.c文件,可以看到,在Test_TimerInt 子函数中首先打开定时器中断,此函数由main主函数所调用。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验五中断控制实验(一)实验目的了解中断的作用;掌握嵌入式系统中断的处理流程;掌握ARM中断编程。

(二)实验设备计算机;ARM硬件仿真器;ARM开发板(三)实验硬件设置在做实验之前,先将开发板电源接好,将仿真器的USB连线与电脑相连,通电,然后按核心板的复位键。

(四)实验原理1. 中断的基本概念CPU与外设之间传输数据的控制方式通常有三种:查询方式、中断方式和DMA方式。

DMA 方式将在后续实验中说明。

查询方式的优点是硬件开销小,使用起来比较简单。

但在此方式下,CPU要不断地查询外设的状态,当外设未准备好时,CPU就只能循环等待,不能执行其它程序,这样就浪费了CPU的大量时间,降低了CPU的利用率。

为了解决这个矛盾,通常采用中断传送方式:即当CPU进行主程序操作时,外设的数据已存入输入端口的数据寄存器;或端口的数据输出寄存器已空,由外设通过接口电路向CPU发出中断请求信号,CPU在满足一定的条件下,暂停执行当前正在执行的主程序,转入执行相应能够进行输入/输出操作的子程序,待输入/输出操作执行完毕之后CPU再返回并继续执行原来被中断的主程序。

这样CPU就避免了把大量时间耗费在等待、查询状态信号的操作上,使其工作效率得以大大地提高。

能够向CPU发出中断请求的设备或事件称为中断源。

系统引入中断机制后,CPU与外设(甚至多个外设)处于“并行”工作状态,便于实现信息的实时处理和系统的故障处理。

中断方式的原理示意图如下所示。

图5-7 中断处理示意图1)中断响应中断源向CPU发出中断请求,若优先级别最高,CPU在满足一定的条件下,可以中断当前程序的运行,保护好被中断的主程序的断点及现场信息。

然后,根据中断源提供的信息,找到中断服务子程序的入口地址,转去执行新的程序段,这就是中断响应。

CPU响应中断是有条件的,如内部允许中断、中断未被屏蔽、当前指令执行完等。

2)中断服务子程序CPU响应中断以后,就会中止当前的程序,转去执行一个中断服务子程序,以完成为相应设备的服务。

中断服务子程序的一般结构如下图所示。

图5-8 中断服务子程序处理流程▼保护现场(由一系列的压栈指令完成)。

目的是为了保护那些与主程序中有冲突的寄存器,(如R0,R1,R2等),如果中断服务子程序中所使用的寄存器与主程序中所使用的寄存器等没有冲突的话,这一步骤可以省略。

▼中断处理,中断处理程序在检查到相应的中断源后,调用对应的中断处理程序完成。

▼恢复现场并返回(由一系列的出栈指令完成)。

是与保护现场对应的,但要注意数据恢复的次序,以免混乱。

由于中断服务子程序需要打断主程序的执行,因此其处理应该及时完成,较长时间的延时将导致系统性能严重下降。

(五)实验关键代码及使用的寄存器S3C44B0X的中断控制器包括5类寄存器:中断控制寄存器、中断状态寄存器、中断模式寄存器、中断屏蔽寄存器和中断清除寄存器。

1) 中断控制寄存器该控制寄存器是处理器总的中断控制,包括中断模式是矢量模式还是非矢量模式,是否使能IRQ模式的中断,是否使能FIQ模式的中断,具体说明如下:表5-3 中断控制寄存器2) 中断状态寄存器该寄存器用于检查中断来源,该寄存器是只读属性的。

表5-4 中断状态寄存器3) 中断模式寄存器用于设置相应中断的工作模式,是IRQ模式还是FIQ模式。

表5-5 中断模式寄存器4) 中断屏蔽寄存器表5-6 中断屏蔽寄存器5) 中断清除寄存器中断处理之后需要清除相应的标志位,中断清除寄存器说明如下:表5-7 中断清除寄存器4. 44B0中断处理S3C44B0X处理器的中断处理与其他CPU的处理模式基本上是一致的,只是由于它引入了几种不同的处理器模式,使中断处理变得更加容易。

其典型的步骤如下:1) 保存现场:当系统出现中断时,处理器首先要做的就是保存现场,这一过程包括:保存当前的PC值到lr中,保存当前的程序运行状态到spsr中。

值得注意的就是由于ARM7采用3级流水线结构,此时的PC值实际上等于当前指令地址加上8(ARM指令时),所以返回时还需要将保存的PC值减4;2) 模式切换:当处理器完成现场保护后,就进入中断模式,并将PC值置为一个固定的值0X00000018,这也就是IRQ模式的中断入口地址。

在中断模式下,有两个独立的寄存器R13、R14,这样可以便于中断程序使用自己特有的堆栈。

但这样随之而来产生一个问题,就是中断处理时堆栈溢出保护的问题,需要我们认真地估计堆栈的大小,同时在中断处理时也要尽量减少函数调用的层次,否则将产生一些不可预知的错误;3) 获取中断源:所有的IRQ中断都从0X00000018开始执行,通常在该地址处放一条跳转指令,进一步跳到我们的中断程序中;4) 处理中断:在中断程序中需要进一步获取中断源,即谁引发了该中断,然后通过查表获取相应中断的处理程序入口,并调用对应的函数;5) 中断返回,恢复现场:在返回时需要恢复处理器模式,包括恢复中断处理用到的所有寄存器、恢复被中断的程序运行状态到CPSR,并跳转到被中断的主程序。

下图为JX44B0教学实验系统中处理外部中断0的流程:图5-8 JX44B0中断处理示意图中断的入口代码(汇编代码):0X00000018: LDR pc, =0X0C000020……0X0C000020: b HandlerIRQHandlerIRQ:sub sp,sp,#4 /* 为中断分发例程入口地址预留栈空间 */stmfd sp!,{r0} /* 保存R0 */ldr r0,=HandleIRQ /* 将中断分发例程入口地址指针保存到R0中 */ldr r0,[r0] /* 将中断分发例程入口地址保存到R0中*/str r0,[sp,#4] /* 将中断分发例程入口地址保存到预留的堆栈空间 */ldmfd sp!,{r0,pc} /* 将R0和中断分发例程入口地址出栈,这条指令也 *//*实现了一个跳转 */上述代码实际上就是一个三级跳,即从FLASH中跳到了RAM的中断入口,然后又从中断入口跳到中断分发例程入口。

在此我们有一个前提条件,即必须在HandleIRQ地址处保存正确的分发例程入口地址,如使用下面代码后IsrIRQ就是中断分发例程:ldr r0,=HandleIRQldr r1,=IsrIRQstr r1,[r0]中断分发例程可以采用汇编语言和C语言两种格式编写,下面将分别列出这两种方式。

1) 用汇编代码编写的中断分发例程:IsrIRQ: /*using I_ISPR register.*/sub lr,lr,#4stmfd sp!,{lr} /* 保存中断返回的PC值 */stmfd sp!,{r0-r4} /* 备份寄存器R0-R4 */sub sp,sp,#4 /* 为PC预留栈空间 */stmfd sp!,{r8-r9} /* 备份寄存器R8-R9 */ldr r9,=I_ISPR /* 读取中断状态 */ldr r9,[r9]cmp r9, #0x0 /* 检查中断状态 */beq i2mov r8,#0x0 /* R8保存中断表的偏移 */i0: /* 逐位检查中断状态 */movs r9,r9,lsr #1bcs i1 /* 如果该位等于1,则处理这一中断 */add r8,r8,#4 /* 修改当前的中断偏移 */b i0 /* 处理下一比特 */i1:ldr r9,=HandleADC /* HandleADC位于中断向量表起始位置,我们将该地址用作是中断向量表的基地址 */add r9,r9,r8 /* 计算入口地址指针:中断基地址加上偏移 */ldr r9,[r9] /* 从地址向量表中获取入口地址 */str r9,[sp,#8] /* 将入口地址保存到堆栈,并移动堆栈指针 */mov lr,pc /* 保存当前PC*/ldmfd sp!,{r8-r9,pc} /* 调用中断例程 */ldmfd sp!,{r0-r4, pc}^/* 中断返回,并恢复中断前的处理器模式*/i2:ldmfd sp!,{r8-r9} /* 如果当前没有任何中断,直接返回 */add sp,sp,#4 /* 移动堆栈指针,该空间由第4句指令预留 */ldmfd sp!,{r0-r4, pc}^/* 中断返回,并恢复中断前的处理器模式*/2) 用C代码编写的中断分发例程:如果采用GNU编译器,需要将该函数定义为中断类型,使用关键字:__attribute__ ((interrupt("IRQ")))。

如下所示代码为C语言的IsrIRQ实现:typedef (*ISR_ROUTINE_ENTRY)(void);void IsrIRQ() __attribute__ ((interrupt("IRQ")));void IsrIRQ(){int count = 0;unsigned int isr_pending;unsigned int isr_mask = 0x00000001;unsigned int isr_mask_set = rINTMSK; /* 读取中断掩码 */ISR_ROUTINE_ENTRY isr_routine_entry = (ISR_ROUTINE_ENTRY)0x0;isr_pending = (rINTPND & ~isr_mask_set); /* 读取中断状态 *//* 查表 */while(isr_mask){if(isr_pending&isr_mask){/* 找到中断源,获取中断例程入口地址 */isr_routine_entry = (ISR_ROUTINE_ENTRY)(*(int*)(HandleADC+count));break;}count+=4;isr_mask <<= 1;}/* 调用中断服务例程 */if(isr_routine_entry) (*isr_routine_entry)();}中断处理例程(该函数无需定义为中断类型)void EINT0_Isr(){rI_ISPC=BIT_EINT0;/* 清除中断标志 */……}中断向量表中各个中断的偏移:表5-8 中断向量表中各个中断的偏移(六)1)编译/执行程序2)跟踪/调试程序3)断点的设置与取消。

4)下载程序与调试(七)实验步骤1. 参照模板工程interrupt(modules\interrupt\interrupt.apj),新建一个工程interrupt,添加相应的文件,并修改interrupt的工程设置;2. 创建interrupt.c并加入到工程interrupt中;3. 编写中断分发例程IsrIRQ;4. 注册外部中断0处理函数ext0_int_isr;5. 实现外部中断0处理函数ext0_int_isr,在其中实现LED开关功能;6. 编译interrupt;7. 下载程序并运行,按下按键EXTINT0将引发一次外部中断,并在中断处理函数中闪灯。

相关文档
最新文档