· ;**************************************************************************
· ; 标题: 多位数码管动态显示定时器中断实现(汇编)
· ; 作者: 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
· #include
·
· #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;
· }
|