数码管的动态显示:精简代码版,要注意关灯,否则有问题,还有时间消影,这个例子虽然很简单,但是精简代码百分之九十的人会写错
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
void delay(uint z);
uchar code table[]={ 0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uchar code tablew[]={0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f};
uchar aa,bb;
uint tt;
sbit dula =P2^6;
sbit wela = P2^7;
main()
{
aa = 0;
bb = 6;
while(1)
{
wela = 1;
P0 = tablew[aa];
wela = 0;
P0 = 0xff;
//delay(1);
dula = 1;
P0 = table[bb];
dula = 0;
P0 = 0xff;
tt=300;
while(tt--);
dula = 1;
P0 = 0x0;//要关灯,或者这个程序有问题,
dula = 0;
delay(1);
aa ++;
bb--;
if(aa == 6)
aa = 0;
if(bb ==0)
bb = 6;
}
while(1);
}
void delay(uint z)
{
uint x,y;
for(x = z;x>0;x--)
for(y=110;y>0;y--);
}
作业2:用数码管的动态扫描制成一个秒表,让数码管后两位显示%1秒
//程序虽然写出来了,但是调试可是花了我大力气, 对于数码管而言
//要记住,不要使用delay()郭天祥那个延时函数,因为这里涉及的是微妙级别的数
//display这个函数执行的时间不能大于10微秒,这就必须消影,
//高速度扫描时,不消影后果很严重,每次段选完以后要进行关灯
//timu:有两个动态扫描的方法和定时器1在数码管的前三位显示表秒
//精确到%1,即后两位显示百分之一秒,一直循环下去
//关于定时器装初值问题,这里有一个规律,就是,12Mhz的晶振,计数恋
//计数N毫秒,就装入N乘以1000
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
uint num;
uchar aa,bb,ge,shi,bai,tt;
sbit wela =P2^6;
sbit dula = P2^7;
void init();
void delay(uint z);
void display(uchar bai,uchar shi,uchar ge);
uchar code table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
main()
{
init();
while(1)
{
if(aa==10)
{ aa = 0;
num++;
if(num == 1000)
num=0;
}
ge = num%10;
shi = num/10%10;
bai = num/100;
display(ge,shi,bai);
}
}
void init()
{
TMOD = 0x11;
TH1 = (65535-1000)/256;
TL1 = (65535-1000)%256;
EA = 1;//开总中断
ET1 = 1;//开定时器1中断
TR1 = 1;//启动定时器1
aa = 0;
}
void display(uchar bai,uchar shi,uchar ge)
{
wela = 1;
P0 = 0xfe;
wela = 0;
P0 = 0x0;//消影操作
dula = 1;
P0 = table[ge];
dula = 0;
tt = 25;
while(tt--);
dula = 1;//关灯操作,高速度扫描时必备
P0 = 0;
dula = 0;
wela = 1 ;
P0 = 0xfd;
wela = 0;
P0= 0x0;//消影操作
dula = 1;
P0 = table[shi];
dula = 0;
tt = 25;
while(tt--);
dula = 1;//关灯操作,高速度扫描时必备
P0 = 0;
dula = 0;
wela = 1;
P0 = 0xfb;
wela = 0;
P0 = 0x0;//消影操作
dula = 1;
P0 = table[bai];
dula =0;
tt=25;
while(tt --);
dula = 1;//关灯操作,高速度扫描时必备
P0 = 0;
dula = 0;
}
void time1()interrupt 3
{
TH1 = (65535-1000)/256;
TL1 = (65535-1000)%256;
aa ++;
}
作业3:利用动态扫描,和定时器1,在数码管上显示从765432开始以十分之一秒的速度往下递减直至765398,并且保持住此数,与此同时利用定时器0以500ms的速度进行流水灯从上往下移动,但数码管减到停止时,实验板上流水灯也停止,然后开始闪烁,3秒后,(用T0)计时,数码管上显示HELLO,并且保持住
//这个程序也调试了我好久,这里主要是标志位的使用
//当一个事件接二连三的发生时,这里要考虑设置标志位
//定时器的关闭后,再次启动,需要重新装入初值,还要重新启动
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit dula = P2^2;
sbit wela = P2^3;
uchar aa,bb,cc,dd,ee,ff,bai,shi,ge,flag,flag1;
uint num,tt;
void init();//一个机器周期执行时间就是1um
void display(uchar cc,uchar dd,uchar ee,uchar bai,uchar shi,uchar ge);
uchar code table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,
0x76,0x79,0x38,0x3f,0};
void main()
{
init();
bai = num/100;
shi = num/10%10;
ge = num%10;
while(1)
{
if(flag1 != 1)
{
display(7,6,5,bai,shi,ge);
}
else
{
display(16,17,18,18,19,20);
}
}
}
void init()
{
TMOD = 0x11;
TH1 = (65535-50000)/256;
TL1 = (65535-50000)%256;
TH0 = (65535-50000)/256;
TL0 = (65535-50000)%256;
EA = 1;
ET1 = 1;
TR1 = 1;
ET0 = 1;
TR0 = 1;
bb = 0;
aa = 0xfe;
ff = 0;
num=432;
flag = 0;
flag1 = 0;
}
void display(uchar cc,uchar dd,uchar ee,uchar bai,uchar shi,uchar ge)
{
wela = 1;
P0 = 0xfe;
wela = 0;
P0 = 0x0;
dula = 1;
P0 = table[cc];
dula = 0;
P0 = 0xff;
tt=50;
while(tt--);
dula = 1;
P0=0;
dula =0;
wela = 1;
P0 = 0xfd;
wela = 0;
P0 = 0x0;
dula = 1;
P0 = table[dd];
dula = 0;
P0 = 0xff;
tt=50;
while(tt--);
dula = 1;
P0=0;
dula =0;
wela = 1;
P0 = 0xfb;
wela = 0;
P0 = 0x0;
dula = 1;
P0 = table[ee];
dula = 0;
P0 = 0xff;
tt=50;
while(tt--);
dula = 1;
P0=0;
dula =0;
wela = 1;
P0 = 0xf7;
wela = 0;
P0 = 0x0;
dula = 1;
P0 = table[bai];
dula = 0;
P0 = 0xff;
tt=50;
while(tt--);
dula = 1;
P0=0;
dula =0;
wela = 1;
P0 = 0xef;
wela = 0;
P0 = 0x0;
dula = 1;
P0 = table[shi];
dula = 0;
P0 = 0xff;
tt=50;
while(tt--);
dula = 1;
P0=0;
dula =0;
wela = 1;
P0 = 0xdf;
wela = 0;
P0 = 0x0;
dula = 1;
P0 = table[ge];
dula = 0;
P0 = 0xff;
tt=50;
while(tt--);
dula = 1;
P0=0;
dula =0;
}
void time_0()interrupt 1
{
TH0 = (65535-50000)/256;
TL0 = (65535-50000)%256;
bb++;
if(flag!=1)
{
if(bb==10)
{
bb = 0;
aa = _crol_(aa,1);
P1 = aa;
}
}
else
{
if(bb%2==0)
{
P1 = ~P1;
if(bb==30)
{
TR0 = 0;
P1 = 0xff;
flag1 = 1;
}
}
}
}
void time1()interrupt 3
{
TH1 = (65535-50000)/256;
TL1 = (65535-50000)%256;
ff++;
if(ff==2)
{
ff = 0;
num --;
if(num == 357)
{
TR0 = 0;
TR1 = 0;
flag = 1;
TH0 = (65536-50000)/256;//重新装入初值
TL0 = (65536-50000)%256;
TR0 = 1;
}
bai = num/100;
shi = num/10%10;
ge = num%10;
}
}
关于中断函数中写入多少程序好的分析:中断函数假设为50毫秒,程序执行的时间不要超过50毫秒,一个机器周期大约是1微妙,单周期指令,双周期指令,那么撑死他有1000,行,才是1毫秒,一般的不要太复杂,所以,在中断函数中,做一些有利于观察,有利于计算的就行了
版权所有,转载请注明链接地址:http://www.cnblogs.com/fengdashen/p/3322170.html