arm7的中断

arm7的中断,第1张

ARM7TDMI内核CPU在响应中断后会切换到异常模式下:FIQ中断是进入快中断模式,IRQ中断时进入中断模式(ARM7TDMI内核有7种模式:用户模式,系统模式,快中断模式,中断模式,管理模式,中止模式和未定义模式,其中后5种被称为异常模式。

中断处理过程,ARM7进入及退出快中断模式和中断模式的过程(中断响应过程)如下:

① 将下一条指令的地址复制到LR(R14)中(在ARM状态下)。

② 将CPSR复制到适当的SPSR(各种模式处CPSR是共用一个的,而SPSR在不同异常模式下是不同的)。

③ 根据异常将CPSR模式强制设为快中断模式或中断模式。

④ 强制PC从相关的异常向量处取指。(到此完成进入中断服务程序的动作)

⑤ 执行异常服务程序。

⑥ 将LR中的值减去偏移量后移入PC。ARM状态快中断模式和中断模式下这个偏移量为4,因为LR保存的是由于FIQ或IRQ占先面没有被执行的指令的地址。

⑦ 将SPSR的值复制回CPSR中。

⑧ 清零在入口置位的中断禁止标志。

一旦产生IRQ中断,微控制器会切换到IRQ模式,并且跳转到向量表0x0000018地址处执行程序。而一旦产生FIQ中断,微控制器会切换到FIQ模式,并且跳转到向量表0x000001C地址处执行程序。所示,在0x00000080处和0x0000001C处必须各有一条跳转指令,分别跳转的IRQ和FIQ中断处理的代码处。在0x00000000处的一般向量表称为异常向量表。

ARM7的中断向量表的前8个中断向量中,最后两个是IRQ和FIQ。可以从这两个中断向量跳转到相应的中断服务函数中去。在ARM7中,IRQ中断用的比较多。当产生一个IRQ中断之后,首先要保存当前工作状态的环境,然后将中断服务函数地址赋给PC,跳转到中断服务函数。执行完中断服务函数之后,再恢复中断前的工作状态环境,返回正常的工作模式。

ARM7有7种模式:User用户、System系统、Fast Interrupt快速中断、Interrupt中断、Supervisor管理、Abort中止、Undefined未定义,共有3,结构如下图。

其中白色寄存器为共有的,彩色为该模式独有的。模式由CPSR中的低五位决定,更改这5位(用户模式除外)就可以进入相应的模式,模式还可以由异常而转换,比如中断被触发,CPU自动进入中断模式。

注意:像R13_irq的_irq这样的后缀在程序中不能出现。

C51没有模式的概念,也可以说C51只有一种模式,不过它的四个工作寄存器组倒是有点模式的意思。

SPSR(Saved Program Status Register)用来做CPSR的备份,发生异常时(不是修改模式位),CPU会自动将CPSR的内容备份到SPSR,所以当模式返回时,需要用软件把SPSR恢复答CPSR。

除用户模式外,其他6个模式可以直接对CPSR进行读写,所以这6个模式叫特权(privileged)模式,系统模式和用户模式有相同的寄存器,只不过系统模式可以直接读写CPSR,其他5个模式需要发生异常(exception)来进入,所以叫异常模式。

单步调试下面代码,观察各个寄存器的值:

AREA ABC,CODE,READONLY

CODE32

系统上电复位后,自动进入管理模式

MOV R0,#0x11

MOV R13,#0x22 管理模式下的R13_svc

MRS R1,CPSR 将CPSR内容读取到R1中

BIC R1,R1,#0x1F 将R1的低5位清零

ORR R1,R1,#0x12 将R1的低5位赋值为0x12,即中断模式

MSR CPSR_C,R1 将R1的值载到CPSR的C域(低八位),CPU进入中断模式

MOV R0,#0x33 R0还是前面那个R0

MOV R13,#0x44 R13已经不是那个R13_svc,是R13_irq

MRS R1,CPSR

BIC R1,R1,#0x1F 进入管理模式

ORR R1,R1,#0x13

MSR CPSR_C,R1

S B S

系统上电复位后,自动进入管理模式对CPSR读写只能通过MRS和MSR,且要采取读—改—写的方式,BIC是按位清零,ORR是按位或,中断模式的模式位是10010(0x12),管理模式的模式位是10011(0x13),别的模式切换同理。

经试验发现:R0的值被更新,说明它是共用的,而这两个模式都有自己的R13。

呵呵!那个你看里面的tmr的代码就知道了!比较简单的!肯定是不能用_irq的!我给你贴段代码出来!你参考哈!

void UartInit(CPU_INT32U PortNum,CPU_INT32U baudrate )

{

CPU_INT32U Fdiv

if ( PortNum == 0 )

{

#if UART0_EN>0

PINSEL0 = 0x00000050 /* RxD0 和 TxD0 */

U0LCR = 0x83 /* 8 位数据位, 无校验位, 1 位停止位 */

Fdiv = ( Fpclk / 16 ) / baudrate /*波特率设置 */

U0DLM = Fdiv / 256

U0DLL = Fdiv % 256

U0LCR = 0x03 /* DLAB = 0 */

U0FCR = 0x07 /* 使能和复位 TX 和 RX 的FIFO */

VICIntSelect &= ~(1 <<VIC_UART0) /* 配置uart0中断为 IRQ 中断源 */

VICVectAddr6 = (CPU_INT32U)Uart0_ISR_Handler /* 设置中断地址*/

VICIntEnable = (1 <<VIC_UART0) /* 使能uart0中断源 */

U0IER = IER_RBR | IER_THRE | IER_RLS /* 使能 UART0 的中断 */

下面是中断服务程序ISR

void Uart0_ISR_Handler(void)

{

#if UART0_EN>0

#if OS_CRITICAL_METHOD == 3 /* 分配存储空间给CPU状态寄存器 */

OS_CPU_SR cpu_sr = 0

#endif

CPU_INT08U IIRValue, LSRValue

CPU_INT08U Dummy = Dummy

只截了一部分哈!主要是后面是我们公司一个项目里面的了!呵呵!


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7807064.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-10
下一篇 2023-04-10

发表评论

登录后才能评论

评论列表(0条)

保存