1 / 22

中断实验

中断实验. 中断实验. 实验目的 实验设备 实验内容 实验原理 实验参考程序. 中断实验. 实验目的 通过实验了解 ARM 的中断方式和原理。 熟悉 ARM 中断的编程方法。. 中断实验. 实验设备 硬件: PC 机,华邦 W90P710 开发板套件。 软件: Lambda IDE 集成开发环境, Windows 2000/NT/XP 。. 中断实验. 实验内容 掌握 ARM 中断工作原理,了解 W90P710 和中断有关的寄存器,掌握常用中断的编程方法 , 编写中断处理程序实现时钟中断。. 实验原理. 中断控制器介绍

zaria
Download Presentation

中断实验

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 中断实验

  2. 中断实验 • 实验目的 • 实验设备 • 实验内容 • 实验原理 • 实验参考程序

  3. 中断实验 • 实验目的 • 通过实验了解ARM的中断方式和原理。 • 熟悉ARM中断的编程方法。

  4. 中断实验 • 实验设备 • 硬件:PC机,华邦W90P710开发板套件。 • 软件:Lambda IDE集成开发环境,Windows 2000/NT/XP。

  5. 中断实验 • 实验内容 • 掌握ARM中断工作原理,了解W90P710和中断有关的寄存器,掌握常用中断的编程方法,编写中断处理程序实现时钟中断。

  6. 实验原理 • 中断控制器介绍 W90P710开发板集成了一个高级中断控制器,简称AIC(advanced interrupt controller),来处理来自设备的中断。它类似于X86体系的8529芯片,是W90P710控制中断的部件。为了响应多个中断源,AIC为每个设备的中断号定义了的优先级。并且实现了一个中断优先级位表[7],如表1-1所示:

  7. 实验原理 表 1-1中断优先级位表

  8. 实验原理 • 若同一优先级的中断同时到来,则根据中断号越低,优先级越高的原则只响应最高优先级中断。另外,优先级为0的四个中断触发的是FIQ中断,而其余级别的中断全都属于IRQ中断。 • AIC最多可以处理32个中断源(现在只定义了31个),每个中断源都对应了唯一的中断号,如图1-1所示:

  9. 实验原理 图 1-1 W90P710 中断号分配

  10. 实验原理 • 其中中断号越低,优先级就越高。例如1号看门狗中断优先级最高。另外优先级为0的四个中断触发的是FIQ中断,而其余级别的中断全都属于IRQ中断。 • 控制AIC的寄存器映射在地址0xfff8_2100-0xfff8_2200。AIC模块的主要功能是屏蔽或者使能中断,相当于在设备级和CPU之间多了一道中断的开关,它的主要控制寄存器有IPER,MECR,MDCR等。

  11. 实验原理 • Timer(定时器)介绍 • 本实验中触发中断的设备为定时器(Timer),触发的中断类型为IRQ。 • Timer完成计时主要是靠一个叫做计数寄存器完成的,一般先赋予计数器一个初值,然后打开计数使能位,使计数器自动计数,一旦计数器里的值向下减少到零或者向上增加到某个约定的数值,那么时钟就触发了一次中断。

  12. 实验原理 • 系统的中断控制机制

  13. 实验参考程序 • 本实验里中断的程序的编写主要包括以下几个部分: • 1安装中断向量表 • 2初始化Timer和AIC,打开中断的一、二级开关 • 3编写中断处理函数 • 4使能Timer的中断位,使其可以触发中断,并开始计数。

  14. 实验参考程序 /* 打开第一级开关,将控制IRQ中断的I位置零 * / CPSR_init: mov r0,#0x5f //开中断 msr cpsr_c,r0 mov pc,lr //返回 /* 打开第二级开关,将Timer对应的AIC的中断通道13打开 */ void AIC_Init() { rAIC_MDCR = 0XFFFFFFFE; /* 将中断通道全部关闭 */ Aic_Int_Enable(13); }

  15. 实验参考程序 /* 打开中断通道i的函数 */ void Aic_Int_Enable(char vector) { unsigned int mask; if( vector > INTERRUPT_VECTOR_END) /*中断号越界检查*/ { return ; } mask = 1 << vector; rAIC_MECR = (mask|rAIC_IMR); } /* 打开第三级开关,使能Timer0的中断,并使其开始计数 */

  16. 实验参考程序 unsigned int Timer_Start( ) { rTCSR0 |= (CEN|IE); /*开启中断使能,计数使能位 */ return TRUE; } 编写中断处理函数 中断处理包括三部分:保存现场,清中断,恢复现场。 /* 保存现场 */

  17. 实验参考程序 STR R3, [SP, #-4]! //将需要使用的工作寄存器压栈 STR R2, [SP, #-4]! STR R1, [SP, #-4]! MOV R1, SP // 保存IRQ堆栈指针 ADD SP, SP,#12 // 调整IRQ堆栈指针 SUB R2, LR,#4 // 保存返回地址 MRS R3, SPSR // 保存SPSR寄存器内容 MSR CPSR_c, #(NO_INT | SYS32_MODE) // 切换成SYS模式

  18. 实验参考程序 // 保存被中断任务的寄存器现场 STR R2, [SP, #-4]! STR LR, [SP, #-4]! STR R12, [SP, #-4]! STR R11, [SP, #-4]! STR R10, [SP, #-4]! STR R9, [SP, #-4]! STR R8, [SP, #-4]! STR R7, [SP, #-4]! STR R6, [SP, #-4]! STR R5, [SP, #-4]! STR R4, [SP, #-4]! LDR R4, [R1], #4 //从IRQ堆栈中读出R1-R3的寄存器内容

  19. 实验参考程序 LDR R5, [R1], #4 LDR R6, [R1], #4 STR R6, [SP, #-4]! //将原来R1-R3的寄存器内容保存至堆栈 STR R5, [SP, #-4]! STR R4, [SP, #-4]! STR R0, [SP, #-4]! // 将R0保存 STR R3, [SP, #-4]! //被中断任务的CPSR寄存器内容保存 /******************做模式切换,执行真正的中断处理****************/ MSR CPSR_c, #(NO_INT | IRQ32_MODE) BL T0_INT_ISR

  20. 实验参考程序 /***************恢复现场,原先保存的寄存器出栈*****************/ LDR R4, [SP], #4 MSR CPSR_cxsf, R4 LDR R0, [SP], #4 LDR R1, [SP], #4 LDR R2, [SP], #4 LDR R3, [SP], #4 LDR R4, [SP], #4 LDR R5, [SP], #4 LDR R6, [SP], #4 LDR R7, [SP], #4 LDR R8, [SP], #4 LDR R9, [SP], #4 LDR R10, [SP], #4

  21. 实验参考程序 LDR R11, [SP], #4 LDR R12, [SP], #4 LDR LR, [SP], #4 LDR PC, [SP], #4 其中,除保存和恢复现场外,真正的中断处理很简单,只是为一个isr_counter简单加1,使其记录中断的次数。可以用c函数T0_INT_ISR实现: void T0_INT_ISR() { OSTimeTick(); rTISR = 0x01; rAIC_EOSCR = 0; }

  22. 实验参考程序 使能Timer的中断位,使其可以触发中断,并开始计数。 unsigned int Timer_Start( ) { rTCSR0 |= (CEN|IE); /*开启中断使能,计数使能位*/ return TRUE; } 上述函数的宏定义这里不做说明,详见实验代码附件。

More Related