您好,欢迎访问三七文档
当前位置:首页 > 办公文档 > 统计图表 > 51之中断定时器蜂鸣器
中断理解中断概念:豆豆主任务是看书,中断时接电话。电话是随机打来的,①中断是随机产生的;②接完电话后,豆豆回去继续看书;再说电话,③外部来了电话,电话处理了这个信之后,电话自动铃响了,这说明电话这个设备处理了部分的信号,符合条件,产生了中断请求。而非豆豆让电话响的,或控制电话响的。在电话响之前,豆豆根本没有处理电话接受到的任何信号,中断的产生,是电话处理产生的。④来电话了,这个中断,会产生电话铃响,这个标志位。豆豆也就是通过电话铃响(标志位),才知道有了个中断;也就是通过电话铃响(标志位),知道这个中断是电话。如果是门的话,那通过门铃响了,就知道有个中断产生了,也知道这个中断是门了。我们把能够产生中断的设备称为信号源。在单片机里面,产生中断的可能是单片机内部的模块,也可能是单片机IO口外部输入的信号。中断响应过程:Cpu正常执行主程序时,突然一个时间点,中断源检测出符合中断条件的信号,向CPU发生中断请求。CPU得到这种中断请求之后,进行中断响应,执行该中断的中断服务程序。然后,中断返回,CPU继续执行主程序。中断的作用:*独立按键和外部中断按键,就是一个很明显的对比。检测独立按键时,我们需要在主程序里面,重复的检测IO口。而有了外部中断按键,我们就不用反复的检测扫描IO口了,因为当按键按下去的时候,单片机会产生一个中断告诉CPU。有了中断,定时器可以计定时器的数,CPU可以做CPU的工作。当定时器完成工作之后,会通过中断告诉CPU,然后再由CPU来处理。同样,像电源掉电、硬件故障等突发情况,都可以通过中断的方式,告诉CPU。我们的很多系统都要求实时性。“想象一下,一个机床正在飞速运转,这时有人的手被卷进去了,然后你迅速地通过电脑给单片机发一串指令。如果你的单片机系统不能实时地处理这个指令,而是每隔一定的时间,去查询下有指令进来了没,那可能指令进来的时候,你的查询时间还没到,所以单片机没执行指令,直到查询时间到了,这时再去处理,人的手已经掉下来了罢了。”我们知道,电脑是可以同时打开很多个软件的(实时多任务),就是因为有定时器中断的存在,才实现了这一效果。每隔一定的时间,产生一个中断,然后CPU就跳转到另一个软件中,执行另一个软件的操作。这就是80C51内核,也就是大家手里51单片机的中断系统结构框图。最左边是中断源,中间这些开关是中断的各种设置寄存器。51的中断有2个优先级别,用来将每个中断进行分级,如果多个中断同时发生的话,先处理高级的,再处理低级的中断。(不管它的自然优先级是怎么样的)如果优先级别相同的中断,就按照自然优先级(也就是系统默认的优先级)来响应中断。由此,51单片机能够在低级中断里面再嵌套一个高级中断。中断源:51单片机共有5个固定的中断源,分别是外部中断0、定时器T0中断、外部中断1、定时器T1中断,串口中断RI/TI。外部中断0,是由IO口P3.2输入的信号来产生的,如果外部给P3.2一个低电平(电平触发)或下降沿(边沿触发)信号,则单片机就会产生一个外部中断0的信号。----外部中断触发方式:再有就是,定时器从初值计数到最大值时,定时器会溢出,这是就会产生一个定时器中断。还有就是,当电脑通过串口给单片机的串口引脚发送一个字符的时候,当单片机的串口模块,接收完了这个字符,就会产生一个中断。串口模块发送完一个字符之后,也会产生一个中断。每个中断源的自然优先级刚才讲了,51单片机的中断系统能够通过寄存器设置来决定开启或关断某个中断源,这个寄存器就是IE。我们知道,寄存器就是我们编程序的时候,可以操作了。也就意味着,我们可以通过编程,来选择开或关哪个中断源了。必须同时满足:1.总中断EA是开启的2.中断源开关是开启的中断源才会向CPU发出中断请求,IE寄存器,是可以位寻址的,也就是说,我们可以通过sbit,定义它的每个位,并进行位操作,像IO口一样,置1,或清0。还有一个寄存器IP,用来,设置各个中断的优先级别。接下来,我们就来分析一下,中断的响应过程:首先是中断源发出中断请求;一般有两种情况:yi.如果是单片机外部输入的信号,那么我们需要对IO口进行采样,判断是否符合中断条件,然后把该中断相应的中断标志位置1。注意:此采样置位的过程是由硬件自动完成的,而非我们编写程序来实现。如果是单片机内部的某些模块,如定时器模块,串口模块,他们可以通过单片机内部的硬件电路,在满足中断条件时,直接将他们对应的中断标志位置1。1.外部中断0和外部中断1的控制位和标志位,储存在寄存器TCON的低四位2.定时器0和定时器1的控制位和标志位,储存在寄存器TCON的高四位。3.串口的控制位和标志位,储存在寄存器SCON中。当某中断源判断中断条件成立时,就会将对应的中断标志位置位,也就向CPU进行了“中断请求”,此过程由硬件自动完成。CPU就是通过查询这些中断标志位,来判断是否由中断产生,以及产生的是什么样的中断。中断源发送完中断请求(即将中断标志位置位)之后,CPU是如何知道这1中断请求的呢?CPU的中断标志位查询。我们知道,每1-4个机器周期,单片机就会执行一条指令。1个机器周期,包括6个状态周期。在这些状态周期中,可能某个状态周期完成了取指令、取数据等操作。在每个机器周期的第6个状态周期S6,CPU就会自动查询寄存器TCON和SCON中的各中断标志位来确定是否发生了“中断请求”,哪个中断源发生了请求。如寄存器TCON中,TF1,TF0分别是定时器1和定时器0的中断标志位IE1和IE0就是外部中断1和外部中断0的中断标志位寄存器SCON中TI和RI就是串口模块,分别是发送完1个字符数据的中断标志位,接收完1个字符数据的中断标志位。CPU会在每个机器周期的S6状态时,按照中断优先级别对各标志位进行查询。然后到下个机器周期的S6状态,再决定要不要中断响应。有以下3种情况比较特殊:1.CPU目前正在处理一个同级或更高级别的中断请求。注意,我们前面讲过,当一个中断,正在被响应时,只有更高级别的中断请求,才可以达到该响应过程,让CPU去响应此更高级别的中断请求,低级别的,或同级别的都不能实现中断嵌套,所以,CPU正在处理一个同级或更高级别的中断请求,执行中断服务程序时,是不能响应其他中断的。2.我们知道,我们用C语言编的程序,会被Keil编译成各种各样的指令,然后单片机执行这些指令。单片机指令,有单周期的,也有双周期的,还有四周期的。当CPU决定是否进行中断响应时,发现现在所处的机器周期,并不是当前执行指令的最后一个机器周期,那它同样不会进行中断响应。3.还有就是如果执行的指令是RETI,或访问寄存器IE、IP的指令,即使已经是指令的最后一个机器周期了,CPU也会至少再执行一条指令才会响应中断。因为这些指令是跟中断有关的。所以,操作这些指令时可能会对中断源进行一些操作。以上就是CPU如何查询中断标志位的。cpu对某中断的真正响应,需要3~8个机器周期。首先,查询到标志位之后,需要等到下一个机器周期才能决定是否响应中断。这就耗去了一个机器周期,进行中断响应,CPU执行LCALL指令,需要2个机器周期,接下来才是对中断进行相应的操作了,这是3个机器周期。如果决定是否响应中断的那个周期是RETI指令的第一个机器周期,RETI需要两个机器周期,则需要再执行一条指令。如果再执行的指令是乘除指令,也就是四周期指令,则需要4个机器周期;如果再执行的指令是乘除指令,也就是四周期指令,则需要4个机器周期;然后再执行LCALL,这就是8个机器周期了,当然,如果发生中断请求时,是在某个处理某个中断响应的话,那就要看中断响应里面的中断服务程序做哪些工作了。所以,中断服务程序里面的时间不应该太长,否则会影响其他中断的响应。所谓中断响应,就是执行LCALL指令。这条指令,主要实现两个功能第1个是把目前主程序将要执行的下一条指令所在的地址,压入堆栈保存起来。以便从中断返回时,恢复主程序第2个是把中断源对应的入口地址交给CPU,CPU就会执行这些入口地址处存储的指令。这些地址是固定的,每个中断源都对应一个入口地址,在这些入口地址处可以存放一些指令,来处理中断。中断响应之后,某些中断标志位,就会自动被清除,是硬件自动完成的但是RI/TI中断标志位,必须我们在程序里面,把这两个位清零才行我们也可以通过查询RI/TI来判断是接收串口数据产生的中断还是发送串口数据产生的中断。回顾一下:step1:中断请求由中断源硬件自动完成,我们不用管。step2:CPU在每个机器周期里面查询中断标志位有硬件自动完成,我们不用管。step3:中断响应在判断符合中断响应的条件,进行中断响应时,调用LCALL指令。由硬件自动完成,我们不用管。这时,CPU的程序指针PC,指向的是中断源的入口地址,那么接下来,就会执行中断源入口地址存放的指令了。address1是主程序的一条指令所在地址,此时进行了中断响应,PC就会指向中断源入口地址,假设发生了外部中断0,是对外部中断0进行的中断响应,PC就会指向0x0003H,我们可以看一下此地址存放了什么代码?我们发现两个中断源入口地址之间的存储空间是很有限的。所以,往往我们会在此入口处放一条跳转指令。把中断服务程序放在其他的地方,然后从中断入口处执行指令跳转过去。这是我们的程序在ROM里面的存放方式大家可以看到中断服务程序被放在了address2处了那么我们就要在中断入口处放一条跳转到address2的指令或许,大家比较郁闷,大家写中断的时候,并没有体会到这个过程那是因为KEil帮你完成了这一切你在程序里面只要加上这个关键字Keil就知道,这是外部中断0的服务程序了、Keil会自动把此段代码的地址存储在中断入口那里……问题:#includereg52.hsbitLed1=P1^0;sbitLed2=P1^1;sbitLed3=P1^2;sbitKey=P3^2;unsignedchart;voidDelay100ms()//@12.000MHz{unsignedchari,j;i=195;j=138;do{while(--j);}while(--i);}voidmain(){EA=1;//中断允许EX0=1;//开外部中断0IT0=0;//低电平触发外部中断Led1=1;Led2=1;while(1){Led1=!Led1;//让LED闪烁一下}}voidint0()interrupt0//电平触发{Delay100ms();}XDL-郭浩2014-2-1322:01:19如果P3.2经一根杜邦线连到低电平XDL-郭浩2014-2-1322:01:28那会有什么现象XDL-郭浩2014-2-1322:01:40大家试一下,然后分析一下为什么会这样定时器/计数器溢出,是定时器/计数器的一种普遍现象,由于单片机内部结构的设置,单片机溢出之后,数会变为0而非最大计数量,这一点与这个水盆是不同的。为何要有初值?定时器常用到初值,初值设置好了之后,我们就可以设定经过多长时间会发生溢出,溢出时,定时器/计数器就会向cpu发出中断请求。定时器/计数器一般都要用到它的中断,51有T0和T1,52多了个T2。THxTLx就是这两个8位加1计数器的寄存器,我们可以用软件对该寄存器进行读写。工作原理(以16位定时器/计数器为例)TH0、TL0这两个计数寄存器组合成一个16位的二进制数,TH0存放的是高8位、TL0存放的是低8位。每来1个脉冲,TL0会加1一次。TL0加满之后,就会像TH0进一位,直至TH0也加到最大值。此时,整个二进制的16位全部是1,对应的十进制数是65535(单片机从0开始计数),此时,如果再来一个计数脉冲,TH0,TL0都会溢出,两个都变成0。这点不难理解:65535的二进制数位:1111111111111111,16个1,如果你再给它加1的话,他就会变成10000000000000000,1个1加16个0了,而单片机这两个寄存器最多存16个位,所以第一个被进上去的位,就会被舍弃,这就是溢出后的结果。溢出之后,由硬件把定时器T0的中断标志位TF
本文标题:51之中断定时器蜂鸣器
链接地址:https://www.777doc.com/doc-5694120 .html