这次51的代码本来是自己写的,不过实在是遇到了点悲剧,时间没算好,还是看这个教程代码,很整洁的
这次用到了定时器,对于现在的52系列有3个定时器,并且Timer0,1,2.并且2有特殊的功能(尤其串口。以后讨论)
其中前面用到了很多定时器有关的设置方面的东西。只要有51的书都会涉及的。
首先说一下我很想放图片进来,但是没有找到很好的方法。我会尝试找一下找到了,我就放上来
这次时间间隔比上次长很多,因为430的Timer学的时间长了点。。。并且现在还需要不断复习和反复看要不马上就不会用了(还有英语考试)
好了,先做笔记吧
#include <AT89X51.H>
unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x00};
unsigned char dispbitcode[]={0xf8,0xf9,0xfa,0xfb,
0xfc,0xfd,0xfe,0xff}; //0~7发送到P1.0~1.2
unsigned char dispbuf[8]={16,16,16,16,16,16,16,16};
unsigned char dispbitcnt;
unsigned int t4mscnt; //每个数码管显示的时间大约4ms
unsigned char tmscnt; //每隔1ms,就刷新一个数码管
unsigned char u;
unsigned char i;
void main(void)
{
TMOD=0x02; //模式2,就是自动装填的模式,关于模式很多参考书都有
TH0=0x06; // 保存初值
TL0=0x06;
TR0=1; //启动定时器0
ET0=1; //使能Timer 0
EA=1; //开启中断
while(1);
}
void t0(void) interrupt 1 using 0
{
tmscnt++;
if(tmscnt==4) //计算下,大概时间就是稍大于4*250us
{
tmscnt=0;
P1=0xff; //关闭所有显示
P0=dispcode[dispbuf[dispbitcnt]];
P1=dispbitcode[dispbitcnt];
dispbitcnt++;
if(dispbitcnt==8)
{
dispbitcnt=0;
}
}
t4mscnt++;
if(t4mscnt==1600) //每个显示时间就是大概1600*250us。不过显然不准,因为好多指令需要消耗时间
{
t4mscnt=0;
u++;
if(u==9)
{
u=0;
}
for(i=0;i<8;i++)
{
dispbuf[i]=16;
}
for(i=0;i<u;i++) //很关键,显示几个数字的功能
{
dispbuf[i]=i+1;
}
}
}
##########################################################################
汇编贴上来供大家欣赏,读一读不是特别的费力,后面的流程写的非常清晰,供大家了解一下。
DISPBUF EQU 30H
DISPCNT EQU 38H
DISPBIT EQU 39H
T1CNTA EQU 3AH
T1CNTB EQU 3BH
CNT EQU 3CH
ORG 00H
LJMP START
ORG 0BH
LJMP INT_T0
START: MOV DISPCNT,#8
MOV R1,#DISPBUF ;直接寻址单元送寄存器
LP: MOV A,#10 ;改:从在MOV R1,#DISPBUF上面调到其下面
MOV @R1,A ;@R1为内部RAM单元
INC R1 ; +1
DJNZ DISPCNT,LP ;DISPCNT减1不为零转移
DISPBUF 10 10 10 10 10 10 10 10
30H 30H 31H 32H 33H 34H 35H 36H 37H
DISPCNT 8 7 6 5 4 3 2 1
MOV DISPBIT,#00H
MOV T1CNTA,#00H
MOV T1CNTB,#00H
MOV CNT,#00H
MOV TMOD,#01H