微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 硬件工程师文库 > 单片机学习知识点全攻略(三)

单片机学习知识点全攻略(三)

时间:05-15 来源:本站整理 点击:

堆栈保护

  CPL P1.0

  MOV TH0,#15H

  MOV TL0,#0A0H ;重置定时常数

  POP PSW

  POP ACC

  RETI

  END

  上面的例程中,定时时间一到,TF0由0变1,就会引发中断,CPU将自动转至000B处寻找程序并执行,由于留给定时器中断的空间只有8个字节,显然不足以写下所有有中断处理程序,所以在000B处安排一条跳转指令,转到实际处理中断的程序处,这样,中断程序能写在任意地方,也能写任意长度了。进入定时中断后,首先要保存当前的一些状态,程序中只演示了保存存ACC和PSW,实际工作中应该根据需要将可能会改变的单元的值都推入堆栈进行保护(本程序中实际不需保存护任何值,这里只作个演示)。

  上面的两个单片机程序运行后,我们发现灯的闪烁非常快,根本分辨不出来,只是视觉上感到灯有些晃动而已,为什么呢?我们能计算一下,定时器中预置的数是5536,所以每计60000个脉冲就是定时时间到,这60000个脉冲的时间是多少呢?我们的晶体震荡器是12M,所以就是60000微秒,即60毫秒,因此速度是非常快的。如果我想实现一个1S的定时,该怎么办呢?在该晶体震荡器濒率下,最长的定时也就是65。536个毫秒啊!上面给出一个例程。

  ORG 0000H

  AJMP START

  ORG 000BH ;定时器0的中断向量地址

  AJMP TIME0 ;跳转到真正的定时器程序处

  ORG 30H

  START:

  MOV P1,#0FFH ;关所 灯

  MOV 30H,#00H ;软件计数器预清0

  MOV TMOD,#00000001B ;定时/计数器0工作于方式1

  MOV TH0,#3CH

  MOV TL0,#0B0H ;即数15536

  SETB EA ;开总中断允许

  SETB ET0 ;开定时/计数器0允许

  SETB TR0 ;定时/计数器0开始运行

  LOOP: AJMP LOOP ;真正工作时,这里可写任意程序

  TIME0: ;定时器0的中断处理程序

  PUSH ACC

  PUSH PSW ;将PSW和ACC推入堆栈保护

  INC 30H

  MOV A,30H

  CJNE A,#20,T_RET ;30H单元中的值到了20了吗?

  T_L1: CPL P1.0 ;到了,取反P10

  MOV 30H,#0 ;清软件计数器

  T_RET:

  MOV TH0,#15H

  MOV TL0,#9FH ;重置定时常数

  POP PSW

  POP ACC

  RETI

  END

  先自己分析一下,看看是怎么实现的?这里采用了软件计数器的概念,思路是这样的,先用定时/计数器0做一个50毫秒的定时器,定时是间到了以后并不是立即取反P10,而是将软件计数器中的值加1,如果软件计数器计到了20,就取反P10,并清掉软件计数器中的值,不然直接返回,这样,就变成了20次定时中断才取反一次P10,因此定时时间就延长了成了20*50即1000毫秒了。

  这个思路在工程中是非常有用的,有的时候我们需要若干个定时器,可51中总共才有2个,怎么办呢?其实,只要这几个定时的时间有一定的公约数,我们就能用软件定时器加以实现,如我要实现P10口所接灯按1S每次,而P11口所接灯按2S每次闪烁,怎么实现呢?对了我们用两个计数器,一个在它计到20时,取反P10,并清零,就如上面所示,另一个计到40取反P11,然后清0,不就行了吗?这部份的程序如下

  ORG 0000H

  AJMP START

  ORG 000BH ;定时器0的中断向量地址

  AJMP TIME0 ;跳转到真正的定时器程序处

  ORG 30H

  START:

  MOV P1,#0FFH ;关所 灯

  MOV 30H,#00H ;软件计数器预清0

  MOV TMOD,#00000001B ;定时/计数器0工作于方式1

  MOV TH0,#3CH

  MOV TL0,#0B0H ;即数15536

  SETB EA ;开总中断允许

  SETB ET0 ;开定时/计数器0允许

  SETB TR0 ;定时/计数器0开始运行

  LOOP: AJMP LOOP ;真正工作时,这里可写任意程序

  TIME0: ;定时器0的中断处理程序

  PUSH ACC

  PUSH PSW ;将PSW和ACC推入堆栈保护

  INC 30H

  INC 31H ;两个计数器都加1

  MOV A,30H

  CJNE A,#20,T_NEXT ;30H单元中的值到了20了吗?

  T_L1: CPL P1.0 ;到了,取反P10

  MOV 30H,#0 ;清软件计数器

  T_NEXT:

  MOV A,31H

  CJNE A,#40,T_RET ;31h单元中的值到40了吗?

  T_L2:

  CPL P1.1

  MOV 31H,#0 ;到了,取反P11,清计数器,返回

  T_RET:

  MOV TH0,#15H

  MOV TL0,#9FH ;重置定时常数

  POP PSW

  POP ACC

  RETI

  END

  您能用定时器的办法实现前面讲的流水灯吗?试试看。

  20、单片机定时/计数器实验

前面我们做了定时器的实验,现在来看一看计数实验,在工作中计数常常会有两种要求:第一、将计数的值显示出来,第二、计数值到一定程度即中断报警。第一种如各种计数器、里程表,第二种如前面例中讲到的生产线上的计数。先看第一种吧。我们的硬件中是这样连线的:324组成的振荡器连到定时/计数器1的外部管脚T

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top