数码管的动态显示:精简代码版,要注意关灯,否则有问题,还有时间消影,这个例子虽然很简单,但是精简代码百分之九十的人会写错
#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