【Keil5 C51】AT89C52 流水灯,数码管动态显示,定时器中断 综合题目

题目:

利用动态扫描和定时器1在数码管上显示出765432开始以1/10s的速度往下递减至765398
并保持显示此数,与此同时利用定时器0以500ms的速度进行流水灯从上往下移动,
当数码管显示到停止时,实验板上流水灯也停止然后全部开始闪烁,3s后(T0)流水灯全部
关闭,数码管上显示HELLO并保持

代码

/* 利用动态扫描和定时器1在数码管上显示出765432开始以1/10s的速度往下递减至765398
并保持显示此数,与此同时利用定时器0以500ms的速度进行流水灯从上往下移动,
当数码管显示到停止时,实验板上流水灯也停止然后全部开始闪烁,3s后(T0)流水灯全部
关闭,数码管上显示HELLO并保持 */

#include <reg52.h>
#include <intrins.h>

#define uint unsigned int
#define uchar unsigned char
#define ulint unsigned long int
	
sbit LE_L = P2^5;			//LED等的锁存器LE口
sbit LE_D = P2^6;
sbit LE_W = P2^7;

uchar code table_D[] = {0xC0,0xF9,0xA4,0XB0,0x99,0x92,0x82,0xF8,0x80,0x98,	//[0-9]
	0x89,0x86,0xC7,0xC0,0xFF};		//H E L O [ 10 11 12 13 不显示]
uchar code table_W[] = {0x01,0x02,0x04,0x08,0x10,0x20};	//[12345]

uint timeT0 = 0;			//T0口时间变量
uint timeT1 = 0;			//T1口时间变量
uint tempL = 0xFE;

void init();//初始化函数
void delay(uint timeY);	//延时函数
void displayN(uchar numD,uchar numW);	//单个数码管显示数字函数
void display(ulint num);	//数码管显示函数
void ledL();	//	流水灯显示函数
void ledS();	//	LED闪烁
void displayH();//数码管显示HELLO

void main(){
	ulint i = 765432;

	init();

	while(1){								//T1为数字减少计时,T0为LED流水灯间隔时间计时
		if(i != 765398){			//当数字没减到765398时进入,让数字减
			display(i);					//显示数字
			ledL();							//当数字在减少的时候LED灯流水
			if(timeT1 >= 100){	//当时间为100ms后,i--
				timeT1 = 0;				//清零T1时间变量
				i--;
				}									//T0为LED闪烁计时,T1为LED闪烁时间计时
		} else if(timeT1 <= 3000){								//当数字减到765398时,数字不再减少,常亮
				//3s内LED闪烁
			display(i);
			ledS();							//当数字减到765398时,LED灯闪烁	
		} else{							//3s后显示HELLO
					displayH();		
		}	
	}	
}

//定时器T0中断
void exterT0() interrupt 1{
	TH0 = 0xFC;		//1ms
	TL0 = 0x17;
	timeT0++;
}
//定时器T1中断
void exterT1() interrupt 3{
	TH1 = 0xFC;		//1ms
	TL1 = 0x17;
	timeT1++;
}
//数码管显示HELLO
void displayH(){
	displayN(10,0);	//H
	displayN(11,1);	//E
	displayN(12,2);	//L
	displayN(12,3);	//L
	displayN(13,4);	//O
	displayN(14,5);
}
//LED灯闪烁
void ledS(){
	if(timeT0 >= 1000){		//1s后全灭
		P1 = 0xFF;
		timeT0 = 0;
	}else if (timeT0 >= 500){	//没到1s,到0.5s时候全亮
		P1 = 0x00;					
	}
}
//LED灯流水
void ledL(){
	P1 = tempL;
	if(timeT0 >= 500){
		timeT0 = 0;
		tempL = _crol_(tempL,1);
	}
	
}
//数码管显示数字
void display(ulint num){
	//num 765432
	uchar num0 = (uchar)(num % 1000000 / 100000);
	uchar num1 = (uchar)(num % 100000 / 10000);
	uchar num2 = (uchar)(num % 10000 / 1000);
	uchar num3 = (uchar)(num % 1000 / 100);
	uchar num4 = (uchar)(num % 100 /10);
	uchar num5 = (uchar)(num % 10);
	
	displayN(num0,0);
	displayN(num1,1);
	displayN(num2,2);
	displayN(num3,3);
	displayN(num4,4);
	displayN(num5,5);

}
//数码管显示单个数字
void displayN(uchar numD,uchar numW){
	LE_D = 1;
	P0 = table_D[numD];
	LE_D = 0;
	LE_W = 1;
	P0 = table_W[numW];
	LE_W = 0;
	delay(5);
	
	//消隐
	LE_W = 1;
	P0 = 0;
	LE_W = 0;
}
//延时
void delay(uint timeY){			//每次延时1ms
	uint y;
	uint z;
	for(z = timeY; z > 0; z--){
			for(y = 115; y > 0; y--){}
	}
}
//初始化
void init(){
	
	LE_D = 1;
	P0 = 0;
	LE_D = 1;
	LE_W = 1;
	P0 = 0xFF;
	LE_W = 0;
	

	
	TMOD = 0x11;			//0001 0001
	
	TH0 = 0xFC;				//1ms
	TL0 = 0x17;	
	TH1 = 0xFC;				//1ms
	TL1 = 0x17;
	
	EA = 1;						//开总中断
	
	ET0 = 1;					//开定时器T0
	ET1 = 1;					//开定时器T1
	
	TR0 = 1;					//T0开始工作
	TR1 = 1;					//T1开始工作
}


  • 6
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值