┊ 网站导航 ┊ 管理登陆 ┊ 免责声明 ┊ 问题反馈 ┊ 友链说明┊本站部分内容来自网络共享资源,如有冒犯您的权利请来信告之删除或纠正! 不得对本站进行复制、盗链或镜像,转载内容须获得同意或授权;欢迎友情链接、站务合作! ![]() ![]() ![]() ![]() ![]() ![]() 本站学习交流群:138..158(高级群1-满)、77930286(高级群2)、61804809(群3) Copyright© MCUSY All Rights Reserved 本站网警备案号: WZ36040002485 ICP备案证书号:粤ICP备09034963号 |
上面的例子中,定时时间一到, 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 ,不就行了吗?这部份的程序如下
┊ 网站导航 ┊ 管理登陆 ┊ 免责声明 ┊ 问题反馈 ┊ 友链说明┊本站部分内容来自网络共享资源,如有冒犯您的权利请来信告之删除或纠正! 不得对本站进行复制、盗链或镜像,转载内容须获得同意或授权;欢迎友情链接、站务合作! ![]() ![]() ![]() ![]() ![]() ![]() 本站学习交流群:138..158(高级群1-满)、77930286(高级群2)、61804809(群3) Copyright© MCUSY All Rights Reserved 本站网警备案号: WZ36040002485 ICP备案证书号:粤ICP备09034963号 |