第1个回答 2020-01-28
做综合设计的吗?
给你个程序自己看看
#include"at89x51.h"
#define
uchar
unsigned
char
#define
uint
unsigned
int
#define
ulong
unsigned
long
/*************************
全局变量定义部分
**************************/
//硬件设计接口不同,要修改下一行
uchar
code
acLEDCS[]={0x7f,0xbf,0xdf,0xef};
uchar
code
acLedSegCode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x58,0x5e};/*
段码
*/
uchar
acLED[4];
/*
显示缓冲区
*/
char
cScanIndex;
/*
位选指针0~3
*/
uchar
cKey;
sbit
cKey1=P2^2;
sbit
cKey2=P2^1;
sbit
cKey3=P2^0;
uchar
cKeyCode;
uchar
cLongDelay;
uchar
Out[32];
bit
bStill;
/*
是否松键标志
*/
uint
nDelayKey=0;
/*
键盘延时变量,为定时中断间隔时间的整数倍
*/
uchar
cMode=0;
uchar
Num;
uchar
cF=100;
uchar
code
tosin[32]={
0x80,0x99,0xb1,0xc7,0xda,0xea,0xf6,0xfd,
0xff,0xfd,0xf5,0xe9,0xd8,0xc5,0xae,0x96,
0x80,0x66,0x4e,0x38,0x25,0x15,0x09,0x02,
0x00,0x02,0x0a,0x16,0x27,0x3a,0x51,0x69
};
union
UniT
{
uint
m_nT;
uchar
m_ucT[2];
}idata
uT;
/***************************
函数声明部分
***************************/
void
Display1(void);
void
Display2(void);
void
Scankey(void);
void
DisposeKEY(void);
/********************
按键处理程序
******************/
void
DisposeKEY(void)
{
if
(cKey1==0)
{
if(cF<134)cF++;else
cF
=
1;nDelayKey
=
2000;}
else
if
(cKey2==0){if(cF>1)cF--;else
cF
=
135;nDelayKey
=
2000;}
else
if
(cKey3==0){if(bStill==0)
{
cMode++;cMode
&=
3;
bStill
=
1;}}
//switch(cKey)
//{
//case
0x30:
/*
例如:KeyADD
*/
//
if(cF<134)cF++;
//
else
cF
=
1;
//
nDelayKey
=
2000;
/*
按住键不动,可连续产生键值,相当于连续按键
*/
//
break;
//
case
0x28:
/*
例如:KeySUB
*/
//
if(cF>1)cF--;
//
else
cF
=
135;
//
nDelayKey
=
2000;
//
break;
//
case
0x18:
//
if(bStill==0)
//
{
//
cMode++;
/*
假设有4种显示状态
*/
//
cMode
&=
3;
//
bStill
=
1;
/*
如果没松键就不会再改变显示方式
*/
//
}
//
break;
//
default:break;
//
}
Display2();
cKey
=
0;
}
void
Display2(void)
{
uchar
i;
acLED[0]=acLedSegCode[cMode+10];
/*
LED显示第1位
*/
acLED[1]=acLedSegCode[cF/100];
/*
LED显示第2位
*/
acLED[2]=acLedSegCode[cF/10%10];
/*
LED显示第3位
*/
acLED[3]=acLedSegCode[cF%10];
/*
LED显示第4位
*/
uT.m_nT=38-5760/cF;
switch(cMode)
{
case
0:
for(i=0;i<16;i++)Out[i]
=
255;
//方波
for(i=16;i<32;i++)Out[i]
=
0;
break;
case
1:
for(i=0;i<32;i++)Out[i]
=
tosin[i];
//正弦波
break;
case
2:
for(i=0;i<16;i++)Out[i]
=
i
<<
4;
//三角波
for(i=16;i<32;i++)Out[i]
=
255-i<<4;
break;
case
3:
for(i=0;i<32;i++)Out[i]
=
i<<3;
//锯齿波
break;
}
}
/**************************
主函数
*****************************/
void
main(void)
{
P3_7=0;
/****************
定时器初始化
*******************/
TMOD=
0x12;
/*
定义定时器0工作于方式2(8位自动重装),定时器1工作于方式1(16位定时器)
*/
uT.m_nT=18-2880/cF;
TH1
=uT.m_ucT[0];
TL1
=uT.m_ucT[1];
TR1
=
1;
ET1
=
1;
IP
=
0x04;
/*
T1中断优先
*/
TH0
=
-200;
/*
8位自动重装定时器约每100uS中断1次,9216次为1秒
*/
TL0
=
-200;
TR0
=
1;
ET0
=
1;
EA
=
1;
/*
开总中断
*/
while(1)
{
if(cKey)
{
DisposeKEY();
/*
响应按键操作
*/
}
}
}
/******************
多任务时序控制时钟中断
*********************/
void
IntT0(void)
interrupt
1
/*
定时器0中断,完成1秒定时和LED延时
*/
{
P0
=
0;
/*
先清显示再换位选
*/
P2
=
acLEDCS[cScanIndex];
/*
送位选数据
*/
P0
=
acLED[cScanIndex++];
/*
送显示数据,位选指针移位
*/
cScanIndex
&=
3;
/*
位选指针回位
*/
/*************************
扫描按键程序
******************/
if(nDelayKey==0)
{
cKey
=
P2
&
0x0e;
//
取键值P2.3、P2.2、P2.1
if(cKey
!=
0x0e)nDelayKey=100;//
设置延迟时间削颤
else
{
bStill
=
0;
}
//
松键
}
else
//
有按键利用DelayKey按键消颤
{
nDelayKey--;
if(nDelayKey==0)
{
cKeyCode
=
P2
&0x0e;
if(cKey
!=
cKeyCode)
{
cKeyCode
=
0;
}
}
}
}
/******************
可控制定时时间间隔的时钟中断
*********************/
void
IntT1(void)
interrupt
3
/*
定时器1中断,记录T1计时溢出次数
*/
{
TL1
=uT.m_ucT[1];
TH1
=uT.m_ucT[0];
P1
=
Out[Num++];
Num
&=
31;
}