电子科技大学现代电子信息系统综合实验课程单片机练习题代码

接上一篇博客https://blog.csdn.net/Jinyindao243052/article/details/107822771
除了实现练习题的功能,我自己还写了一些函数,实践证明在考试中用得到!

#include 
#include 
#include 
//数码管的引脚
sbit led0=P0^0;
sbit led1=P0^1;
sbit led2=P0^2;
sbit led3=P0^3;
sbit led4=P0^4;
sbit led5=P0^5;
sbit led6=P0^6;
sbit led7=P0^7;
//定义按键
sbit KEY2 = P2^0;		//按键1
sbit KEY3 = P2^1;		//按键2
unsigned char key;
unsigned char DispBuf[8];
unsigned char s_led[8]={1,1,1,1,1,1,1,1};//led显示控制:s_led[0]对应最右边的数码管
unsigned char s_dat[8]={1,1,1,0,0,1,1,1};//数码管显示控制:s_dat[0]对应最右边的数码管
unsigned char d[8]={1,1,1,15,14,1,1,1};//数据:d[0]对应最右边的数码管
code unsigned char Tab[] =																																		
	{//定义0123456789AbCdEF的数码管字型数据
		0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
		0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71
	};
/*
函数:KeyScan()
功能:键盘扫描
返回:扫描到的键值
*/
unsigned char KeyScan()
{
	unsigned char k = '\0';
	if ( KEY2 == 0 ) k = 'A';
	if ( KEY3== 0 ) k = 'B';
	return k;
}


//定义显示缓冲区(由定时中断程序自动扫描)
unsigned char DispBuf[8];

/*
函数:T1INTSVC()
功能:定时器T1的中断服务函数,扫描数码管
*/
void T1INTSVC() interrupt 3
{
	code unsigned char com[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
	static unsigned char n = 0;
	TR1 = 0;
	TH1 = 0xFC;
	TL1 = 0x66;
	TR1 = 1;
	XBYTE[0x7800] = 0xFF;		//暂停显示
	XBYTE[0x7801] = ~DispBuf[n];	//更新扫描数据
	XBYTE[0x7800] = ~com[n];	//重新显示
	n++;
	n &= 0x07;
}


/*
函数:DispClear()
功能:清除DispBuf
*/
void DispClear()
{
	unsigned char i;
	for ( i=0; i<8; i++ )
	{
		DispBuf[i] = 0x00;
	}
}


//延时函数
void delay(unsigned int t)
{
	do
	{
		TH0 = 0xFA;
		TL0 = 0x24;		//设置定时器初值(对应0.001s)
		TR0 = 1;		//启动定时器
		while ( !TF0 );	//等待定时器溢出
		TR0 = 0;		//停止定时器
		TF0 = 0;		//清除溢出标志
	} while ( --t != 0 );	//循环t次
}
/*
函数:DispInit()
功能:数码管扫描显示初始化
*/
void DispInit()
{
	DispClear();	//初始为全灭
	EA = 0;
	TMOD &= 0x0F;
	TMOD |= 0x10;
	TH1 = 0xFC;
	TL1 = 0x66;
	TR1 = 1;
	ET1 = 1;
	EA = 1;
}
/*系统初始化函数*/
void SysInit()
{
	TMOD &= 0xF0;
	TMOD |= 0x01;	//设置定时器T0为16位定时器
	DispInit();		//数码管扫描显示初始化
}

//自己实现的函数
/*
LED全部熄灭
*/
void ledclear()
{
   led0=1;
   led1=1;
   led2=1;
   led3=1;
   led4=1;
   led5=1;
   led6=1;
   led7=1;
  
}
/*
led灯控制函数
s[0]对应最右边的LED灯,0为亮,1为不亮
*/
void displed(unsigned char s[8])
{    
   unsigned char i=0;
   ledclear();
   if(s[0]==0)
   led0=0;
   if(s[1]==0)
   led1=0;
   if(s[2]==0)
   led2=0;
   if(s[3]==0)
   led3=0;
   if(s[4]==0)
   led4=0;
   if(s[5]==0)
   led5=0;
   if(s[6]==0)
   led6=0;
   if(s[7]==0)
   led7=0;
}
//实现led向左循环移动times次
shift_ledr(unsigned char times)
{   
    unsigned char i=0;
	unsigned char j=0;
	unsigned char temp=0;
	for(i=0;i<times;i++)
	{
	    temp=s_led[0];
		for(j=1;j<=7;j++)
		{
		s_led[j-1]=s_led[j];
		}
		s_led[7]=temp;
		displed(s_led);
	}
}
//实现led向右循环移动times次
shift_ledl(unsigned char times)
{   
    unsigned char i=0;
	unsigned char j=0;
	unsigned char temp=0;
	for(i=0;i<times;i++)
	{
	    temp=s_led[7];
		for(j=7;j>=1;j--)
		{
		s_led[j]=s_led[j-1];
		}
		s_led[0]=temp;
		displed(s_led);
	}
}
/* 数码管显示控制函数
s控制哪个数码管亮,dat控制对应位置显示哪个数
s[0]对应最右边的数码管,DispBuf[0],0为亮,1为灭
dat[0]对应最右边的数码管,DispBuf[0],是几就显示几
*/
void dispdata(unsigned char s[8],unsigned char d[8])

{   	
   DispClear();
   if(s[0]==0)
   DispBuf[0]=Tab[d[0]];
   if(s[1]==0)
   DispBuf[1]=Tab[d[1]];
   if(s[2]==0)
   DispBuf[2]=Tab[d[2]];
   if(s[3]==0)
   DispBuf[3]=Tab[d[3]];
   if(s[4]==0)
   DispBuf[4]=Tab[d[4]];
   if(s[5]==0)
   DispBuf[5]=Tab[d[5]];
   if(s[6]==0)
   DispBuf[6]=Tab[d[6]];
   if(s[7]==0)
   DispBuf[7]=Tab[d[7]];
}
void shift_l(unsigned char times)//数码管左移左移times次
{
unsigned char i=0;
unsigned char j=0;
unsigned char temp1=0;
unsigned char temp2=0;
unsigned char temp3=0;
for(j=0;j<times;j++)
{

    temp1=s_dat[7];
	temp2=d[7];
	for(i=7;i>=1;i--)
	{
		s_dat[i]=s_dat[i-1];
		d[i]=d[i-1];
	}
	s_dat[0]=temp1;
	d[0]=temp2;
	//控制每次停留的时间

}
    dispdata(s_dat,d);
}

/*
更改d的数值
把temp的数值赋给d
*/
void modify_d(unsigned char temp[8])
{    
 	unsigned char i=0;
	for(i=0;i<8;i++)
	{
	 	  d[i]=temp[i];	
	} 
}
/*
修改d的某一位
把第a位改为b
*/
void modify_d_bit(unsigned char a,unsigned char b)
{
   d[a]=b;

}
/*判断是否有键按下,按下退出*/
void keyin()
{
 for(;;)
   {
    delay(50);
	key=KeyScan();
	if(key!='\0')
	{
	   break;
	}
   }
}
/*
判断按键是否抬起,抬起退出
*/
void keyout()
{
   for(;;)
   {
	  delay(50);
	  key=KeyScan();
	  if(key=='\0')
	  {
	    break;
	  }
   }
}
/*
把num代表的数存储到是s数组中,保存位数的长度是len
*/
void num2str(unsigned char *s,unsigned int num,unsigned char len)
{
 	 unsigned char i=0;
	 unsigned char temp=0;
	 for(i=0;i<len;i++)
	 {
	    temp=num%10;
		num=(num-temp)/10;
		*s++=temp;
	 }
}
/*
改变s_dat,把第a位设置为0或1
*/
void modify_s_dat_bit(unsigned char a,unsigned char b)
{
   s_dat[a]=b;
   if(b==1)
   {
   DispBuf[a]=0x00;
   }
   else
   {
   DispBuf[a]=Tab[d[a]];
   }
}
/*
更改s_dat,控制哪些数码管亮
*/
void modify_s_dat(unsigned char s[8])
{
   	 unsigned char i=0;
	 for(i=0;i<8;i++)
	 {
		 s_dat[i]=s[i];
		 if(s_dat[i]==1)
		 {
		    DispBuf[i]=0x00;
		 }
		 else
		 {
		    DispBuf[i]=Tab[d[i]];
		 }
	 }
}

  /*
快速改变灯的第a位的亮灭
b=0亮,b=1灭
*/
void modify_s_led(unsigned char a,unsigned char b)
{
  s_led[a]=b;
  displed(s_led);
}
/*
对char类型的0和1取反
char a=0
a=0x08
不像sbit类型一样可以直接取反
*/
unsigned char convert(unsigned char a)
{
   unsigned char b=0;
   if(a==0)
   {
	 b=1;
   }
   return b;
}


void main()
{	
    unsigned char temp[8]={1,1,1,0,0,1,1,1};
	unsigned char temp1[8]={1,1,0,0,1,1,7,1};
	unsigned char temp3;
	unsigned char temp4=0;
	unsigned char temp5=0;
	unsigned char temp6=0;
	unsigned char i=0;
	unsigned char mode0=0;
	unsigned char mode1=0;
	unsigned char wait=0;
	
	SysInit();
	displed(s_led);
	dispdata(s_dat,d);
	delay(2000);
	d[6]=9;
	dispdata(s_dat,d);
	for(;;)
	{
		  	 	for(;;)
                 {
                    delay(50);
                	key=KeyScan();
                	if(key!='\0')
	                {
	                  break;
                    }

					if(wait==20)
					{ 
					  if(mode1==1)
					  {
					  s_led[0]=convert(s_led[0]);
					  displed(s_led);
					  temp4++;
					  if(temp4==10)
					  {
						 shift_l(1);
						 temp4=0;
					  }
					  }
					}			   

					wait++;
					if(wait==21)
					{
					  wait=0;
					}

                  }
	
		if(key=='A')
		{
		   mode0=convert(mode0);
           s_led[7]=convert(s_led[7]);
		   displed(s_led);
		}
		if(key=='B')
		{
		   mode1=convert(mode1);
		   if(mode1==0)
		   {
			temp4=0;
			s_led[0]=1;
			displed(s_led);
		   }
		}
		 for(temp5=0;temp5<8;temp5++)
			{
			 
			 if(d[temp5]!=1)
			 { 
			 for(temp6=temp5+1;temp6<8;temp6++)
			 {
			   if(d[temp6]!=1)
			   {
				break;
			   }
			 }
			 break;
			 }			
			 }
		if(mode0==0&mode1==0)
		{
			if(temp5!=0)
			{
			 d[temp5]=15;
			 d[temp6]=14;
			}
			else
			{
			 d[temp6]=15;
			 d[temp5]=14;
			}
		}
		else
		{
		    if(temp5!=0)
			{
			 d[temp5]=9;
			 d[temp6]=0;
			}
			else
			{
			 d[temp6]=9;
			 d[temp5]=0;
			}
		}
		dispdata(s_dat,d);
			 
		    	for(;;)
                 {
                    delay(50);
                	key=KeyScan();
                	if(key=='\0')
	                {
	                  break;
                    }
		 
	             } 
       }
}

你可能感兴趣的:(其他,单片机,经验分享)