51单片机006:利用动态扫描和定时器1在数码管上显示出从765开始以1/10秒的速度往下递减直至321并保持显示此数,与此同时利用定时器0以500MS速度进行流水灯从上至下移动,当数码管上数减到……

题目:利用动态扫描和定时器1在数码管上显示出从765开始以1/10秒的速度往下递减直至321并保持显示此数,与此同时利用定时器0以500MS速度进行流水灯从上至下移动,当数码管上数减到停止时,实验板上流水灯也停止然后全部开始闪烁,3秒后(用T0定时)流水灯全部关闭、数码管上显示出“HAO”。到此保持住。

思路:

1、“从765开始以1/10秒的速度往下递减直至321并保持显示此数”:

定义num变量,初始值为765,定时器定时0.1s,num--,完成向下递减效果,保持显示此数,可以通过控制TCON中的TR0/TR1运行控制寄存器,使定时器停止计时,num就不会向下递减。

2、“利用定时器0以500MS速度进行流水灯从上至下移动”:

一个简单的利用定时器实现流水灯

3、“当数码管上数减到停止时,实验板上流水灯也停止然后全部开始闪烁,3秒后(用T0定时)流水灯全部关闭、数码管上显示出“HAO”。到此保持住。”

数码管和LED可分为以下几个阶段:

阶段一:数码管数字递减,LED为流水灯

阶段二:数码管显示321,LED闪烁三秒

阶段三:数码管显示HAO,LED关闭

定义两个状态变量,flag和flag_led。

当flag == 0,flag_led == 0时:数码管递减,LED效果为流水灯

当flag == 1,flag_led == 0时:数码管显示为321,LED效果为闪烁3s

当flag_led == 1,flag == 1时:数码管显示为HAO,LED效果为关闭

原理图:

代码:

说明:由于进行数码管位选时和LED的引脚有些冲突,所以只选取了后三位LED灯进行流水灯演示。

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

//定义数码管位选信号控制脚
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

//定义LED位选信号控制脚
sbit led5=P2^5;
sbit led6=P2^6;
sbit led7=P2^7;

//共阴极数码管显示0~F的段码数据
unsigned char gsmg_code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,  //0-9
								0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x76,0x3f};      //a-f , h ,o


unsigned int num = 765;
unsigned int flag = 0;
unsigned int flag_led = 0;
unsigned int count_10ms;  //定义10ms计时变量
unsigned int count_50ms;  //定义50ms计时变量
				
//延时函数
void delay_10us(unsigned int ten_us)
{
	while(ten_us--);	
}
				

/*****************************数码管*****************************/
void shumaguan(unsigned char location,number)
{
	P0=0x00;
  switch(location)
	{ 
	  case 8:LSC=0;LSB=0;LSA=0;break;
		case 7:LSC=0;LSB=0;LSA=1;break;
	  case 6:LSC=0;LSB=1;LSA=0;break;
	  case 5:LSC=0;LSB=1;LSA=1;break;
		case 4:LSC=1;LSB=0;LSA=0;break;
		case 3:LSC=1;LSB=0;LSA=1;break;
		case 2:LSC=1;LSB=1;LSA=0;break;
		case 1:LSC=1;LSB=1;LSA=1;break;
	}
	P0=gsmg_code[number];
} 

void smg_display(unsigned int num)
{
	if(flag == 0)
	{
		shumaguan(1,num/100);
		delay_10us(100);	
		shumaguan(2,(num/10)%10);
		delay_10us(100);
		shumaguan(3,num%10);
		delay_10us(100);
	}
	if(flag_led == 1)
	{
		shumaguan(1,17); //H  
		delay_10us(100);
		shumaguan(2,10); //A
		delay_10us(100);
		shumaguan(3,18); //O
		delay_10us(100);
	}
	
}

/****************************定时器********************************/
/*****定时器1********/
void time1_init(void)
{
	TMOD|=0X10;             //选择为定时器1模式,工作方式1
	TH0=(65535-10000)/256;  //10ms循环10次
	TL0=(65535-10000)%256;	
	ET1=1;                  //打开定时器1中断允许
	EA=1;                   //打开总中断
	TR1=1;                  //打开定时器		
}

void time1() interrupt 3  //定时器1中断函数
{
	TH0=(65535-10000)/256;  //10ms循环10次
	TL0=(65535-10000)%256;	
	count_10ms++;
}

/*******定时器0**********/
void time0_init(void)
{
	TMOD|=0X01;               //选择为定时器0模式,工作方式1
	TH0=(65535-50000)/256;    //50ms定时10次
	TL0=(65535-50000)%256;
	ET0=1;                    //打开定时器0中断允许
	EA=1;                     //打开总中断
	TR0=1;                    //打开定时器		
}

void time0() interrupt 1    //定时器0中断函数
{

	TH0=(65535-50000)/256;    //50ms定时10次
	TL0=(65535-50000)%256;
	count_50ms++;
}
	

void main()
{
	time0_init();
	time1_init();
	while(1)
	{
		smg_display(num);
		if(count_10ms == 10) 
		{
			count_10ms = 0;
			num--;		
			smg_display(num);
			if(num == 321)
			{
				TR1 = 0;     //停止计时
				flag = 1;
				smg_display(num);
			}
		}
		
		if(flag == 0)  //流水灯
		{
				flag_led = 0;
				if(count_50ms==10) //500ms
				{
					led5=0;led6=1;led7=1;
				}			
				if(count_50ms==20) //500ms
				{
					led5=1;led6=0;led7=1;
				}		
				if(count_50ms==30) //500ms
				{
					led5=1;led6=1;led7=0;
					count_50ms = 0;
				}					
		}
		else  //led闪烁 
		{	
			if(count_50ms <= 60)
			{
				led5=1;led6=1;led7=1; //全部熄灭
				delay_10us(10);
				led5=0;led6=0;led7=0; //全部点亮
				delay_10us(10);
			}
			//到了3s
			else
			{
				TR0 = 0;
				flag_led = 1;
				led5=1;led6=1;led7=1; //全部熄灭
			}
		}
	}
}

posted @ 2023-12-07 10:38  Flying3080  Views(73)  Comments(0Edit  收藏  举报  来源