;************************************************************************** ; 标题: 多位数码管动态显示定时器中断实现(汇编) ; 作者: wentao http://blog.liuwentao.net ; http://wentao.programfan.com ; 日期: 2007.2.22 ; 软件: Keil A51 V8.00 ; 芯片: AT89X51 ; 说明: 实验板实测通过,数码管为8位共阳 ; 声明: 自用存档!另仅供需要的朋友参考,请勿用做不道德转载及商业用途! ;************************************************************************** org 0000h ajmp start org 000bh ;定时器0的中断入口地址 ajmp time0 ;跳到定时器0的中断服务程序处 org 0030h start: mov 30h,#0 ;30单元为显示值(查段码表时的偏址)兼循环控制,初始为0 mov 31h,#0xfe ;31单元为位码(选通各位数码管),初值为11111110 mov p2,#0xff ;关所有数码管 mov dptr,#table ;段码表首址 mov tmod,#00000001b ;定时/计数器0工作于方式1 mov th0,#0xfc mov tl0,#0x18 ;预置定时常数64536(fc18) setb ea ;开总中断 setb et0 ;定时/计数器0允许中断 setb tr0 ;启动定时/计数器0 ajmp $ ;原地等待中断 time0: ;定时器0的中断服务程序 clr ea ;关总中断 push acc ;保护现场 push psw mov a,30h ;取欲显示值 movc a,@a+dptr ;对应段码表中码值送入a mov p0,a ;段码送入P0口 mov p2,31h ;位码(在31h单元中)送入P2口 mov a,31h ;取位码到a rl a ;位码循环左移以选通下一个数码管 mov 31h,a ;更改后的位码送回31h单元 inc 30h ;30单元加1以显示下一个数(循环控制加1) anl 30h,#0x07 ;使30单元增到8时自动归0(控制30单元在0~7之间) mov th0,#0xfc ;重置定时常数 mov tl0,#0x18 pop psw pop acc setb ea ;开总中断 reti table: db 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8 ;段码表 ; 0 1 2 3 4 5 6 7 对应内容 db 0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e ; 8 9 a b c d e f end /************************************************************************** * 标题: 多位数码管动态显示定时器中断实现(C51) * 作者: wentao http://blog.liuwentao.net http://wentao.programfan.com * 日期: 2007.2.22 * 软件: Keil C51 V8.02 * 芯片: AT89X51 * 说明: 实验板实测通过,数码管为8位共阳 * 声明: 自用存档!另仅供需要的朋友参考,请勿用做不道德转载及商业用途! **************************************************************************/ #include <reg51.h> #include <intrins.h> #define uchar unsigned char uchar code dis_code[16] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8, //段码表 // 0 1 2 3 4 5 6 7 //对应内容 0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}; // 8 9 a b c d e f uchar data i = 0x00; // 循环控制变量兼偏移量,初值为0 uchar data j = 0xfe; // 位码(选通各位数码管),初值为11111110 void main() { P2 = 0xff; // 关所有数码管 TMOD = 0x01; // 定时/计数器0工作于方式1 TH0 = 0xfc; // 装载定时常数64536(fc18) TL0 = 0x18; EA = 1; // 开总中断 ET0 = 1; // 定时/计数器0允许中断 TR0 = 1; // 启动定时/计数器0 while(1); // 执行主程序,等待中断 } void time0(void) interrupt 1 // T/C0中断服务程序(延时1ms) { P2 = j; // 位码送入P2口显示 P0 = dis_code[i]; // 段码表中取值送P0口 j = _crol_(j,1); // 位码循环左移1位选通下一数码管 i++; // 偏移量加1取下一段码(循环控制加1) i &= 0x07; // 偏量增到8时自动归0(控制在0~7之间循环) TH0 = 0xfc; // 重新装载定时常数 TL0 = 0x18; }

评论