|
发表于 2020-3-10 22:10:16
|
显示全部楼层
#include"at89x52.h"
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
uchar code acLEDCS[]={0xe0,0xd0,0xb0,0x70}; /* 位选地址码,“0”有效,位选接的是P2口高4位 */
uchar code acLedSegCode[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c};/* 段码 */
uchar acLED[4]; /* 显示缓冲区 */
char cScanIndex; /* 位选指针0~3 */
uchar cKey; /* 初始键值 */
uchar cKeyCode; /* 键值 */
uchar cLongDelay; /* 按键长按时间 */
bit bStill; /* 是否松键标志 */
char cMode; /* 显示方式变量,0~3对应4种方式 */
uint nTimer; /* 定时计数变量,为定时中断间隔时间的整数倍 */
uint nDelayKey; /* 键盘延时变量,为定时中断间隔时间的整数倍 */
uint nComnTimer; /* 通信等待延时计时变量,为定时中断间隔时间的整数倍 */
bit bComOK; /* 数据包完整接收标志 */
uchar ucRecnum; /* 已接收字符数变量 */
//根据不同题目再添加一些变量
/* 联合变量(大名2字节,小名2*1字节保存在同一物理空间),可用于定时器初值计算,控制中断周期 */
union UniT
{
uint m_nT;
uchar m_ucT[2];
}idata uT;
/************************* 数码管显示函数 ***************************/
void display()
{ // 添加要显示的数据
acLED[0]=acLedSegCode[??? / 1000]; /* LED显示第1位 */
acLED[1]=acLedSegCode[??? / 100 % 10]; /* LED显示第2位 */
acLED[1]=acLedSegCode[??? % 1000/100]; /* LED显示第2位 */
acLED[2]=acLedSegCode[???/10%10]; /* LED显示第3位 */
acLED[3]=acLedSegCode[???%10]; /* LED显示第4位 */
}
/******************** 按键处理程序 ******************/
void DisposeKEY()
{
switch(cKEY)
{
case 6: /* 例如:KeyADD */
// 此处添加按键相应的变量变化
nDelayKey = 2000; /* 按住键不动,可连续产生键值,相当于连续按键 */
break;
case 5: /* 例如:KeySUB */
// 此处添加按键相应的变量变化
nDelayKey = 2000;
break;
case 3: /* 例如:KeyMode */
if(bStill==0)
{
if(cMode++==4) /* 假设有4种显示状态 */
{
cMode = 0;
}
bStill = 1; /* 如果没松键就不会再改变显示方式 */
}
break;
case 2:
if(cLongDelay<3)
{
cLongDelay++;
nDelayKey = 9216;
break;
}
cLongDelay = 0;
Mode = SetSome;
//
break;
}
display();
cKEY = 0;
}
/************************** 主函数 *****************************/
void main(void)
{
/**************** 定时器初始化 *******************/
TMOD= 0x12;
TH1 = 0; /* 16位定时器,测每周的时间 */
TL1 = 0;
TR1 = 1;
ET1 = 1;
IP = 0x04; /* T1中断优先 */
RCAP2L = 0;
RCAP2H = 0;
TR2 = 1; /* 启动T2定时器*/
ET2 = 1;
/**************** 串口初始化 *******************/
// TMOD = 0x22;
// SCON = 0x50 /* =50;串口工作在方1,REN=1(允许接收)=d0:串口方式3 */
// TL1 = 0xfa;
// TH1 = 0xfa;
// IP = 0x10 /* 串口中断优先 */
// TR1 = 1; /* 启动T1,T1是波特率发生器(对应22.1184M晶振,9600bps)*/
// ES = 1; /* 允许串口中断 */
TH0 = -200; /* 8位自动重装定时器约每100uS中断1次,9216次为1秒 */
TL0 = -200;
TR0 = 1;
ET0 = 1;
EX0 = 1; /* 允许外部中断0 */
EA = 1; /* 开总中断 */
display(); /* 显示初始界面 */
while(1)
{
if(cKEY)
{
DisposeKEY(); /* 响应按键操作 */
}
if(bComOK)
{
bComOK = 0;
DisComm(); /* 响应从串口接收的命令 */
}
}
}
/****************** 多任务时序控制时钟中断 *********************/
void IntT0() interrupt 1
{
//*************************中断次数计数******************
nTimer++;
if(nTimer == 9216) /* 满1秒,进行秒处理 */
{
/* 根据需要添加 */
}
//*************************显示刷新******************
P0 = 0; /* 先清显示再换位选 */
P2 = acLEDCS[cScanIndex]; /* 送位选数据 */
P0 = acLed[cScanIndex++]; /* 送显示数据,位选指针移位 */
cScanIndex &= 3; /* 位选指针回位 */
//*************************扫描按键******************
if(nDelayKey==0)
{
cKey = P2 & 0x07; // 取键值P10、P11、P12
if(cKey != 0x07)nDelayKey=100;// 设置延迟时间削颤
else
{
bStill=0;
cLongDelay=0;
} // 松键
}
else // 有按键利用DelayKey按键消颤
{
nDelayKey--;
if(nDelayKey==0)
{
cKeyCode = P2 &0x07; // 取键值P10、P11、P12
if(cKey != cKeyCode)
{
cKeyCode = 0;
}
}
}
// if(nComnTimer)
// nComnTimer--; /* 通信等待延时计时变量 */
// 还可以添加其他任务
}
/****************** 可控制定时时间间隔的时钟中断 *********************/
void IntT1() interrupt 3 /* 定时器1中断,记录T1计时溢出次数 */
{
// 此处添加定时时间间隔可变的任务
}
/****************** 外部中断服务 *************************/
void Pint0() interrupt 0 /* 电机每周产生1次外部中断0,取定时器1计数值,计算每秒转速 */
{
// 此处添加在外部中断发生时的操作命令
}
/****************** 串口中断服务 *************************/
void Serial() interrupt 4
{
if(TI)TI=0;
else
{
ComBuf[ucRecnum++] = SBUF; /* 接收串口数据 */
ucCheck += SBUF; /* 计算校验和 */
RI = 0;
if(ucRecnum == ?)
{
ucRecnum = 0;
bComOK = 1;
}
}
}
/****************** 通过串口发送1个字节 *************************/
void SendAByte(uchar LData)
{
SBUF = LData;
nComTimer = 200;
while(TI==0 && nComnTimer);
}
//一个程序框架很屌的 |
|