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();
}
}