23
第 6 第 第第第

第 6 章 中断系统

  • Upload
    nakia

  • View
    95

  • Download
    0

Embed Size (px)

DESCRIPTION

第 6 章 中断系统. §6.1 中断的一般概念. 中断向量,是中断源提供的处理程序的入口,其入口处,是由系统统一划拨存储空间,给各中断源存放中断处理程序的入口,即中断向量表。 中断响应过程:申请 - 响应( 终止当前程序 - 保护断点 - 转到处理程序。 ) - 中断处理( 保护现场 - 处理 - 清该标志、恢复现场 - 返回。软件 )。. CPU 对突发事件响应方式 中断源及中断申请 开中断与关中断 中断优先级及中断嵌套 中断向量与中断处理. 硬件实现. 一个应用系统,面对处理器众多的中,是根据应用来选取允许中断的事件与不允许中断的事件。. 软件完成. - PowerPoint PPT Presentation

Citation preview

Page 1: 第 6 章 中断系统

第 6章 中断系统

第 6章 中断系统

Page 2: 第 6 章 中断系统

§6.1 §6.1 中断的一般概念中断的一般概念CPUCPU 对突发事件响应方式对突发事件响应方式中断源及中断申请中断源及中断申请开中断与关中断开中断与关中断中断优先级及中断嵌套中断优先级及中断嵌套中断向量与中断处理中断向量与中断处理

CPUCPU 对突发事件响应方式对突发事件响应方式中断源及中断申请中断源及中断申请开中断与关中断开中断与关中断中断优先级及中断嵌套中断优先级及中断嵌套中断向量与中断处理中断向量与中断处理

一个应用系统,面对处理一个应用系统,面对处理器众多的中,是根据应用来选器众多的中,是根据应用来选取允许中断的事件与不允许中取允许中断的事件与不允许中断的事件。断的事件。

一个应用系统,面对处理一个应用系统,面对处理器众多的中,是根据应用来选器众多的中,是根据应用来选取允许中断的事件与不允许中取允许中断的事件与不允许中断的事件。断的事件。

中断向量,是中断源提供的处理程序中断向量,是中断源提供的处理程序的入口,其入口处,是由系统统一划拨存的入口,其入口处,是由系统统一划拨存储空间,给各中断源存放中断处理程序的储空间,给各中断源存放中断处理程序的入口,即中断向量表。入口,即中断向量表。

中断响应过程:申请中断响应过程:申请 -- 响应(响应(终止当前程终止当前程序序 -- 保护断点保护断点 -- 转到处理程序。转到处理程序。)) -- 中断中断处理(处理(保护现场保护现场 -- 处理处理 -- 清该标志、恢复清该标志、恢复现场现场 -- 返回。软件返回。软件)。)。

中断向量,是中断源提供的处理程序中断向量,是中断源提供的处理程序的入口,其入口处,是由系统统一划拨存的入口,其入口处,是由系统统一划拨存储空间,给各中断源存放中断处理程序的储空间,给各中断源存放中断处理程序的入口,即中断向量表。入口,即中断向量表。

中断响应过程:申请中断响应过程:申请 -- 响应(响应(终止当前程终止当前程序序 -- 保护断点保护断点 -- 转到处理程序。转到处理程序。)) -- 中断中断处理(处理(保护现场保护现场 -- 处理处理 -- 清该标志、恢复清该标志、恢复现场现场 -- 返回。软件返回。软件)。)。

硬件实现硬件实现硬件实现硬件实现

软件完成软件完成软件完成软件完成

Page 3: 第 6 章 中断系统

§6.2 SPCE061A中断系统

§6.2 SPCE061A中断系统

Page 4: 第 6 章 中断系统

中断类型与中断源中断类型与中断源 异常中断异常中断 -RESET-RESET ,向量地址为,向量地址为 FFF7FFF7

HH 。优先级最高。。优先级最高。 软中断软中断 -- 执行指令执行指令 BREAKBREAK ,向量地址,向量地址

为为 FFF5HFFF5H 。优先级最低。。优先级最低。 事件中断事件中断 -- 外部与片内外部与片内 I/OI/O 事件。快速事件。快速

中断中断 FIQFIQ 与中断与中断 IRQIRQ 。。 FIQFIQ 优先级高优先级高于于 IRQ IRQ 。。

异常中断异常中断 -RESET-RESET ,向量地址为,向量地址为 FFF7FFF7HH 。优先级最高。。优先级最高。

软中断软中断 -- 执行指令执行指令 BREAKBREAK ,向量地址,向量地址为为 FFF5HFFF5H 。优先级最低。。优先级最低。

事件中断事件中断 -- 外部与片内外部与片内 I/OI/O 事件。快速事件。快速中断中断 FIQFIQ 与中断与中断 IRQIRQ 。。 FIQFIQ 优先级高优先级高于于 IRQ IRQ 。。

Page 5: 第 6 章 中断系统

中断源中断源(事件)(事件) 优先级优先级 向量向量(通道)(通道) 保留字保留字PWMPWM 音频中断音频中断 FIQFIQ//IRQ0IRQ0 FFF6HFFF6H//FFF8HFFF8H _FIQ_FIQ//_IRQ0_IRQ0

TimerATimerA 溢出信号溢出信号 FIQFIQ//IRQ1IRQ1 FFF6HFFF6H//FFF9HFFF9H _FIQ_FIQ//_IRQ1_IRQ1

TimerBTimerB 溢出信号溢出信号 FIQFIQ//IRQ2IRQ2 FFF6HFFF6H//FFFAHFFFAH _FIQ_FIQ//_IRQ2_IRQ2

EXT2EXT2

IRQ3IRQ3 FFFBHFFFBH _IRQ3_IRQ3EXT1EXT1

键唤醒键唤醒4096Hz4096Hz 时基信号时基信号

IRQ4IRQ4 FFFCHFFFCH _IRQ4_IRQ42048Hz2048Hz 时基信号时基信号1024Hz1024Hz 时基信号时基信号4Hz4Hz 时基信号时基信号

IRQ5IRQ5 FFFDHFFFDH_IRQ5_IRQ5

2Hz2Hz 时基信号时基信号TMB1TMB1 选频信号选频信号

IRQ6IRQ6 FFFEHFFFEH _IRQ6_IRQ6TMB2TMB2 选频信号选频信号UARTUART IRQ7IRQ7 FFFFHFFFFH _IRQ7_IRQ7

如果同时有两个以上的如果同时有两个以上的 IRQIRQ中断时,按此优先级中断时,按此优先级响应响应。但较。但较“高级别”“高级别” IRQIRQ 中断不能中断中断不能中断“较低级别”“较低级别” IRQIRQ 中断。即在中断。即在 IIRQRQ 中断中不允许中断嵌套。中断中不允许中断嵌套。

如果同时有两个以上的如果同时有两个以上的 IRQIRQ中断时,按此优先级中断时,按此优先级响应响应。但较。但较“高级别”“高级别” IRQIRQ 中断不能中断中断不能中断“较低级别”“较低级别” IRQIRQ 中断。即在中断。即在 IIRQRQ 中断中不允许中断嵌套。中断中不允许中断嵌套。 事事

件件中中断断

事事件件中中断断

中断服务中断服务程序以此取名。程序以此取名。 中断服务中断服务程序以此取名。程序以此取名。

Page 6: 第 6 章 中断系统

中断控制寄存器 P_INT_CtrlP_INT_Ctrl (( 7010H7010H ) 读) 读 // 写写 读,中断标志字,用于判别产生中断的读,中断标志字,用于判别产生中断的

源。写,选择允许中断的源。源。写,选择允许中断的源。 P_INT_Clear P_INT_Clear (( 7011H7011H ) 写) 写

清中断标志。选择的源与中断标志字对清中断标志。选择的源与中断标志字对应。写“应。写“ 1”1” 清该中断标志。清该中断标志。

P_INT_Ctrl_NewP_INT_Ctrl_New (( 702DH702DH ) 读) 读 // 写写 激活与屏蔽中断。读,了解哪些中断源激活与屏蔽中断。读,了解哪些中断源

被屏蔽。写,对应被屏蔽。写,对应 00 的中断源被屏蔽。对应的中断源被屏蔽。对应 11的中断源被激活。的中断源被激活。

Page 7: 第 6 章 中断系统

中断控中断控制 字制 字 事 件事 件 说 明说 明

b15b15 FIQ PWMFIQ PWM 音频中断音频中断

b14b14 IRQ0 PWMIRQ0 PWM 音频中断音频中断b12b12 FIQ_TMAFIQ_TMA

b13b13 IRQ1_TMAIRQ1_TMA

b11b11 FIQ_TMBFIQ_TMB

b10b10 IRQ2_TMBIRQ2_TMB

b9b9 IRQ3_ EXT2IRQ3_ EXT2

b8b8 IRQ3_ EXT1IRQ3_ EXT1

b7b7 IRQ3_KEYIRQ3_KEY

b6b6 IRQ4_ 4KHzIRQ4_ 4KHz

b5b5 IRQ4_ 2KHzIRQ4_ 2KHz

b4b4 IRQ4_ 1KHzIRQ4_ 1KHz

b3b3 IRQ5_ 4HzIRQ5_ 4Hz

b2b2 IRQ5_ 2HzIRQ5_ 2Hz

b1b1 IRQ6_ TMB1IRQ6_ TMB1

b0b0 IRQ6_ TMB2IRQ6_ TMB2

UART IRQUART IRQ 写写 [[P_UART_Command2P_UART_Command2]]b7b7 、、 b6b6

osc

中中断断控控制制字字

每一位对应一个事件,每一位对应一个事件,如果通过如果通过 [P_INT_Ctrl][P_INT_Ctrl] 向某向某位位写写 11 ,则允许该事件向,则允许该事件向 CCPUPU 申请中断。申请中断。

如果通过如果通过 [P_INT_Ctrl][P_INT_Ctrl]读读,,是读中断标志,是读中断标志,置置 11 的的位,说明该事件已向位,说明该事件已向 CPUCPU申请了中断。申请了中断。

[P_INT_Ctrl_New][P_INT_Ctrl_New] 端端口的每一位,也对应表中的口的每一位,也对应表中的事件。事件。

如果通过如果通过 [P_INT_Clea[P_INT_Clear]r] 向某位写向某位写 11 ,则清除该事,则清除该事件的中断标志。件的中断标志。

Page 8: 第 6 章 中断系统

注意:只有在注意:只有在 P_INT_CtrlP_INT_Ctrl 中中设置了中断源允许位为“设置了中断源允许位为“ 1”1” ,, 相应开 相应开 // 关中断指令才有意义。关中断指令才有意义。

注意:只有在注意:只有在 P_INT_CtrlP_INT_Ctrl 中中设置了中断源允许位为“设置了中断源允许位为“ 1”1” ,, 相应开 相应开 // 关中断指令才有意义。关中断指令才有意义。

中断控制指令中断控制指令

Page 9: 第 6 章 中断系统

[例[例 6.16.1 ]] IRQ5IRQ5 有有 22 个中断源,个中断源, 2Hz2Hz 和和 44HzHz 。。 TIME2TIME2 对对 2Hz2Hz 中断计数, 中断计数, TIME4TIME4对对 4Hz4Hz 中断计数。中断计数。 2Hz2Hz 中断控制中断控制 AA 口口 00 ~~33 LEDLED 以以 2S2S 速率闪烁, 速率闪烁, 4Hz4Hz 中断控制中断控制 BB口口 00 ~3~3 LEDLED 以以 1S1S 速率闪烁。速率闪烁。

Y

否,就是 2Hz 中断。

.DEFINE P_IOA_DATA 0x7000 .DEFINE P_IOA_DATA 0x7000

.DEFINE P_IOA_DIR 0x7002 .DEFINE P_IOA_DIR 0x7002

.DEFINE P_IOA_ATTRI 0x7003.DEFINE P_IOA_ATTRI 0x7003

.DEFINE P_IOB_DATA 0x7005 .DEFINE P_IOB_DATA 0x7005

.DEFINE P_IOB_DIR 0x7007 .DEFINE P_IOB_DIR 0x7007

.DEFINE P_IOB_ATTRI 0x7008 .DEFINE P_IOB_ATTRI 0x7008

.DEFINE P_INT_Ctrl 0x7010 .DEFINE P_INT_Ctrl 0x7010

.DEFINE P_INT_CLEAR 0x7011 .DEFINE P_INT_CLEAR 0x7011

.DEFINE P_INT_CTRL_New 0x702D.DEFINE P_INT_CTRL_New 0x702D

.RAM.RAM

.VAR TIME2 //2Hz.VAR TIME2 //2Hz 计数器计数器

.VAR TIME4 //4Hz.VAR TIME4 //4Hz 计数器计数器

.CODE .CODE

.PUBLIC _main //.PUBLIC _main // 主程序 主程序 _main: _main: INT offINT offR1=0xffff //r1R1=0xffff //r1 的值为的值为 0xffff 0xffff [P_IOA_ATTRI]=r1 //IOA[P_IOA_ATTRI]=r1 //IOA 口设置为同相高电平输口设置为同相高电平输出出[P_IOA_DIR]=r1 [P_IOA_DIR]=r1 [P_IOA_DATA]=r1;[P_IOA_DATA]=r1;

.DEFINE P_IOA_DATA 0x7000 .DEFINE P_IOA_DATA 0x7000

.DEFINE P_IOA_DIR 0x7002 .DEFINE P_IOA_DIR 0x7002

.DEFINE P_IOA_ATTRI 0x7003.DEFINE P_IOA_ATTRI 0x7003

.DEFINE P_IOB_DATA 0x7005 .DEFINE P_IOB_DATA 0x7005

.DEFINE P_IOB_DIR 0x7007 .DEFINE P_IOB_DIR 0x7007

.DEFINE P_IOB_ATTRI 0x7008 .DEFINE P_IOB_ATTRI 0x7008

.DEFINE P_INT_Ctrl 0x7010 .DEFINE P_INT_Ctrl 0x7010

.DEFINE P_INT_CLEAR 0x7011 .DEFINE P_INT_CLEAR 0x7011

.DEFINE P_INT_CTRL_New 0x702D.DEFINE P_INT_CTRL_New 0x702D

.RAM.RAM

.VAR TIME2 //2Hz.VAR TIME2 //2Hz 计数器计数器

.VAR TIME4 //4Hz.VAR TIME4 //4Hz 计数器计数器

.CODE .CODE

.PUBLIC _main //.PUBLIC _main // 主程序 主程序 _main: _main: INT offINT offR1=0xffff //r1R1=0xffff //r1 的值为的值为 0xffff 0xffff [P_IOA_ATTRI]=r1 //IOA[P_IOA_ATTRI]=r1 //IOA 口设置为同相高电平输口设置为同相高电平输出出[P_IOA_DIR]=r1 [P_IOA_DIR]=r1 [P_IOA_DATA]=r1;[P_IOA_DATA]=r1;

[P_IOB_ATTRI]=r1 //IOB[P_IOB_ATTRI]=r1 //IOB 口设置为同相高电平输出口 口设置为同相高电平输出口 [P_IOB_DIR]=r1 [P_IOB_DIR]=r1 [P_IOB_DATA]=r1;[P_IOB_DATA]=r1;R1=0x000CR1=0x000C[P_INT_Ctrl ]=R1[P_INT_Ctrl ]=R1[P_INT_CTRL_New ]=R1[P_INT_CTRL_New ]=R1R1=0R1=0[TIME2]=R1[TIME2]=R1[TIME4]=R1[TIME4]=R1INT IRQINT IRQLoopLoop::NOPNOPNOPNOPJMP JMP LoopLoop//============================//============================.TEXT.TEXT.PUBLIC _IRQ5.PUBLIC _IRQ5_IRQ5:_IRQ5:PUSH R1,R5 TO [SP]PUSH R1,R5 TO [SP]R1 = 0x0008;R1 = 0x0008;TEST R1,[P_INT_Ctrl]; //TEST R1,[P_INT_Ctrl]; // 中断识别中断识别JNZ JNZ L_IRQ5_4HzL_IRQ5_4Hz;;

[P_IOB_ATTRI]=r1 //IOB[P_IOB_ATTRI]=r1 //IOB 口设置为同相高电平输出口 口设置为同相高电平输出口 [P_IOB_DIR]=r1 [P_IOB_DIR]=r1 [P_IOB_DATA]=r1;[P_IOB_DATA]=r1;R1=0x000CR1=0x000C[P_INT_Ctrl ]=R1[P_INT_Ctrl ]=R1[P_INT_CTRL_New ]=R1[P_INT_CTRL_New ]=R1R1=0R1=0[TIME2]=R1[TIME2]=R1[TIME4]=R1[TIME4]=R1INT IRQINT IRQLoopLoop::NOPNOPNOPNOPJMP JMP LoopLoop//============================//============================.TEXT.TEXT.PUBLIC _IRQ5.PUBLIC _IRQ5_IRQ5:_IRQ5:PUSH R1,R5 TO [SP]PUSH R1,R5 TO [SP]R1 = 0x0008;R1 = 0x0008;TEST R1,[P_INT_Ctrl]; //TEST R1,[P_INT_Ctrl]; // 中断识别中断识别JNZ JNZ L_IRQ5_4HzL_IRQ5_4Hz;;

L_IRQ5_2Hz:L_IRQ5_2Hz: R1=0x0004R1=0x0004[P_INT_Clear] = R1; //[P_INT_Clear] = R1; // 清中断清中断R2=[R2=[TIME2TIME2] ] //// 计数器计数器 +1+1R2+=1R2+=1[[TIME2TIME2]=R2]=R2CMP R2CMP R2 ,, 22 //// 是否是否 1S?1S?JBE JBE LED2Hz_OFF LED2Hz_OFF //// 否否 , LED, LED灭灭R1=0xFFF0 R1=0xFFF0 //// 是是 , LED, LED亮亮[P_IOA_DATA]=R1[P_IOA_DATA]=R1CMP R2,4 CMP R2,4 //// 是否是否 2S?2S?JBE JBE LED2Hz_RET LED2Hz_RET //// 否否 ,,中断中断返回返回R2=0 R2=0 //// 是是 , , 清清 TIME2TIME2[TIME2]=R2[TIME2]=R2JMP LED2Hz_RETJMP LED2Hz_RETLED2Hz_OFF:LED2Hz_OFF:R1=0xFFFFR1=0xFFFF[P_IOA_DATA]=R1[P_IOA_DATA]=R1LED2Hz_RETLED2Hz_RETPOP R1,R5 FROM [SP];POP R1,R5 FROM [SP];RETI;RETI;

L_IRQ5_2Hz:L_IRQ5_2Hz: R1=0x0004R1=0x0004[P_INT_Clear] = R1; //[P_INT_Clear] = R1; // 清中断清中断R2=[R2=[TIME2TIME2] ] //// 计数器计数器 +1+1R2+=1R2+=1[[TIME2TIME2]=R2]=R2CMP R2CMP R2 ,, 22 //// 是否是否 1S?1S?JBE JBE LED2Hz_OFF LED2Hz_OFF //// 否否 , LED, LED灭灭R1=0xFFF0 R1=0xFFF0 //// 是是 , LED, LED亮亮[P_IOA_DATA]=R1[P_IOA_DATA]=R1CMP R2,4 CMP R2,4 //// 是否是否 2S?2S?JBE JBE LED2Hz_RET LED2Hz_RET //// 否否 ,,中断中断返回返回R2=0 R2=0 //// 是是 , , 清清 TIME2TIME2[TIME2]=R2[TIME2]=R2JMP LED2Hz_RETJMP LED2Hz_RETLED2Hz_OFF:LED2Hz_OFF:R1=0xFFFFR1=0xFFFF[P_IOA_DATA]=R1[P_IOA_DATA]=R1LED2Hz_RETLED2Hz_RETPOP R1,R5 FROM [SP];POP R1,R5 FROM [SP];RETI;RETI;

L_IRQ5_4Hz:L_IRQ5_4Hz: R1=0x0008R1=0x0008[P_INT_Clear] = R1; //[P_INT_Clear] = R1; // 清中断清中断R2=[R2=[TIME4TIME4] //] // 计数器计数器 +1+1R2+=1R2+=1[[TIME4TIME4]=R2]=R2CMP R2CMP R2 ,, 22 //// 是否是否 0.5S?0.5S?JBE JBE LED4Hz_OFFLED4Hz_OFF //// 否否 , LED, LED灭灭R1=0xFFF0R1=0xFFF0 //// 是是 , LED, LED亮亮[P_IOB_DATA]=R1[P_IOB_DATA]=R1CMP R2,4CMP R2,4 //// 是否是否 1S?1S?JBE JBE LED4Hz_RETLED4Hz_RET //// 否否 ,,中断中断返回返回R2=0R2=0 //// 是是 , , 清清 TIME4TIME4[TIME4]=R2[TIME4]=R2JMP LED4Hz_RETJMP LED4Hz_RETLED4Hz_OFF:LED4Hz_OFF:R1=0xFFFFR1=0xFFFF[P_IOA_DATA]=R1[P_IOA_DATA]=R1LED4Hz_RETLED4Hz_RETPOP R1,R5 FROM [SP];POP R1,R5 FROM [SP];RETI;RETI;

L_IRQ5_4Hz:L_IRQ5_4Hz: R1=0x0008R1=0x0008[P_INT_Clear] = R1; //[P_INT_Clear] = R1; // 清中断清中断R2=[R2=[TIME4TIME4] //] // 计数器计数器 +1+1R2+=1R2+=1[[TIME4TIME4]=R2]=R2CMP R2CMP R2 ,, 22 //// 是否是否 0.5S?0.5S?JBE JBE LED4Hz_OFFLED4Hz_OFF //// 否否 , LED, LED灭灭R1=0xFFF0R1=0xFFF0 //// 是是 , LED, LED亮亮[P_IOB_DATA]=R1[P_IOB_DATA]=R1CMP R2,4CMP R2,4 //// 是否是否 1S?1S?JBE JBE LED4Hz_RETLED4Hz_RET //// 否否 ,,中断中断返回返回R2=0R2=0 //// 是是 , , 清清 TIME4TIME4[TIME4]=R2[TIME4]=R2JMP LED4Hz_RETJMP LED4Hz_RETLED4Hz_OFF:LED4Hz_OFF:R1=0xFFFFR1=0xFFFF[P_IOA_DATA]=R1[P_IOA_DATA]=R1LED4Hz_RETLED4Hz_RETPOP R1,R5 FROM [SP];POP R1,R5 FROM [SP];RETI;RETI;

Page 10: 第 6 章 中断系统

[例[例 6.26.2 ]键唤醒,]键唤醒, AA 口键盘输入,口键盘输入,BB 口口 LEDLED 输出。输出。

.include Hardwore.inc //.include Hardwore.inc // 硬件资源接口硬件资源接口

.define P_IOA_RL 0x7004.define P_IOA_RL 0x7004 // // P_IOA_LatchP_IOA_Latch

.CODE.CODE

.PUBLIC _main.PUBLIC _main_main:_main: r1=0 r1=0 //IOA //IOA 为带下拉电阻输入。为带下拉电阻输入。 [P_IOA_Dir]=r1[P_IOA_Dir]=r1 [P_IOA_Attr]=r1[P_IOA_Attr]=r1 [P_IOA_Data]=r1[P_IOA_Data]=r1 r1=0xFFFF //IOBr1=0xFFFF //IOB 低电平输出低电平输出 [P_IOB_Dir]=r1[P_IOB_Dir]=r1 [P_IOB_Attrib] = r1[P_IOB_Attrib] = r1 r1=0r1=0 [P_IOA_Data]=r1[P_IOA_Data]=r1 INT OFFINT OFF

.include Hardwore.inc //.include Hardwore.inc // 硬件资源接口硬件资源接口

.define P_IOA_RL 0x7004.define P_IOA_RL 0x7004 // // P_IOA_LatchP_IOA_Latch

.CODE.CODE

.PUBLIC _main.PUBLIC _main_main:_main: r1=0 r1=0 //IOA //IOA 为带下拉电阻输入。为带下拉电阻输入。 [P_IOA_Dir]=r1[P_IOA_Dir]=r1 [P_IOA_Attr]=r1[P_IOA_Attr]=r1 [P_IOA_Data]=r1[P_IOA_Data]=r1 r1=0xFFFF //IOBr1=0xFFFF //IOB 低电平输出低电平输出 [P_IOB_Dir]=r1[P_IOB_Dir]=r1 [P_IOB_Attrib] = r1[P_IOB_Attrib] = r1 r1=0r1=0 [P_IOA_Data]=r1[P_IOA_Data]=r1 INT OFFINT OFF

Keydown:Keydown: R1= [P_IOA_Data]R1= [P_IOA_Data] CMP R1,0x0001CMP R1,0x0001 JNE JNE KeydownKeydownKeyup:Keyup: R1= [P_IOA_Data]R1= [P_IOA_Data] CMP R1,0x0000CMP R1,0x0000 JNE JNE KeyupKeyup R1=0xFFFFR1=0xFFFF [P_IOA_Data]=R1[P_IOA_Data]=R1 //LED//LED灭灭?? R1=0x0080R1=0x0080 [P_INT_Ctrl]=R1[P_INT_Ctrl]=R1 //// 开开 IRQ3_KEYIRQ3_KEY 中断中断 R1=[P_IOA_RL]R1=[P_IOA_RL] //// 激活键唤醒激活键唤醒 INT IRQINT IRQ R1=0x0007R1=0x0007 [P_SystemClock]=R1[P_SystemClock]=R1 //CPU//CPU 入睡入睡

Keydown:Keydown: R1= [P_IOA_Data]R1= [P_IOA_Data] CMP R1,0x0001CMP R1,0x0001 JNE JNE KeydownKeydownKeyup:Keyup: R1= [P_IOA_Data]R1= [P_IOA_Data] CMP R1,0x0000CMP R1,0x0000 JNE JNE KeyupKeyup R1=0xFFFFR1=0xFFFF [P_IOA_Data]=R1[P_IOA_Data]=R1 //LED//LED灭灭?? R1=0x0080R1=0x0080 [P_INT_Ctrl]=R1[P_INT_Ctrl]=R1 //// 开开 IRQ3_KEYIRQ3_KEY 中断中断 R1=[P_IOA_RL]R1=[P_IOA_RL] //// 激活键唤醒激活键唤醒 INT IRQINT IRQ R1=0x0007R1=0x0007 [P_SystemClock]=R1[P_SystemClock]=R1 //CPU//CPU 入睡入睡

R1= 0xFFFER1= 0xFFFE //// 低位为低位为 00 R4=0xFFFFR4=0xFFFF R4=R4 LSL 4R4=R4 LSL 4 //SR//SR 置全置全 11 R2=0xFFFFR2=0xFFFFL_Loopin:L_Loopin: R2 - =1R2 - =1 JNZ JNZ L_LoopinL_Loopin R1=R1 ROL 1R1=R1 ROL 1 ////循环左移循环左移 [P_IOB_Data]=R1[P_IOB_Data]=R1 //LED//LED显示显示 CMP R1,0xFF7FCMP R1,0xFF7F //// 是否最后一个是否最后一个 LEDLED JNE JNE L_LoopinL_Loopin R1=0xFFFER1=0xFFFE JMP JMP L_LoopinL_Loopin

R1= 0xFFFER1= 0xFFFE //// 低位为低位为 00 R4=0xFFFFR4=0xFFFF R4=R4 LSL 4R4=R4 LSL 4 //SR//SR 置全置全 11 R2=0xFFFFR2=0xFFFFL_Loopin:L_Loopin: R2 - =1R2 - =1 JNZ JNZ L_LoopinL_Loopin R1=R1 ROL 1R1=R1 ROL 1 ////循环左移循环左移 [P_IOB_Data]=R1[P_IOB_Data]=R1 //LED//LED显示显示 CMP R1,0xFF7FCMP R1,0xFF7F //// 是否最后一个是否最后一个 LEDLED JNE JNE L_LoopinL_Loopin R1=0xFFFER1=0xFFFE JMP JMP L_LoopinL_Loopin

这个循环起什这个循环起什么作用?么作用?

这个循环起什这个循环起什么作用?么作用?低位低位 LEDLED 会亮会亮吗?程序如何吗?程序如何修改?修改?

低位低位 LEDLED 会亮会亮吗?程序如何吗?程序如何修改?修改?// _IRQ3// _IRQ3 中断服务程序中断服务程序

.TEXT.TEXT

.PUBLIC _IRQ3.PUBLIC _IRQ3_IRQ3:_IRQ3: PUSH R1, R4 TO [SP]PUSH R1, R4 TO [SP] R1=0x0080R1=0x0080 TEST R1, [P_INT_Ctrl]TEST R1, [P_INT_Ctrl] JZ JZ L_NOTKeyArouseL_NOTKeyArouse R1=0x0080R1=0x0080 [P_INT_Clear]=R1[P_INT_Clear]=R1L_NOTKeyArouse:L_NOTKeyArouse: POP R1, R4 FROM [SP]POP R1, R4 FROM [SP] RETIRETI.END.END

// _IRQ3// _IRQ3 中断服务程序中断服务程序.TEXT.TEXT.PUBLIC _IRQ3.PUBLIC _IRQ3_IRQ3:_IRQ3: PUSH R1, R4 TO [SP]PUSH R1, R4 TO [SP] R1=0x0080R1=0x0080 TEST R1, [P_INT_Ctrl]TEST R1, [P_INT_Ctrl] JZ JZ L_NOTKeyArouseL_NOTKeyArouse R1=0x0080R1=0x0080 [P_INT_Clear]=R1[P_INT_Clear]=R1L_NOTKeyArouse:L_NOTKeyArouse: POP R1, R4 FROM [SP]POP R1, R4 FROM [SP] RETIRETI.END.END

交换后,高位交换后,高位 LELEDD会亮吗?程序会亮吗?程序

如何修改?如何修改?

交换后,高位交换后,高位 LELEDD会亮吗?程序会亮吗?程序

如何修改?如何修改? [P_IOB_Data]=R1 //LED[P_IOB_Data]=R1 //LED 显示显示 R1=R1 ROL 1R1=R1 ROL 1 // // 循环左移循环左移

CMP R1,0xFEFFCMP R1,0xFEFF

Page 11: 第 6 章 中断系统

用用 CC语言编写中断服务程序语言编写中断服务程序用用 CC语言编写中断服务程序语言编写中断服务程序

函数库函数库 SPCE061.LIBSPCE061.LIB 提供了相提供了相关的底层函数,中断服务程序可以关的底层函数,中断服务程序可以直接用这些函数来描述。直接用这些函数来描述。

函数库函数库 SPCE061.LIBSPCE061.LIB 提供了相提供了相关的底层函数,中断服务程序可以关的底层函数,中断服务程序可以直接用这些函数来描述。直接用这些函数来描述。

Page 12: 第 6 章 中断系统

SPCE061.LIBSPCE061.LIB 中与中断相关的函中与中断相关的函数数

函数原形:函数原形:void Set_INT_Ctrl(unsigned int);void Set_INT_Ctrl(unsigned int);void Set_INT_Mask(unsigned int);void Set_INT_Mask(unsigned int);unsigned int Get_INT_Ctrl(void);unsigned int Get_INT_Ctrl(void);unsigned int Get_INT_Mask(void);unsigned int Get_INT_Mask(void); void INT_Clear(unsigned int);void INT_Clear(unsigned int);void FIQ_ON(void )void FIQ_ON(void )void FIQ_OFF(void);void FIQ_OFF(void);void IRQ_ON(void);void IRQ_ON(void);void IRQ_OFF(void);void IRQ_OFF(void);void INT_FIQ(void);void INT_FIQ(void);void INT_IRQ(void);void INT_IRQ(void);void INT_FIQ_IRQ(void);void INT_FIQ_IRQ(void);void INT_OFF(void);void INT_OFF(void);

函数原形:函数原形:void Set_INT_Ctrl(unsigned int);void Set_INT_Ctrl(unsigned int);void Set_INT_Mask(unsigned int);void Set_INT_Mask(unsigned int);unsigned int Get_INT_Ctrl(void);unsigned int Get_INT_Ctrl(void);unsigned int Get_INT_Mask(void);unsigned int Get_INT_Mask(void); void INT_Clear(unsigned int);void INT_Clear(unsigned int);void FIQ_ON(void )void FIQ_ON(void )void FIQ_OFF(void);void FIQ_OFF(void);void IRQ_ON(void);void IRQ_ON(void);void IRQ_OFF(void);void IRQ_OFF(void);void INT_FIQ(void);void INT_FIQ(void);void INT_IRQ(void);void INT_IRQ(void);void INT_FIQ_IRQ(void);void INT_FIQ_IRQ(void);void INT_OFF(void);void INT_OFF(void);

FIQ_ON(); FIQ_ON(); FIQ ONFIQ ONFIQ_OFF(); FIQ_OFF(); FIQ OFFFIQ OFFIRQ_ON(); IRQ_ON(); IRQ ONIRQ ONIRQ_OFF(); IRQ_OFF(); IRQ OFFIRQ OFFINT_FIQ(); INT FIQINT_FIQ(); INT FIQINT_IRQ(); INT IRQINT_IRQ(); INT IRQINT_FIQ_IRQ(); INT INT_FIQ_IRQ(); INT FIQ_IRQFIQ_IRQINT_OFF(); INT OFFINT_OFF(); INT OFF

FIQ_ON(); FIQ_ON(); FIQ ONFIQ ONFIQ_OFF(); FIQ_OFF(); FIQ OFFFIQ OFFIRQ_ON(); IRQ_ON(); IRQ ONIRQ ONIRQ_OFF(); IRQ_OFF(); IRQ OFFIRQ OFFINT_FIQ(); INT FIQINT_FIQ(); INT FIQINT_IRQ(); INT IRQINT_IRQ(); INT IRQINT_FIQ_IRQ(); INT INT_FIQ_IRQ(); INT FIQ_IRQFIQ_IRQINT_OFF(); INT OFFINT_OFF(); INT OFF

Page 13: 第 6 章 中断系统

[例[例 6.46.4 ]] AA 口的口的 LEDLED 按按 1S1S 速率速率闪烁闪烁

#include “SPCE061.H”#include “SPCE061.H”main()main(){{

asm(“INT OFF”);asm(“INT OFF”);*P_IOA_Dir = 0x00FF;*P_IOA_Dir = 0x00FF;*P_IOA_Attib = 0x00FF;*P_IOA_Attib = 0x00FF;*P_IOA_DATA = 0x0000;*P_IOA_DATA = 0x0000; //A//A 口为输出,低电平。口为输出,低电平。*P_INT_Ctrl = C_IRQ5_2Hz;*P_INT_Ctrl = C_IRQ5_2Hz; //0004H//0004H P_INT_Ctrl P_INT_Ctrl asm(“INT IRQ”);asm(“INT IRQ”);while(1)while(1) ////死循环。死循环。 *P_Watchdog_Clear = C_WDTCLR*P_Watchdog_Clear = C_WDTCLR

}}

#include “SPCE061.H”#include “SPCE061.H”main()main(){{

asm(“INT OFF”);asm(“INT OFF”);*P_IOA_Dir = 0x00FF;*P_IOA_Dir = 0x00FF;*P_IOA_Attib = 0x00FF;*P_IOA_Attib = 0x00FF;*P_IOA_DATA = 0x0000;*P_IOA_DATA = 0x0000; //A//A 口为输出,低电平。口为输出,低电平。*P_INT_Ctrl = C_IRQ5_2Hz;*P_INT_Ctrl = C_IRQ5_2Hz; //0004H//0004H P_INT_Ctrl P_INT_Ctrl asm(“INT IRQ”);asm(“INT IRQ”);while(1)while(1) ////死循环。死循环。 *P_Watchdog_Clear = C_WDTCLR*P_Watchdog_Clear = C_WDTCLR

}}

#include “SPCE061.H”#include “SPCE061.H”unsigned int g_uioutput = 0;unsigned int g_uioutput = 0;void IRQ5(void)_attribute_((ISR))void IRQ5(void)_attribute_((ISR))void IRQ5(void)void IRQ5(void){{

if (*P_INT_Ctrl & 0x0004)if (*P_INT_Ctrl & 0x0004) { //IRQ5_2Hz{ //IRQ5_2Hz

*P_IOA_Data = g_uioutput;*P_IOA_Data = g_uioutput; g_uioutput ^=0xFFFF;g_uioutput ^=0xFFFF; //// 取反取反*P_INT_Clear = 0x0004;*P_INT_Clear = 0x0004; // C_IRQ5_2Hz// C_IRQ5_2Hz

}}else else { // IRQ5_4Hz { // IRQ5_4Hz

*P_INT_Clear = 0x0008;*P_INT_Clear = 0x0008; //C_IRQ5_4Hz//C_IRQ5_4Hz }}

}}

#include “SPCE061.H”#include “SPCE061.H”unsigned int g_uioutput = 0;unsigned int g_uioutput = 0;void IRQ5(void)_attribute_((ISR))void IRQ5(void)_attribute_((ISR))void IRQ5(void)void IRQ5(void){{

if (*P_INT_Ctrl & 0x0004)if (*P_INT_Ctrl & 0x0004) { //IRQ5_2Hz{ //IRQ5_2Hz

*P_IOA_Data = g_uioutput;*P_IOA_Data = g_uioutput; g_uioutput ^=0xFFFF;g_uioutput ^=0xFFFF; //// 取反取反*P_INT_Clear = 0x0004;*P_INT_Clear = 0x0004; // C_IRQ5_2Hz// C_IRQ5_2Hz

}}else else { // IRQ5_4Hz { // IRQ5_4Hz

*P_INT_Clear = 0x0008;*P_INT_Clear = 0x0008; //C_IRQ5_4Hz//C_IRQ5_4Hz }}

}}

如果不喜欢使用如果不喜欢使用 SPCE061.HSPCE061.H ,也不想包含,也不想包含 SPCE061.libSPCE061.lib,你也可以象下面这样写程,你也可以象下面这样写程序,其实,这里只是将序,其实,这里只是将 SPCE061.libSPCE061.lib中我们用到的部分代码摘出来了。中我们用到的部分代码摘出来了。volatile unsigned int *P_IOA_Data= (unsigned int*)(0x7000); // Data vector for Ivolatile unsigned int *P_IOA_Data= (unsigned int*)(0x7000); // Data vector for IOAOAvolatile unsigned int *P_IOA_Dir = (unsigned int*)(0x7002); // Direction vector fvolatile unsigned int *P_IOA_Dir = (unsigned int*)(0x7002); // Direction vector for IOAor IOAvolatile unsigned int *P_IOA_Attrib = (unsigned int*)(0x7003); // Attribute vectvolatile unsigned int *P_IOA_Attrib = (unsigned int*)(0x7003); // Attribute vector for IOAor for IOAvolatile unsigned int *P_IOB_Data = (unsigned int*)(0x7005); // Data vector for volatile unsigned int *P_IOB_Data = (unsigned int*)(0x7005); // Data vector for IOBIOBvolatile unsigned int *P_IOB_Dir = (unsigned int*)(0x7007); // Direction vector fvolatile unsigned int *P_IOB_Dir = (unsigned int*)(0x7007); // Direction vector for IOBor IOBvolatile unsigned int *P_IOB_Attrib = (unsigned int*)(0x7008); // Attribute vectvolatile unsigned int *P_IOB_Attrib = (unsigned int*)(0x7008); // Attribute vector for IOBor for IOB

如果不喜欢使用如果不喜欢使用 SPCE061.HSPCE061.H ,也不想包含,也不想包含 SPCE061.libSPCE061.lib,你也可以象下面这样写程,你也可以象下面这样写程序,其实,这里只是将序,其实,这里只是将 SPCE061.libSPCE061.lib中我们用到的部分代码摘出来了。中我们用到的部分代码摘出来了。volatile unsigned int *P_IOA_Data= (unsigned int*)(0x7000); // Data vector for Ivolatile unsigned int *P_IOA_Data= (unsigned int*)(0x7000); // Data vector for IOAOAvolatile unsigned int *P_IOA_Dir = (unsigned int*)(0x7002); // Direction vector fvolatile unsigned int *P_IOA_Dir = (unsigned int*)(0x7002); // Direction vector for IOAor IOAvolatile unsigned int *P_IOA_Attrib = (unsigned int*)(0x7003); // Attribute vectvolatile unsigned int *P_IOA_Attrib = (unsigned int*)(0x7003); // Attribute vector for IOAor for IOAvolatile unsigned int *P_IOB_Data = (unsigned int*)(0x7005); // Data vector for volatile unsigned int *P_IOB_Data = (unsigned int*)(0x7005); // Data vector for IOBIOBvolatile unsigned int *P_IOB_Dir = (unsigned int*)(0x7007); // Direction vector fvolatile unsigned int *P_IOB_Dir = (unsigned int*)(0x7007); // Direction vector for IOBor IOBvolatile unsigned int *P_IOB_Attrib = (unsigned int*)(0x7008); // Attribute vectvolatile unsigned int *P_IOB_Attrib = (unsigned int*)(0x7008); // Attribute vector for IOBor for IOB

ISR-interrupt service routine

Page 14: 第 6 章 中断系统

[例[例 6.56.5 ]不同中断入口的中断源程]不同中断入口的中断源程序举例。序举例。 LEDLED ,, AA 口为口为 1S1S 、、 BB 口口 0.0.5S5S 闪烁。闪烁。#include “SPCE061.H”#include “SPCE061.H”

#define TIMER_DATA_FOR_4KHz (65535-2048)#define TIMER_DATA_FOR_4KHz (65535-2048) //// 计数器初值计数器初值main()main(){{

asm(“INT OFF”);asm(“INT OFF”);*P_IOA_Dir = 0xFFFF;*P_IOA_Dir = 0xFFFF;*P_IOA_Attib = 0xFFFF;*P_IOA_Attib = 0xFFFF;*P_IOA_Data = 0x00FF;*P_IOA_Data = 0x00FF; //A //A 口为输出,低口为输出,低 88 位输出低电平。位输出低电平。*P_IOB_Dir = 0xFFFF;*P_IOB_Dir = 0xFFFF;*P_IOB_Attib = 0xFFFF;*P_IOB_Attib = 0xFFFF;*P_IOB_Data = 0x00FF;*P_IOB_Data = 0x00FF; //B //B 口为输出,低口为输出,低 88 位输出低电平。位输出低电平。*P_Timer_Data = TIMER_DATA_FOR_4KHz; *P_Timer_Data = TIMER_DATA_FOR_4KHz; //0.5S//0.5S ,, 20482048 次分次分

频频*P_Timer_Ctrl = C_SourceA_4096Hz*P_Timer_Ctrl = C_SourceA_4096Hz //0004H //0004H ( (P_Timer_Ctrl)P_Timer_Ctrl)*P_INT_Ctrl = C_IRQ4_1KHz*P_INT_Ctrl = C_IRQ4_1KHz | | C_IRQ2_TMB ; C_IRQ2_TMB ; //// 允许中断允许中断 asm(“INT IRQ”);asm(“INT IRQ”);while(1)while(1) ////死循环。死循环。 *P_Watchdog_Clear = C_WDTCLR*P_Watchdog_Clear = C_WDTCLR

}}

#include “SPCE061.H”#include “SPCE061.H”#define TIMER_DATA_FOR_4KHz (65535-2048)#define TIMER_DATA_FOR_4KHz (65535-2048) //// 计数器初值计数器初值main()main(){{

asm(“INT OFF”);asm(“INT OFF”);*P_IOA_Dir = 0xFFFF;*P_IOA_Dir = 0xFFFF;*P_IOA_Attib = 0xFFFF;*P_IOA_Attib = 0xFFFF;*P_IOA_Data = 0x00FF;*P_IOA_Data = 0x00FF; //A //A 口为输出,低口为输出,低 88 位输出低电平。位输出低电平。*P_IOB_Dir = 0xFFFF;*P_IOB_Dir = 0xFFFF;*P_IOB_Attib = 0xFFFF;*P_IOB_Attib = 0xFFFF;*P_IOB_Data = 0x00FF;*P_IOB_Data = 0x00FF; //B //B 口为输出,低口为输出,低 88 位输出低电平。位输出低电平。*P_Timer_Data = TIMER_DATA_FOR_4KHz; *P_Timer_Data = TIMER_DATA_FOR_4KHz; //0.5S//0.5S ,, 20482048 次分次分

频频*P_Timer_Ctrl = C_SourceA_4096Hz*P_Timer_Ctrl = C_SourceA_4096Hz //0004H //0004H ( (P_Timer_Ctrl)P_Timer_Ctrl)*P_INT_Ctrl = C_IRQ4_1KHz*P_INT_Ctrl = C_IRQ4_1KHz | | C_IRQ2_TMB ; C_IRQ2_TMB ; //// 允许中断允许中断 asm(“INT IRQ”);asm(“INT IRQ”);while(1)while(1) ////死循环。死循环。 *P_Watchdog_Clear = C_WDTCLR*P_Watchdog_Clear = C_WDTCLR

}}

#include “SPCE061.H”#include “SPCE061.H”unsigned int g_uiIOA_LED = 0xFFunsigned int g_uiIOA_LED = 0xFF , , g_uiIOB_LED = 0xFF;g_uiIOB_LED = 0xFF;unsigned int g_uiClockCnt = 0;unsigned int g_uiClockCnt = 0;void IRQ2(void)_attribute_((ISR))void IRQ2(void)_attribute_((ISR)) ;;void IRQ2(void)void IRQ2(void) //TimerB //TimerB 中断中断{{

*P_IOB_Data = g_uiIOB_LED *P_IOB_Data = g_uiIOB_LED ;; g_uiIOB_LED ^= 0xFFFF;g_uiIOB_LED ^= 0xFFFF; //// 取反取反*P_INT_Clear = 0x0400;*P_INT_Clear = 0x0400; // // 清该中断标志清该中断标志

}}void IRQ4(void)_attribute_((ISR))void IRQ4(void)_attribute_((ISR)) ;;void IRQ4(void)void IRQ4(void){{

IF *P_INT_Ctrl & C_IRQ4_1KHzIF *P_INT_Ctrl & C_IRQ4_1KHz // // 如果是如果是 IRQ4_1KHzIRQ4_1KHz 中中断断

{{ IF g_uiClockCnt <1024IF g_uiClockCnt <1024 ////且计数器且计数器 <1024<1024 g_uiClockCnt++ ;g_uiClockCnt++ ; // // 计数器加计数器加 11

#include “SPCE061.H”#include “SPCE061.H”unsigned int g_uiIOA_LED = 0xFFunsigned int g_uiIOA_LED = 0xFF , , g_uiIOB_LED = 0xFF;g_uiIOB_LED = 0xFF;unsigned int g_uiClockCnt = 0;unsigned int g_uiClockCnt = 0;void IRQ2(void)_attribute_((ISR))void IRQ2(void)_attribute_((ISR)) ;;void IRQ2(void)void IRQ2(void) //TimerB //TimerB 中断中断{{

*P_IOB_Data = g_uiIOB_LED *P_IOB_Data = g_uiIOB_LED ;; g_uiIOB_LED ^= 0xFFFF;g_uiIOB_LED ^= 0xFFFF; //// 取反取反*P_INT_Clear = 0x0400;*P_INT_Clear = 0x0400; // // 清该中断标志清该中断标志

}}void IRQ4(void)_attribute_((ISR))void IRQ4(void)_attribute_((ISR)) ;;void IRQ4(void)void IRQ4(void){{

IF *P_INT_Ctrl & C_IRQ4_1KHzIF *P_INT_Ctrl & C_IRQ4_1KHz // // 如果是如果是 IRQ4_1KHzIRQ4_1KHz 中中断断

{{ IF g_uiClockCnt <1024IF g_uiClockCnt <1024 ////且计数器且计数器 <1024<1024 g_uiClockCnt++ ;g_uiClockCnt++ ; // // 计数器加计数器加 11

ELSEELSE {{

*P_IOA_Data = g_uiIOA_LED *P_IOA_Data = g_uiIOA_LED ;; ////显示显示 g_uiIOA_LED ^= 0xFFFF;g_uiIOA_LED ^= 0xFFFF; //// 取反,下一个显示状态取反,下一个显示状态 g_uiClockCnt = 0g_uiClockCnt = 0 //// 计数器清计数器清 00*P_INT_Clear = C_IRQ4_1KHz;*P_INT_Clear = C_IRQ4_1KHz; // // 清该中断标志清该中断标志

}}}}IF *P_INT_Ctrl & C_IRQ4_2KHzIF *P_INT_Ctrl & C_IRQ4_2KHz //// 如果是如果是 IRQ4_2KHzIRQ4_2KHz{{ *P_INT_Clear = C_IRQ4_2KHz; // *P_INT_Clear = C_IRQ4_2KHz; // 清清 IRQ4_2KHzIRQ4_2KHz 中断标志中断标志}}IF *P_INT_Ctrl & C_IRQ4_4KHz //IF *P_INT_Ctrl & C_IRQ4_4KHz // 如果是如果是 IRQ4_4KHzIRQ4_4KHz{{ *P_INT_Clear = C_IRQ4_4KHz; // *P_INT_Clear = C_IRQ4_4KHz; // 清清 IRQ4_4KHzIRQ4_4KHz 中断标志中断标志}}

}}

ELSEELSE {{

*P_IOA_Data = g_uiIOA_LED *P_IOA_Data = g_uiIOA_LED ;; ////显示显示 g_uiIOA_LED ^= 0xFFFF;g_uiIOA_LED ^= 0xFFFF; //// 取反,下一个显示状态取反,下一个显示状态 g_uiClockCnt = 0g_uiClockCnt = 0 //// 计数器清计数器清 00*P_INT_Clear = C_IRQ4_1KHz;*P_INT_Clear = C_IRQ4_1KHz; // // 清该中断标志清该中断标志

}}}}IF *P_INT_Ctrl & C_IRQ4_2KHzIF *P_INT_Ctrl & C_IRQ4_2KHz //// 如果是如果是 IRQ4_2KHzIRQ4_2KHz{{ *P_INT_Clear = C_IRQ4_2KHz; // *P_INT_Clear = C_IRQ4_2KHz; // 清清 IRQ4_2KHzIRQ4_2KHz 中断标志中断标志}}IF *P_INT_Ctrl & C_IRQ4_4KHz //IF *P_INT_Ctrl & C_IRQ4_4KHz // 如果是如果是 IRQ4_4KHzIRQ4_4KHz{{ *P_INT_Clear = C_IRQ4_4KHz; // *P_INT_Clear = C_IRQ4_4KHz; // 清清 IRQ4_4KHzIRQ4_4KHz 中断标志中断标志}}

}}

Page 15: 第 6 章 中断系统

【实验六】IRQ4 中断实验

Page 16: 第 6 章 中断系统

LED闪亮1KHz 中断控制

2KHz 中断控制

4KHz 中断控制

1KHz 中断, 1mS 中断。2KHz 中断, 0.5mS 中断。4KHz 中断, 0.25mS 中断。

Page 17: 第 6 章 中断系统

寄存器组压栈保护寄存器组压栈保护

1KHz 中断 ?

>0.25S?

TIME4+1TIME4+1

LED亮

TIME4 清 0

清清 4KHz4KHz 中断标志中断标志

LED灭

>0.5S?

寄存器组出栈恢复寄存器组出栈恢复

>1S?

TIME1+1

LED亮

TIME1 清 0

清清 1KHz 中断标志中断标志

>2S?

中断返回中断返回

Y Y

Y Y

IRQ4IRQ4 中断程序中断程序

Y

2KHz 中断 ?

>0.5S?

TIME2+1TIME2+1

LED亮

TIME2 清 0

清清 2KHz2KHz 中断标志中断标志

LED灭

>1S?

Y

Y

LED灭

否则, 4KHz 中断

Y

N

IOA0,1IOA0,1IOA4,7IOA4,7

IOA2,3IOA2,3

Page 18: 第 6 章 中断系统

程序设计程序设计.DEFINE P_IOA_DATA 0x7000 .DEFINE P_IOA_DATA 0x7000 .DEFINE P_IOA_DIR 0x7002 .DEFINE P_IOA_DIR 0x7002 .DEFINE P_IOA_ATTRI 0x7003.DEFINE P_IOA_ATTRI 0x7003.DEFINE P_INT_Ctrl 0x7010 .DEFINE P_INT_Ctrl 0x7010 .DEFINE P_INT_CLEAR 0x7011 .DEFINE P_INT_CLEAR 0x7011 .DEFINE P_WATCHDOG_CLEAR 0x7012.DEFINE P_WATCHDOG_CLEAR 0x7012.RAM.RAM.VAR TIME1 //1KHz.VAR TIME1 //1KHz 计数器计数器.VAR TIME2 //2KHz.VAR TIME2 //2KHz 计数器计数器.VAR TIME4 //4KHz.VAR TIME4 //4KHz 计数器计数器.CODE .CODE .PUBLIC _main //.PUBLIC _main // 主程序 主程序 _main: _main: INT offINT offR1=0xffff //r1R1=0xffff //r1 的值为的值为 0xffff 0xffff [P_IOA_ATTRI]=r1 //IOA[P_IOA_ATTRI]=r1 //IOA 口设置为同相低电平输口设置为同相低电平输出出[P_IOA_DIR]=r1 ;[P_IOA_DIR]=r1 ;R1=0R1=0[P_IOA_DATA]=r1;[P_IOA_DATA]=r1;

.DEFINE P_IOA_DATA 0x7000 .DEFINE P_IOA_DATA 0x7000

.DEFINE P_IOA_DIR 0x7002 .DEFINE P_IOA_DIR 0x7002

.DEFINE P_IOA_ATTRI 0x7003.DEFINE P_IOA_ATTRI 0x7003

.DEFINE P_INT_Ctrl 0x7010 .DEFINE P_INT_Ctrl 0x7010

.DEFINE P_INT_CLEAR 0x7011 .DEFINE P_INT_CLEAR 0x7011

.DEFINE P_WATCHDOG_CLEAR 0x7012.DEFINE P_WATCHDOG_CLEAR 0x7012

.RAM.RAM

.VAR TIME1 //1KHz.VAR TIME1 //1KHz 计数器计数器

.VAR TIME2 //2KHz.VAR TIME2 //2KHz 计数器计数器

.VAR TIME4 //4KHz.VAR TIME4 //4KHz 计数器计数器

.CODE .CODE

.PUBLIC _main //.PUBLIC _main // 主程序 主程序 _main: _main: INT offINT offR1=0xffff //r1R1=0xffff //r1 的值为的值为 0xffff 0xffff [P_IOA_ATTRI]=r1 //IOA[P_IOA_ATTRI]=r1 //IOA 口设置为同相低电平输口设置为同相低电平输出出[P_IOA_DIR]=r1 ;[P_IOA_DIR]=r1 ;R1=0R1=0[P_IOA_DATA]=r1;[P_IOA_DATA]=r1;

R1=0x0070R1=0x0070[P_INT_Ctrl ]=R1[P_INT_Ctrl ]=R1R1=0R1=0[TIME1]=R1[TIME1]=R1[TIME2]=R1[TIME2]=R1[TIME4]=R1[TIME4]=R1INT onINT onLoopLoop::R1=1R1=1[P_WATCHDOG_CLEAR]=R1[P_WATCHDOG_CLEAR]=R1JMP JMP LoopLoop//============================//============================.TEXT.TEXT.PUBLIC _IRQ4.PUBLIC _IRQ4_IRQ4:_IRQ4:PUSH R1,R5 TO [SP]PUSH R1,R5 TO [SP]R1 = 0x0010; //R1 = 0x0010; // 中断识别中断识别TEST R1,[P_INT_Ctrl]; //TEST R1,[P_INT_Ctrl]; // 是是 1KHz?1KHz? JNZ JNZ L_IRQ4_1KHzL_IRQ4_1KHz;;R1 = 0x0020;R1 = 0x0020;TEST R1,[P_INT_Ctrl]; //TEST R1,[P_INT_Ctrl]; // 是是 2KHz?2KHz? JNZ JNZ L_IRQ4_2KHzL_IRQ4_2KHz;;

R1=0x0070R1=0x0070[P_INT_Ctrl ]=R1[P_INT_Ctrl ]=R1R1=0R1=0[TIME1]=R1[TIME1]=R1[TIME2]=R1[TIME2]=R1[TIME4]=R1[TIME4]=R1INT onINT onLoopLoop::R1=1R1=1[P_WATCHDOG_CLEAR]=R1[P_WATCHDOG_CLEAR]=R1JMP JMP LoopLoop//============================//============================.TEXT.TEXT.PUBLIC _IRQ4.PUBLIC _IRQ4_IRQ4:_IRQ4:PUSH R1,R5 TO [SP]PUSH R1,R5 TO [SP]R1 = 0x0010; //R1 = 0x0010; // 中断识别中断识别TEST R1,[P_INT_Ctrl]; //TEST R1,[P_INT_Ctrl]; // 是是 1KHz?1KHz? JNZ JNZ L_IRQ4_1KHzL_IRQ4_1KHz;;R1 = 0x0020;R1 = 0x0020;TEST R1,[P_INT_Ctrl]; //TEST R1,[P_INT_Ctrl]; // 是是 2KHz?2KHz? JNZ JNZ L_IRQ4_2KHzL_IRQ4_2KHz;;

L_IRQ4_4KHz:L_IRQ4_4KHz: R2=[R2=[TIME4TIME4] //] //TIME4TIME4 计数器计数器 +1+1R2+=1R2+=1[[TIME4TIME4]=R2]=R2R1=[P_IOA_DATA] //R1=[P_IOA_DATA] // 读读 AA引脚状态引脚状态CMP R2CMP R2 ,, 0x04000x0400 //// 是否是否≤≤ 0.25S?0.25S?JBE JBE LED4KHz_OFFLED4KHz_OFF //// 是是 , LED, LED灭灭R1|=0x00F0R1|=0x00F0 //// 否否 ,4,4 ~~ 7 LED7 LED亮亮[P_IOA_DATA]=R1[P_IOA_DATA]=R1CMP R2,0x0800CMP R2,0x0800 //// 是否是否≤≤ 0.5S?0.5S?JBE JBE LED4KHz_RETLED4KHz_RET //// 是是 , 4, 4 ~~ 7 LED7 LED继续继续亮亮中断返回中断返回R2=0R2=0 //// 否否 ,,清清 TIME4,TIME4,在下一次中断灭在下一次中断灭[TIME4]=R2[TIME4]=R2JMP LED4KHz_RETJMP LED4KHz_RETLED4Hz_OFF:LED4Hz_OFF:R1&=0xFF0F // 4R1&=0xFF0F // 4 ~~ 7 LED7 LED灭灭[P_IOA_DATA]=R1[P_IOA_DATA]=R1LED4Hz_RET:LED4Hz_RET:R1=0x0040R1=0x0040[P_INT_Clear] = R1; //[P_INT_Clear] = R1; // 清中断清中断POP R1,R5 FROM [SP];POP R1,R5 FROM [SP];RETI;RETI;

L_IRQ4_4KHz:L_IRQ4_4KHz: R2=[R2=[TIME4TIME4] //] //TIME4TIME4 计数器计数器 +1+1R2+=1R2+=1[[TIME4TIME4]=R2]=R2R1=[P_IOA_DATA] //R1=[P_IOA_DATA] // 读读 AA引脚状态引脚状态CMP R2CMP R2 ,, 0x04000x0400 //// 是否是否≤≤ 0.25S?0.25S?JBE JBE LED4KHz_OFFLED4KHz_OFF //// 是是 , LED, LED灭灭R1|=0x00F0R1|=0x00F0 //// 否否 ,4,4 ~~ 7 LED7 LED亮亮[P_IOA_DATA]=R1[P_IOA_DATA]=R1CMP R2,0x0800CMP R2,0x0800 //// 是否是否≤≤ 0.5S?0.5S?JBE JBE LED4KHz_RETLED4KHz_RET //// 是是 , 4, 4 ~~ 7 LED7 LED继续继续亮亮中断返回中断返回R2=0R2=0 //// 否否 ,,清清 TIME4,TIME4,在下一次中断灭在下一次中断灭[TIME4]=R2[TIME4]=R2JMP LED4KHz_RETJMP LED4KHz_RETLED4Hz_OFF:LED4Hz_OFF:R1&=0xFF0F // 4R1&=0xFF0F // 4 ~~ 7 LED7 LED灭灭[P_IOA_DATA]=R1[P_IOA_DATA]=R1LED4Hz_RET:LED4Hz_RET:R1=0x0040R1=0x0040[P_INT_Clear] = R1; //[P_INT_Clear] = R1; // 清中断清中断POP R1,R5 FROM [SP];POP R1,R5 FROM [SP];RETI;RETI;

L_IRQ4_1KHz:L_IRQ4_1KHz: R2=[R2=[TIME1TIME1] ] //// 计数器计数器 +1+1R2+=1R2+=1[[TIME1TIME1]=R2]=R2R1=[P_IOA_DATA]R1=[P_IOA_DATA]CMP R2CMP R2 ,, 0x04000x0400 //// 是否是否 1S?1S?JBE JBE LED1KHz_OFF //LED1KHz_OFF //小于等于小于等于 , LED, LED灭灭R1|=0x0003 R1|=0x0003 //// 否则否则 ,0,0 ~~ 1LED1LED[P_IOA_DATA]=R1[P_IOA_DATA]=R1CMP R2,0800 CMP R2,0800 //// 是否是否 2S?2S?JBE JBE LED1KHz_RET //LED1KHz_RET //小于等于小于等于 , 0, 0 ~~ 1LED1LED继续亮继续亮 ,,中断中断返回返回R2=0 R2=0 //// 是是 , , 清清 TIME1 TIME1 ,, 在下一次中断灭在下一次中断灭[TIME1]=R2[TIME1]=R2JMP LED2Hz_RETJMP LED2Hz_RETLED1KHz_OFF:LED1KHz_OFF:R1&=0xFFFCR1&=0xFFFC[P_IOA_DATA]=R1[P_IOA_DATA]=R1LED1KHz_RET:LED1KHz_RET:R1=0x0010R1=0x0010[P_INT_Clear] = R1; //[P_INT_Clear] = R1; // 清中断清中断POP R1,R5 FROM [SP];POP R1,R5 FROM [SP];RETI;RETI;

L_IRQ4_1KHz:L_IRQ4_1KHz: R2=[R2=[TIME1TIME1] ] //// 计数器计数器 +1+1R2+=1R2+=1[[TIME1TIME1]=R2]=R2R1=[P_IOA_DATA]R1=[P_IOA_DATA]CMP R2CMP R2 ,, 0x04000x0400 //// 是否是否 1S?1S?JBE JBE LED1KHz_OFF //LED1KHz_OFF //小于等于小于等于 , LED, LED灭灭R1|=0x0003 R1|=0x0003 //// 否则否则 ,0,0 ~~ 1LED1LED[P_IOA_DATA]=R1[P_IOA_DATA]=R1CMP R2,0800 CMP R2,0800 //// 是否是否 2S?2S?JBE JBE LED1KHz_RET //LED1KHz_RET //小于等于小于等于 , 0, 0 ~~ 1LED1LED继续亮继续亮 ,,中断中断返回返回R2=0 R2=0 //// 是是 , , 清清 TIME1 TIME1 ,, 在下一次中断灭在下一次中断灭[TIME1]=R2[TIME1]=R2JMP LED2Hz_RETJMP LED2Hz_RETLED1KHz_OFF:LED1KHz_OFF:R1&=0xFFFCR1&=0xFFFC[P_IOA_DATA]=R1[P_IOA_DATA]=R1LED1KHz_RET:LED1KHz_RET:R1=0x0010R1=0x0010[P_INT_Clear] = R1; //[P_INT_Clear] = R1; // 清中断清中断POP R1,R5 FROM [SP];POP R1,R5 FROM [SP];RETI;RETI;

L_IRQ4_2KHz:L_IRQ4_2KHz: R2=[R2=[TIME2TIME2] ] //// 计数器计数器 +1+1R2+=1R2+=1[[TIME2TIME2]=R2]=R2R1=[P_IOA_DATA]R1=[P_IOA_DATA]CMP R2CMP R2 ,, 0x04000x0400 //// 是否是否≤≤ 0.5S?0.5S?JBE JBE LED2KHz_OFF //LED2KHz_OFF //小于等于小于等于 , LED, LED灭灭R1|=0x000C R1|=0x000C //// 否则否则 ,,22 ~~ 33 LED LED亮亮[P_IOA_DATA]=R1[P_IOA_DATA]=R1CMP R2,0800 CMP R2,0800 //// 是否是否小于等于小于等于 1S?1S?JBE JBE LED2KHz_RET //LED2KHz_RET //小于等于小于等于 , 2, 2 ~~ 3 LED3 LED继续亮继续亮 ,,中断中断返回返回R2=0 R2=0 //// 否则否则 ,,清清 TIME2 TIME2 ,, 在下一次中断灭在下一次中断灭[TIME2]=R2[TIME2]=R2JMP LED2KHz_RETJMP LED2KHz_RETLED2KHz_OFF:LED2KHz_OFF:R1&=0xFFF3R1&=0xFFF3[P_IOA_DATA]=R1[P_IOA_DATA]=R1LED2KHz_RET:LED2KHz_RET:R1=0x0010R1=0x0010[P_INT_Clear] = R1; //[P_INT_Clear] = R1; // 清中断清中断POP R1,R5 FROM [SP];POP R1,R5 FROM [SP];RETI;RETI;

L_IRQ4_2KHz:L_IRQ4_2KHz: R2=[R2=[TIME2TIME2] ] //// 计数器计数器 +1+1R2+=1R2+=1[[TIME2TIME2]=R2]=R2R1=[P_IOA_DATA]R1=[P_IOA_DATA]CMP R2CMP R2 ,, 0x04000x0400 //// 是否是否≤≤ 0.5S?0.5S?JBE JBE LED2KHz_OFF //LED2KHz_OFF //小于等于小于等于 , LED, LED灭灭R1|=0x000C R1|=0x000C //// 否则否则 ,,22 ~~ 33 LED LED亮亮[P_IOA_DATA]=R1[P_IOA_DATA]=R1CMP R2,0800 CMP R2,0800 //// 是否是否小于等于小于等于 1S?1S?JBE JBE LED2KHz_RET //LED2KHz_RET //小于等于小于等于 , 2, 2 ~~ 3 LED3 LED继续亮继续亮 ,,中断中断返回返回R2=0 R2=0 //// 否则否则 ,,清清 TIME2 TIME2 ,, 在下一次中断灭在下一次中断灭[TIME2]=R2[TIME2]=R2JMP LED2KHz_RETJMP LED2KHz_RETLED2KHz_OFF:LED2KHz_OFF:R1&=0xFFF3R1&=0xFFF3[P_IOA_DATA]=R1[P_IOA_DATA]=R1LED2KHz_RET:LED2KHz_RET:R1=0x0010R1=0x0010[P_INT_Clear] = R1; //[P_INT_Clear] = R1; // 清中断清中断POP R1,R5 FROM [SP];POP R1,R5 FROM [SP];RETI;RETI;

Page 19: 第 6 章 中断系统

本章小结本章小结掌握中断系统的一般概念掌握中断系统的一般概念

CPUCPU 对对 I/OI/O 设备管理的方式设备管理的方式 中断优先级及中断嵌套中断优先级及中断嵌套 开中断与关中断开中断与关中断 中断响应过程中断响应过程

掌握掌握 µµ’nSP’nSPTMTM 中断系统的基本特点中断系统的基本特点– 中断中断源、源、中断中断事件、事件、中断优先级、中断中断优先级、中断向量、向量、

中断响应中断响应µµ’nSP’nSPTMTM 系统的中断程序设计系统的中断程序设计

掌握中断系统的一般概念掌握中断系统的一般概念 CPUCPU 对对 I/OI/O 设备管理的方式设备管理的方式 中断优先级及中断嵌套中断优先级及中断嵌套 开中断与关中断开中断与关中断 中断响应过程中断响应过程

掌握掌握 µµ’nSP’nSPTMTM 中断系统的基本特点中断系统的基本特点– 中断中断源、源、中断中断事件、事件、中断优先级、中断中断优先级、中断向量、向量、

中断响应中断响应µµ’nSP’nSPTMTM 系统的中断程序设计系统的中断程序设计

作业:作业:P106 3P106 3 、、 66 、、

作业:作业:P106 3P106 3 、、 66 、、

Page 20: 第 6 章 中断系统

寄存器组压栈保护寄存器组压栈保护

TMB2 中断 ?

>1S?

计数器计数器 +1+1

LED亮

计数器清 0

清清 Timer2Timer2 中断标志中断标志

LED灭

>2S?

寄存器组出栈恢复寄存器组出栈恢复

>0.5S?

计数器 +1

LED亮

计数器清 0

清清 Timer4Timer4 中断标志中断标志

LED灭

>1S?

中断返回中断返回

Y Y

Y Y

IRQ6IRQ6 中断程序中断程序

[例[例 6.36.3 ]]

Page 21: 第 6 章 中断系统

[例[例 6.36.3 ]程]程序序

.include hardware.inc.include hardware.inc

.DEFINE timea_clk 0x020d ;.DEFINE timea_clk 0x020d ;

.DEFINE timeb_clk 0x0004 ;.DEFINE timeb_clk 0x0004 ;

.RAM.RAM

.VAR TA_Flag.VAR TA_Flag

.VAR TB_Flag.VAR TB_Flag

.PUBLIC _main //.PUBLIC _main // 主程序主程序_main:_main:INT offINT offR1=0xffffR1=0xffff[P_IOA_ATTRI]=r1 //IOA[P_IOA_ATTRI]=r1 //IOA 口设置为同相低电平输出口设置为同相低电平输出[P_IOA_DIR]=r1[P_IOA_DIR]=r1R1=0R1=0[P_IOA_DATA]=r1;[P_IOA_DATA]=r1;R1=0xffffR1=0xffff[P_IOB_ATTRI]=r1 //IOB[P_IOB_ATTRI]=r1 //IOB 口设置为同相高电平输出口设置为同相高电平输出[P_IOB_DIR]=r1[P_IOB_DIR]=r1R1=0R1=0[P_IOB_DATA]=r1;[P_IOB_DATA]=r1;

R1=0xFF9F[P_TimerA_Data]=R1[P_TimerB_Data]=R1R1= timea_clk timea_clk [P_TimerA_Ctrl]=R1[P_TimerA_Ctrl]=R1R2=0000000000000100BR2=0000000000000100BR1=0010000000000000BR1=0010000000000000BR1 | =R2R1 | =R2[P_INT_Ctrl]=R1[P_INT_Ctrl]=R1INT IRQ,FIQINT IRQ,FIQL_LOOP:L_LOOP:NOPNOPNOPNOPNOPNOPJMP L_LOOPJMP L_LOOP

.TEXT.TEXT

.PUBLIC _FIQ.PUBLIC _FIQ_FIQ:_FIQ:PUSH R1,R5 TO [SP]PUSH R1,R5 TO [SP]R1 = 0x0800; R1 = 0x0800; //// 中断识别中断识别TEST R1,[P_INT_Ctrl]; TEST R1,[P_INT_Ctrl]; //// 是是 FIQ_TMB?FIQ_TMB? JNZ JNZ L_FIQ_TMBL_FIQ_TMB;;R1 = 0x0200; R1 = 0x0200; //// 否否 ,,TEST R1,[P_INT_Ctrl]; TEST R1,[P_INT_Ctrl]; //// 是是 FIQ_TMAFIQ_TMA ? ?JNZ JNZ L_FIQ_TMAL_FIQ_TMA;;L_FIQ_PWM:L_FIQ_PWM: //// 否否 ,,是是 FIQ_PWFIQ_PWMMR1=0x8000R1=0x8000[P_INT_Clear]=R1[P_INT_Clear]=R1POP R1,R5 FROM [SP]POP R1,R5 FROM [SP]RETIRETI

L_FIQ_TMA:L_FIQ_TMA:R1=[TA_Flag]R1=[TA_Flag]R1R1^̂=0xFFFF=0xFFFF[P_IOA_Data]=R1[P_IOA_Data]=R1[TA_Flag]=R1[TA_Flag]=R1R1=0x0200R1=0x0200[P_INT_Clear]=R1[P_INT_Clear]=R1POP R1,R5 FROM [SP]POP R1,R5 FROM [SP]RETIRETIL_FIQ_TMB:L_FIQ_TMB:R1=0x0800R1=0x0800[P_INT_Clear]=R1[P_INT_Clear]=R1POP R1,R5 FROM [SP]POP R1,R5 FROM [SP]RETIRETI

Page 22: 第 6 章 中断系统

主程序主程序

初始化初始化 AA 、、 BB 口口关中断关中断

S1S1 键按下吗?键按下吗?

松开松开 S1S1 键吗?键吗?

LEDLED灯灭灯灭

设置中断设置中断开中断开中断

系统进入睡眠状态系统进入睡眠状态

循环点亮循环点亮 LEDLED

有键按下吗?有键按下吗?

Y

Y

Y

NN

N

Page 23: 第 6 章 中断系统

IOA0

IOA1

IOA2

IOA3

IOA4

IOA5

IOA6

IOA7

R×8