/* MCU: AT89S52
/* MCU-crystal: 12M
/* Version: 01
/* Last Updata: 2009-2-21
/* Author:
/* Description:
/* 使用定时器0,定时中断2ms一次对数码管显示扫描;
/* 三个位管要以扫描方式显示,使用共阳管,计数速度为1S;
/* 段A-H接到P0.1....7,位选为 P1.0,1,2;
/* 流水也以计数方式从200到250在P2口显示,低电平有效;
/****************************************************/
#include <reg52.h>
unsigned char code num_disp[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xd8,0x80,0x90}//共阳数字字形0到9
unsigned char code bit_sel[]={0xfb,0xfd,0xfe}//低电平有效数字个十百位选择
unsigned char buf[3]={0,0,2}//计算中的个十百位暂时存放处
unsigned char one,ten,second//个十位变量和流水灯显示3秒的时间变量
unsigned char rate//扫描速度,调整以适应显示效果
unsigned char stop=0, flag=1,flag1=0//闪烁3秒的标志位,用于主函数对中断的关断参数传递
unsigned int t,tt//2ms变量
unsigned char rate//与变量t同步,辅助赋值变
/**********主函数**********/
main(void)
{
TMOD=0X01
TH0=0xf8//定时2ms
TL0=0x30
ET0=1
EA=1
TR0=1
while(1)
{ if(stop==1)//判断stop信号,为1后便关闭定时器
{ TR0=0
ET0=0
EA=0
}
}
}
/*******************中断*******************/
void timer0() interrupt 1
{
TH0=0xf8//重新赋值定时2ms
TL0=0x30
if(flag==0)//定义用于判断计数是否到了250,若到了则不再计数,转向else执行流水灯闪烁任务
{
t++
if(t==500)
{ t=0
one++
P2=200+ten*10+one//在P2口的流水等,也是从200开始计数。
if(one==10)
{ one=0
ten++
if(ten==5)
{ flag=1//转向执行闪烁任务
}
}
}
}
else//flag已经==1;转向else执行流水灯闪烁任务
{ tt++
if(tt==500)
{ tt=0
second++
P2=~P2//流水灯全部以1S速度闪烁
if(second==3)stop=1//判断3秒时间到,关闭中断,停止闪烁,数码管熄灭
}
}
rate++
P0=0XFF//消隐
if(rate==3)rate=0
P0=num_disp[buf[rate]]
P1=bit_sel[rate]
buf[0]=one
buf[1]=ten
//因为百位没有变,所以不用赋值
}
ORG 0000HAJMP START
ORG 0030H
START:MOV SP,#60H堆栈,本程序也可不要
MOV 30H,#56H 求5678H+1234H
MOV 31H,#78H
MOV 32H,#12H
MOV 33H,#34H
MOV A,31H
ADD A,33H
MOV R2,A低8位在R2
MOV A,30H
ADDC A,32H
MOV R1,A高8位在R1
MOV R3,#10H 30H至40H共10H个字节
MOV R0,#30H 间接寻址模式起始地址为30H
CLR A
LOOP: MOV @R0,A
INC R0
DJNZ R3,LOOP
HERE: JMP HERE 结束原地循环
END
ORG 0000H 起始地址LJMP MAIN
ORG 000BH 中断地址
LJMP CLOCK
ORG 0050H
MAIN: MOV R7,#14H 寄存器R7载入20
MOV 27H,#00H
MOV 28H,#00H
MOV 29H,#00H 27H 28H 29H 三个寄存器初始化,即秒,分,时
MOV TMOD,#01H Timer0 选作定时器,选用工作模式1
MOV TL0,#0B0H
MOV TH0,#3CH 往Timer0寄存器中载入计数初值3CB0H,即定时时间为50000us
ORL IE,#87H 开启外部中断0,外部中断1 和 Timer0中断
SETB TR0 开启TIMER0
WAIT:
LCALL DZSPLAY 调用显示子程序
LJMP WAIT
CLOCK: DJNZ R7,NEXT R7自减,不为0则跳转NEXT
INC 27H R7减到20次 即计时一秒后27H加1
MOV R7,#14H
MOV A, 27H 27H的值载入累加器
CJNE A,#60,EXIT 累加器A不到60跳转EXIT
MOV 27H,#00H
INC 28H 累加器A计数到60,28H加1,27H清零
MOV A,#28H
CJNE A,#60,EXIT
MOV 28H,#00H 累加器A计数到60,29H加1,28H清零
INC 29H
MOV A,29H
CJNE A,#24,EXIT 累加器A计数到24,27H 28H 29H清零
MOV 29H ,#00H
MOV 28H,#00H
MOV 27H,#00H
EXIT:RETI 返回
NEXT:
MOV TH0,#3CH
MOV TL0,#0B0H 重新给计数器寄存器载入初值
RETI
DZSPLAY:
MOV A,27H 显示子程序,显示秒,分,时
MOV B,#10 秒,分,时 分别除以10 分两位显示
DIV AB
MOV 32H,A
MOV 31H,B
MOV A,31H
MOV DPTR,#LEDSEG
MOVC A,@A+DPTR
MOV DPTR,#8004H
MOVX @DPTR, A
MOV DPTR,#8002H
MOV A,#00000001B 数码管位选 显示在最低位
MOVX @DPTR,A
ACALL DLAY
MOV A,32H
MOV DPTR,#LEDSEG
MOVC A,@A+DPTR
MOV DPTR,#8004H
MOVX @DPTR,A
MOV DPTR,#8002H
MOV A,#00000010B
MOVX @DPTR,A
ACALL DLAY
MOV A,28H
MOV B,#10
DIV AB
MOV 34H,A
MOV 33H,B
MOV A,33H
MOV DPTR,#LEDSEG
MOVC A,@A+DPTR
MOV DPTR,#8004H
MOVX @DPTR,A
MOV DPTR,#8002H
MOV A,#00000100B
MOVX @DPTR,A
ACALL DLAY
MOV A,34H
MOV DPTR,#LEDSEG
MOVC A,@A+DPTR
MOV DPTR,#8004H
MOVX @DPTR,A
MOV DPTR,#8002H
MOV A,#00001000B
MOVX @DPTR,A
ACALL DLAY
MOV A,29H
MOV B,#1O
DIV AB
MOV 36H,A
MOV 35H,B
MOV A,35H
MOV DPTR,#LEDSEG
MOVC A,@A+DPTR
MOV DPTR,#8004H
MOVX @DPTR,A
MOV DPTR,#8002H
MOV A,#00010000B
MOVX @DPTR,A
ACALL DLAY
MOV A,36H
MOV DPTR,#LEDSEG
MOVC A,@A+DPTR
MOV DPTR,#8004H
MOVX @DPTR,A
MOV DPTR,#8002H
MOV A,#00100000B
MOVX @DPTR,A
ACALL DLAY
LJMP DZSPLAY
DLAY:MOV R1,#01H 延时子程序
DL2:MOV R2,#01H
DL1:NOP
NOP
DJNZ R2,DL1
DJNZ R1,DL2
RET
LEDSEG:DB 3FH,06H,5BH,4FH,66H,6DH,7DH 07H,7FH,6FH 0-9数码显示管
指令不清楚看下单片机的书
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)