收藏 分享(赏)

嵌入式 中断实验.doc

上传人:eukav 文档编号:4294139 上传时间:2018-12-21 格式:DOC 页数:10 大小:889KB
下载 相关 举报
嵌入式 中断实验.doc_第1页
第1页 / 共10页
嵌入式 中断实验.doc_第2页
第2页 / 共10页
嵌入式 中断实验.doc_第3页
第3页 / 共10页
嵌入式 中断实验.doc_第4页
第4页 / 共10页
嵌入式 中断实验.doc_第5页
第5页 / 共10页
点击查看更多>>
资源描述

1、5.3 中断实验5.3.1 实验目的1. 了解中断的作用;2. 掌握嵌入式系统中断的处理流程;3. 掌握 ARM 中断编程。5.3.2 实验内容1. 编写中断处理程序,处理外部中断;5.3.3 预备知识1. 了解 ADT IDE 集成开发环境的基本功能;2. 了解中断的作用以及基本处理过程。5.3.4 实验设备1. 硬件:JX44B0 教学实验箱、PC 机;2. 软件:PC 机操作系统 Windows 98(2000、XP) ADT IDE 集成开发环境。5.3.5 基础知识1. 中断的基本概念CPU 与外设之间传输数据的控制方式通常有三种:查询方式、中断方式和 DMA 方式。DMA 方式将在

2、后续实验中说明。查询方式的优点是硬件开销小,使用起来比较简单。但在此方式下,CPU 要不断地查询外设的状态,当外设未准备好时,CPU 就只能循环等待,不能执行其它程序,这样就浪费了 CPU 的大量时间,降低了 CPU 的利用率。为了解决这个矛盾,通常采用中断传送方式:即当 CPU 进行主程序操作时,外设的数据已存入输入端口的数据寄存器;或端口的数据输出寄存器已空,由外设通过接口电路向 CPU 发出中断请求信号,CPU 在满足一定的条件下,暂停执行当前正在执行的主程序,转入执行相应能够进行输入/输出操作的子程序,待输入/输出操作执行完毕之后 CPU 再返回并继续执行原来被中断的主程序。这样 CP

3、U 就避免了把大量时间耗费在等待、查询状态信号的操作上,使其工作效率得以大大地提高。能够向 CPU 发出中断请求的设备或事件称为中断源。系统引入中断机制后,CPU 与外设(甚至多个外设)处于“并行”工作状态,便于实现信息的实时处理和系统的故障处理。中断方式的原理示意图如下所示。图 5-7 中断处理示意图1) 中断响应中断源向 CPU 发出中断请求,若优先级别最高,CPU 在满足一定的条件下,可以中断当前程序的运行,保护好被中断的主程序的断点及现场信息。然后,根据中断源提供的信息,找到中断服务子程序的入口地址,转去执行新的程序段,这就是中断响应。CPU 响应中断是有条件的,如内部允许中断、中断未

4、被屏蔽、当前指令执行完等。2) 中断服务子程序CPU 响应中断以后,就会中止当前的程序,转去执行一个中断服务子程序,以完成为相应设备的服务。中断服务子程序的一般结构如下图所示。图 5-8 中断服务子程序处理流程 保护现场(由一系列的压栈指令完成)。目的是为了保护那些与主程序中有冲突的寄存器,(如 R0,R1,R2 等),如果中断服务子程序中所使用的寄存器与主程序中所使用的寄存器等没有冲突的话,这一步骤可以省略。 中断处理,中断处理程序在检查到相应的中断源后,调用对应的中断处理程序完成。 恢复现场并返回(由一系列的出栈指令完成)。是与保护现场对应的,但要注意数据恢复的次序,以免混乱。由于中断服务

5、子程序需要打断主程序的执行,因此其处理应该及时完成,较长时间的延时将导致系统性能严重下降。2. S3C44B0X 中断控制器S3C44B0X 的中断控制器包括 5 类寄存器:中断控制寄存器、中断状态寄存器、中断模式寄存器、中断屏蔽寄存器和中断清除寄存器。1) 中断控制寄存器该控制寄存器是处理器总的中断控制,包括中断模式是矢量模式还是非矢量模式,是否使能 IRQ 模式的中断,是否使能 FIQ 模式的中断,具体说明如下:表 5-3 中断控制寄存器寄 存 器 名 称 地 址 读 写 状 态 描 述 复 位 值INTCON 0x01E00000 R/W 中断控制寄存器 0x7INTCON 位 描 述

6、初 始 状 态保留 3 0 0V 2 IRQ 禁止/使能向量模式0:向量中断模式 1:非向量中断模式1I 1 使能 CPU 的 IRQ 中断,在使用 IRQ 中断之前,必须清除该位0:IRQ 中断使能 1:IRQ 中断禁止1F 0 使能 CPU 的 FIQ 中断,在使用 FIQ 中断之前,必须清除该位0:FIQ 中断使能 1:FIQ 中断禁止12) 中断状态寄存器该寄存器用于检查中断来源,该寄存器是只读属性的。表 5-4 中断状态寄存器寄 存 器 名 称 地 址 读 写 状 态 描 述 复 位 值INTPND 0x01E00004 R 指示中断请求状态0:中断已被响应1:有中断请求0x03)

7、中断模式寄存器用于设置相应中断的工作模式,是 IRQ 模式还是 FIQ 模式。表 5-5 中断模式寄存器寄 存 器 名 称 地 址 读 写 状 态 描 述 复 位 值INTMOD 0x01E00008 R/W 中断模式寄存器0:IRQ 模式1:FIQ 模式0x04) 中断屏蔽寄存器表 5-6 中断屏蔽寄存器寄 存 器 名 称 地 址 读 写 状 态 描 述 复 位 值INTMSK 0x01E0000C R/W 确定哪一个中断源被屏蔽,屏蔽的中断源将不引发中断0:中断服务有效1:中断服务屏蔽0x7FFFFFF5) 中断清除寄存器中断处理之后需要清除相应的标志位,中断清除寄存器说明如下:表 5-7

8、 中断清除寄存器寄 存 器 名 称 地 址 读 写 状 态 描 述 复 位 值I_ISPC 0x01E00024 W IRQ 中断请求清 0 寄存器未定义F_ISPC 0x01E0003C W FIQ 中断请求清 0 寄存器未定义4. JX44B0 中断处理S3C44B0X 处理器的中断处理与其他 CPU 的处理模式基本上是一致的,只是由于它引入了几种不同的处理器模式,使中断处理变得更加容易。其典型的步骤如下:1) 保存现场:当系统出现中断时,处理器首先要做的就是保存现场,这一过程包括:保存当前的 PC 值到 lr 中,保存当前的程序运行状态到 spsr 中。值得注意的就是由于ARM7 采用

9、3 级流水线结构,此时的 PC 值实际上等于当前指令地址加上 8(ARM 指令时),所以返回时还需要将保存的 PC 值减 4;2) 模式切换:当处理器完成现场保护后,就进入中断模式,并将 PC 值置为一个固定的值 0X00000018,这也就是 IRQ 模式的中断入口地址。在中断模式下,有两个独立的寄存器 R13、R14,这样可以便于中断程序使用自己特有的堆栈。但这样随之而来产生一个问题,就是中断处理时堆栈溢出保护的问题,需要我们认真地估计堆栈的大小,同时在中断处理时也要尽量减少函数调用的层次,否则将产生一些不可预知的错误;3) 获取中断源:所有的 IRQ 中断都从 0X00000018 开始

10、执行,通常在该地址处放一条跳转指令,进一步跳到我们的中断程序中;4) 处理中断:在中断程序中需要进一步获取中断源,即谁引发了该中断,然后通过查表获取相应中断的处理程序入口,并调用对应的函数;5) 中断返回,恢复现场:在返回时需要恢复处理器模式,包括恢复中断处理用到的所有寄存器、恢复被中断的程序运行状态到 CPSR,并跳转到被中断的主程序。下图为 JX44B0 教学实验系统中处理外部中断 0 的流程:图 5-8 JX44B0 中断处理示意图中断的入口代码(汇编代码):0X00000018: LDR pc, =0X0C0000200X0C000020: b HandlerIRQHandlerIRQ

11、: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 的中断入口,然后又从中断入口跳到中断分发例程入口。在此我们

12、有一个前提条件,即必须在 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 预留栈空间

13、 */stmfd sp!,r8-r9 /* 备份寄存器 R8-R9 */ ldr r9,=I_ISPR /* 读取中断状态 */ldr r9,r9 cmp r9, #0x0 /* 检查中断状态 */beq i2 mov r8,#0x0 /* R8 保存中断表的偏移 */i0: /* 逐位检查中断状态 */movs r9,r9,lsr #1bcs i1 /* 如果该位等于 1,则处理这一中断 */add r8,r8,#4 /* 修改当前的中断偏移 */b i0 /* 处理下一比特 */i1: ldr r9,=HandleADC /* HandleADC 位于中断向量表起始位置,我们将该地址用作是

14、中断向量表的基地址 */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!,r

15、0-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 = 0x0000000

16、1;unsigned int isr_mask_set = rINTMSK; /* 读取中断掩码 */ISR_ROUTINE_ENTRY isr_routine_entry = (ISR_ROUTINE_ENTRY)0x0;isr_pending = (rINTPND /* 读取中断状态 */* 查表 */while(isr_mask)if(isr_pendingbreak;count+=4;isr_mask 5) dither_count = 0;if(ext0_countelse*(unsigned char*)0x2000000 = 0x0f; ext0_count+;void dela

17、y()int index = 0; for ( index = 0 ; index 100000; index+);5.3.6 实验步骤1. 参照模板工程 interrupt(modulesinterruptinterrupt.apj),新建一个工程interrupt,添加相应的文件,并修改 interrupt 的工程设置;2. 创建 interrupt.c 并加入到工程 interrupt 中;3. 编写中断分发例程 IsrIRQ;4. 注册外部中断 0 处理函数 ext0_int_isr;5. 实现外部中断 0 处理函数 ext0_int_isr,在其中实现 LED 开关功能;6. 编译 interrupt;7. 下载程序并运行,按下按键 EXTINT0 将引发一次外部中断,并在中断处理函数中闪灯。5.3.7 实验报告要求1. 中断处理的主要步骤有哪些?试说明每一步的主要工作。2. 编写程序处理定时中断;3. 简述 S3C44B0X 非矢量中断的处理步骤。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 中等教育 > 中学实验

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报