小蜜蜂——复用P0口对LED和数码管操作

1 按键控制LED的代码

void ScanKeys()
{
	if(S4 == 0)
	{
		delayk(100);
		if(S4 == 0)
		{
			while(S4 == 0)//防止一次按下,多次执行函数。while的位置也决定了按键按下生效还是松开生效
			{
				xianshi();//数码管现实函数 这样在按键按下过程中,数码管不会显示异常
			}
			InitHC138(4);
			stat_led = (stat_led | 0x40) & (~stat_led | 0xbf);
			P0 = stat_led;
			InitHC138(0);//操作完成后所有锁存器都不选中
		}
	}
}

着重说一下 

stat_led = (stat_led | 0x40) & (~stat_led | 0xbf);
P0 = stat_led;

这两行代码正是这个题目的考察精髓点所在:因为P0口是复用的,除了LED还有数码管也在对P0赋值。所以需要一个变量单独储存LED操作情况,用这个变量赋值给P0

(stat_led | 0x40)  括号内的 低四位保持不变 高四位 除了次高位即P0^6 变为1 其他的也不变

(~stat_led | 0xbf)括号内的 除了次高位变成取反,其他的都变为1 

这样,两者相与最终结果 次高位取反 其他位不变 。实现对P0^6操作而不影响其他工作 

2 串口通信的代码段

void InitUart()
{
	TMOD = 0x21;//一共用到了两个定时器,TMOD要一起配置好
	TH1 = 0xfd;
	TL1 = 0xfd;
	TR1 = 1;
	
	SCON = 0x50;
	AUXR = 0x00;
	
	ES = 1;
	EA = 1;
}

void ServiceUart() interrupt 4
{
	if(RI == 1)
	{
		RI = 0;
		command = SBUF;
	}
}

void working()
{
	if(command != 0x00)
	{

		  switch(command & 0xf0)
	  {
		  case 0xa0:
				InitHC138(4);
				stat_led = (stat_led | 0x0f) & (~command | 0xf0);
			  P0 = stat_led;
				InitHC138(0);
			  command = 0x00;
			break;
			
			 case 0xb0:
				SendByte((h/10 << 4)|(h%10));//十进制格式变成十六进制格式,数值并不相等
			  SendByte((m/10 << 4)|(m%10));
			  SendByte((s/10 << 4)|(s%10));
			command = 0x00;
			break;
	  }
	}
}

void SendByte(unsigned char dat)
{
	SBUF = dat;
	while(TI == 0);
	TI = 0;
}

完整代码

初始化的时候数码管与要求有点差别,懒得改了
其他功能完全实现
#include"reg52.h"


sfr AUXR = 0x8e;

sbit S5 = P3^2;
sbit S4 = P3^3;
sbit L1 = P0^0;
sbit L2 = P0^1;
sbit L3 = P0^2;
sbit L4 = P0^3;
sbit L7 = P0^6;
sbit L8 = P0^7;

unsigned char code SMG_duanma[18]={

0xc0,0xf9,0xa4,0xb0,

0x99,0x92,0x82,0xf8,

0x80,0x90,0x88,0x83,

0xc6,0xa1,0x86,0x8e,
0xbf,0x7f};

unsigned char ms = 0;
unsigned char s = 0;
unsigned char m = 0;
unsigned char h = 0;
unsigned char command = 0x00;
unsigned int stat_led = 0XFF;
unsigned char urdat;

void SMG_xuanze(unsigned char dat,unsigned pos);
void xianshi();
void InitHC138(unsigned char n);
void SendByte(unsigned char dat);
void SendString(unsigned char *str);
//====================================通用函数=========================

void Delay(unsigned int t)
{
	while(t--);
}

void InitHC138(unsigned char n)
{
	switch(n)
	{
		case 4:
			P2 = (P2&0X1F) | 0X80;
		break;
		case 5:
			P2 = (P2&0X1F) | 0Xa0;
		break;
		case 6:
			P2 = (P2&0X1F) | 0Xc0;
		break;
		case 7:
			P2 = (P2&0X1F) | 0Xe0;
		break;
		case 0:
			P2 = (P2&0X1F) | 0X00;
		break;
	}
}
//=============================================================

//==================系统初始化=================================
unsigned char i = 0;
unsigned char dat = 0;
void InitSystem()
{
	InitHC138(5);
	P0 = 0X00;
	InitHC138(4);
	for(i=1;i <= 8;i++)
	{
		P0 = 0XFF<<i;
		Delay(50000);
	}
	for(i=1;i <= 8;i++)
	{
		P0 = ~(0XFF<<i);
		Delay(50000);
	}
	for(dat = 1;dat <= 8;dat++)
	{
	  SMG_xuanze(0x00,dat);	
		Delay(50000);
	}

}
//=======================秒表======================================
void InitTimer()
{
	TH0 = (65535 - 50000)/256;//50ms
	TL0 = (65535 - 50000)%256;

	ET0 = 1;
	EA = 1;
	TR0 = 1;
}

void ServiceTimer0() interrupt 1
{
	TH0 = (65535 - 50000)/256;
	TL0 = (65535 - 50000)%256;

	ms++;

	if(ms == 20)//1s
	{
		s++;
		ms = 0;
		if(s == 60)
		{
			m++;
			s = 0;
		}
		if(m == 60)
		{
			h++;
			m = 0;
		}
	}
}
//==========================串口通信=======================
void InitUart()
{
	TMOD = 0x21;
	TH1 = 0xfd;
	TL1 = 0xfd;
	TR1 = 1;
	
	SCON = 0x50;
	AUXR = 0x00;
	
	ES = 1;
	EA = 1;
}

void ServiceUart() interrupt 4
{
	if(RI == 1)
	{
		RI = 0;
		command = SBUF;
	}
}

void working()
{
	if(command != 0x00)
	{

		  switch(command & 0xf0)
	  {
		  case 0xa0:
				InitHC138(4);
				stat_led = (stat_led | 0x0f) & (~command | 0xf0);
			  P0 = stat_led;
				InitHC138(0);
			  command = 0x00;
			break;
			
			 case 0xb0:
				SendByte((h/10 << 4)|(h%10));//Ê®½øÖÆСʱת³ÉBCDÂë
			  SendByte((m/10 << 4)|(m%10));
			  SendByte((s/10 << 4)|(s%10));
			command = 0x00;
			break;
	  }
	}
}

void SendByte(unsigned char dat)
{
	SBUF = dat;
	while(TI == 0);
	TI = 0;
}
//ÕâÊÇ·¢ËÍ×Ö·û´®
/*void SendString(unsigned char *str)
{
	while(*str != '\0')
	{
		SendByte(*str++);
	}
}
*/
//===============================================================


//==================数码管显示==========================
void SMG_xuanze(unsigned char dat,unsigned pos)
{
	InitHC138(6);
	P0 = 0X01 << pos;
	InitHC138(7);
	P0 = dat;
}



void xianshi()
{
	SMG_xuanze(SMG_duanma[h/10],0);
	Delay(500);
	SMG_xuanze(SMG_duanma[h%10],1);
	Delay(500);
	SMG_xuanze(SMG_duanma[16],2);
	Delay(500);
	SMG_xuanze(SMG_duanma[m/10],3);
	Delay(500);
	SMG_xuanze(SMG_duanma[m%10],4);
	Delay(500);
	SMG_xuanze(SMG_duanma[16],5);
	Delay(500);
	SMG_xuanze(SMG_duanma[s/10],6);
	Delay(500);
	SMG_xuanze(SMG_duanma[s%10],7);
	Delay(500);
}
//============================================
//===================按键===================
void delayk(unsigned char time)
{
	while(time--);
}

void ScanKeys()
{
	if(S4 == 0)
	{
		delayk(100);
		if(S4 == 0)
		{
			while(S4 == 0)
			{
				xianshi();
			}
			InitHC138(4);
			stat_led = (stat_led | 0x40) & (~stat_led | 0xbf);
			P0 = stat_led;
			InitHC138(0);
		}
	}
	if(S5 == 0)
	{
		delayk(100);
		if(S5 == 0)
		{
			while(S5 == 0)
			{
				xianshi();
			}
			InitHC138(4);
			stat_led = (stat_led | 0x80) & (~stat_led | 0x7f);
			P0 = stat_led;
			InitHC138(0);
		}
	}
}
//==============================================


void main()
{
	InitUart();
	InitSystem();
	InitTimer();
	while(1)
	{
		xianshi();
		ScanKeys();
		working();
	}
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值