计数 组_中断响应条件
最编程
2024-10-13 18:06:13
...
2024.10.13:计算机组成原理学习笔记
中断响应条件
- 条件1:CPU要处于开中断状态
- 条件2:至少要有一个未被屏蔽的中断请求
- 屏蔽?
- 中断优先级
- 屏蔽字的作用
- 条件3:当前指令刚执行完
条件1:CPU要处于开中断状态
当CPU处于开中断状态,我们才可以检测中断,此处没有考虑不可屏蔽中断,在大部分情况下,不可屏蔽中断是不能发生的,其次,不可屏蔽中断没有响应周期,只要检测到,立刻就去处理
条件2:至少要有一个未被屏蔽的中断请求
没有中断请求就不会响应
屏蔽?
对于一个外部中断,我们处理它的时候其实是分了两个阶段:响应、处理(执行服务程序)
(单级中断)不存在屏不屏蔽,屏不屏蔽指的是(多重中断)(在处理一个中断的时候出现了第二个中断请求或者同时出现了多个中断请求)
中断优先级
由于中断的处理分成了两个阶段,我们要先响应再处理,因此对于优先级来说,它也有两种
首先是(响应优先级),它处理的是如果多个中断源同时到达了,我应该先响应谁
- 中断响应优先级看题干(硬件的判优电路判出了一个优先级,指的就是响应优先级):由(查询程序或者中断判优电路)决定优先权,反映的是多个中断同时请求时选择哪个先被响应
其次是(处理优先级),响应之后,要执行这个中断源对应的中断服务程序
- 由(各自的中断屏蔽字)来动态设定的,反应了本中断与其他所有中断之间的处理优先级,在多重中断系统中通常用中断屏蔽字来对中断优先权进行动态分配
屏蔽字的作用
中断屏蔽:中断系统允许CPU在执行某个中断服务程序时被新的中断请求打断,但有些紧急的中断不允许被新的中断打断,这就是中断屏蔽的概念,通过中断屏蔽字来实现该功能
每一个中断源都会有一个自己的中断屏蔽字,系统可能会发生哪些中断,对应的屏蔽字就会有多少位,假设下列表格对应的这个计算机系统总共就只有四种中断
条件3:当前指令刚执行完
在非流水线处理器中,PC此时存放下条指令的地址
不管是(可屏蔽中断)还是(不可屏蔽中断),CPU都是会在一条指令执行完,采取检测这个引脚
上一篇: 路由通信 VLAN 技术
下一篇: Vue3 基本语法
推荐阅读
-
计数 组_中断响应条件
-
韦根26协议读头的使用及proteus仿真-模拟韦根26读头的数据发送 使用定时器T1,采用16位定时器方式。 //8051 T1初始化 void Timer1_init { TMOD=0x10; //T1 16位定时器模式 ET1=0; //关闭定时器中断 TR1=0; //关闭定时器 TF1=0; //清除TF1标志 } 例如,就发送上面的这个数据:01000110111000001001010101 十进制的18580053 发送数据0的时候,就是将数据线D0拉低404us,发送数据1的时候,就是将数据线D1拉低404us。 首先设置定时器初值,用STC的下载器计算404us的预装入值。 拉低数据线,等待404us到时,之后抬高数据线,再等待2ms的时间,一位数据就发送完成了。 void Send_bit(bit bD) { //拉低数据线D0 404us TL1 = 0x8C; //设置定时初值 TH1 = 0xFE; //设置定时初值 if(bD==0) Send_D0=0; else Send_D1=0; TR1=1; //开启定时器 while(TF1 ==0); //等待溢出 //时间到抬高数据线 if(bD==0) Send_D0=1; else Send_D1=1; TF1=0; //清溢出标志 TR1=0; //关定时器 //下面是数据位的间隔 2ms TL1 = 0xCD; //设置定时初值 TH1 = 0xF8; //设置定时初值 TR1=1; //开启定时器 while(TF1 ==0); //等待溢出 TF1=0; //清溢出标志 TR1=0; //关定时器 } 将韦根26协议的数据装入一个无符号长整型变量里: //二进制 0 100011011100000100101010 1 头尾两位为奇偶校验位,十进制是18580053 unsigned long WG26=18580053; 无符号长整型是四个字节32位,装入26位的数据,则最前面的6位是无效的,循环移位6次,把无效数据移除。 //000000 01000110111000001001010101 for(i=0; i<6; i++) { WGdata=WGdata<<1; } //现在WGdata中的数据是 01000110111000001001010101 000000,后面多了6个0。 有效数据已经移动到最前面,可以开始发送了,循环26次发送数据 for(i=0; i<26; i++) { if( (WGdata & 0x80000000) == 0x80000000 ) Send_bit(1); //如果最高位为1,发送1 else Send_bit(0); //如果最高位为0,发送0 WGdata=WGdata<<1; //左移1位 } } 完整发送函数: //发送韦根26数据,用4个字节保存,一共32位 void SendWG26(unsigned long WGdata) { uchar data i; //从最高位开始发送数据,将开头的6个无效数据位隔过去 //18580053 //000000 01000110111000001001010101 //01000110111000001001010101 000000 for(i=0; i<6; i++) { WGdata=WGdata<<1; } //有效数据位已经移到了开头,开始发送数据 for(i=0; i<26; i++) { if( (WGdata & 0x80000000) == 0x80000000 ) Send_bit(1); else Send_bit(0); WGdata=WGdata<<1; } } 数据的接收 将数据线D0,D1连接到与门74HC08上,两条数据线上有数据发送时会产生INT0的下降沿中断。 (这只是仿真图,实际硬件连接有所不同) 在中断服务程序中接收数据: 还是用一个节的无符号长整型数据WG26,将收到的数据记入其最低位。每接到一位数据,左移一次。当接收到26个数据时,认为收到了读头发来的完整数据。设置接收完成标志ReceiveFlag=1;供主程序查询。 这里设置了一个超时检测,就是接收到的两位数据之间的时间间隔如果大于5ms就认为数据超时,(因为读头发来的数据每位之间的间隔是2ms)。这样,如果有意外的脉冲干扰,引起计数数据位的count值错误,也只会产生一次数据接收错误,将各种标志和变量全部清零后,不会影响下一次的数据接收。 在中断服务程序退出之前,一定要清除中断标志IE0,以免响应了无效数据的中断标志,产生接收错误。 void INT0_ISR(void) interrupt 0 //外部中断0服务程序 { //如果接到的两位数据之间间隔超过5ms,定时器溢出标志TF1置位 //超时检测使用定时器T1,16位定时方式 EX0=0; //关中断 //如果有定时器超时标志置位 if(TF1==1) //数据有误,放弃数据 { LCD_StrDisp(0x00,"Try Again "); LCD_StrDisp(0x40,"TimeOut Error "); Beep(10); //隔过至少一个数据包的时间,以便放弃不完整的数据 //延时100ms Delay50ms; Delay50ms; TR1=0; //关定时 TF1=0; //清标志 TL1 = 0x00; //设置定时初值 5ms 溢出 TH1 = 0xEE; //设置定时初值 5ms 溢出 count=0; WG26=0; ReceiveFlag=0; } //如果数据位间隔未超时 else { WG26=WG26<<1; if(RD0==0) //接收到了0 WG26=WG26&0xFFFFFFFE; else if(RD1==0) //接收到了1 WG26=WG26|0x00000001; count++; if(count==26) { count=0; ReceiveFlag=1; TR1=0; //关定时 TF1=0; //清标志 } else { //为接收下一位做准备 TR1 = 0; //关定时 TF1 = 0; //清除TF1标志 TL1 = 0x00; //设置定时初值 TH1 = 0xEE; //设置定时初值 //超过5ms溢出标志被置位 TR1 = 1; //定时器1开始计时 } } IE0=0; //清除INT0中断标志,很重要! EX0=1; //开中断 } 在主程序查询到接收完成标志后,开始对数据进行奇偶校验位的核对。 得到奇校验位,记入odd=1 将无效的6位移除 得到偶校验位,记入even=0 将偶校验位移除,统计前12位有几个1 100011011100 000100101010