前面既然已经讲了定时器中计时器的使用,刚脆还是把定时器中断给讲一下。 先打个比方说吧,比如说,你是个超级奶爸,在家招呼读书的孩子,将孩子送到学校去之后,你回家得买菜洗菜煮饭烧菜,你先把上午的菜给备好了,然后计划11点钟煮饭,11点半开始烧菜,你怎么做?象前面的计时器的使用一样盯着时钟看?也不是不行,但是那你这段时间别的事算是做不成了,下午的菜备不备?你心爱单片机玩不玩?想看的小说是不是让你心痒痒?怎么办?买个闹钟呗,然后上好闹钟呗,然后就去干你想干的别的事。 然后闹钟响了,你自然会起身,去做这个时候该做的重要的事件了。等等,该做什么?我怎么忘了?怎么办?让我想想,哦想起来了,煮饭。不行,不能这样,这次能想起来,下回万一想不起来怎么办?好办,在闹钟上贴个条子,上面写上这个闹钟响后要做的事:你呀的快去煮饭。 嗯不错,饭煮上了,接下来干什么呢?继续做之前在做的事是个不错的主意,哦你个卖糕滴,上次做的是什么事?做到哪一步了?我怎么又给忘了?这样不行,下次在闹钟响的时候,得把手头正在做的事记一下并放在一个固定的地方,煮完饭后回到这个地方找到记录,真好,我真聪明,虽然我的记性非常感人。 以上事件中,最主要的是你手头正在做的事,被闹钟打断,因为你得立即去处理闹钟上写的事。你把这个闹钟上写的事处理完之后,还得回头继续做前面做的事。这些事,反正现有的教材称之为中断和中断处理。 引起中断的事件当然不止是闹钟,还有可能是另外的事,比如说,你玩单片机玩得正高兴,突然你那位喊你去买菜,你也不得不放下自己的心爱,乖乖地买菜去先。买完菜之后,你不见得就能去继续玩机器了,说不定你那位又给你一个中断,让你去拖地。地还没拖完,孩子回来了找你要钱买玩具。真是中断事件一件接一件,怎么处理? 你怎么处理我不管,咱们现在管管单片机怎么处理中断,其实跟上面说的差不多,你把中断后要做的事,写在一段程序中(就如上面说的挂在闹钟上的那个小纸条),C语言中叫中断函数。这个函数的开头记录现场(将一些数据推入指定的单元中如堆栈),末尾则写上程序据此恢复现场。 为什么写一段中断函数就行了,而不是在主函数中写一段中断处理程序,也不用在主程序中写调用函数?又是一个疑问点不是?因为单片机在芯片设计上是这样设计的:程序在运行中,一旦被中断,则程序的运行是直接跳转到程序存储器中的一个固定地址单元中,并把这个单元中的数据当作操作码来执行。一个单片机是至少有几个中断的,如每个定时器都具备中断功能。如何区分不同的中断?靠的就是每个中断分配有不同的跳转固定地址,这个在教材中称之为中断的入口地址,具体地址分配表称之为中断向量表。定时器0的中断入口地址为000BH,也就是说定时器0在发生溢出后,如果你打开了其中断功能,则程序立即跳转到程序存储器中地址编号为000BH的单元处开始运行程序,用不着你专门写调用指令。在51单片机的设计中,紧随其后的一个中断入口地址为0013H,所以,0013H这个单元中,你不能写入其它程序,否则编译会乱套,而在000BH到0012H之间你也只能写入定时器0的溢出中断后要执行的程序,除非这个中断在你的程序中永远用不到。这个空间太少了,一般是不够用的,所以,编程中都是只写个跳转命令,让其跳转到后面,这个跳转幅度,一般要完全避开所有的中断入口地址,以免影响中断功能的使用。
|