📄 keymatrix3.c
字号:
//******************************************************************************
#include "At89x52.h"
#include "Intrins.h"
//******************************************************************************
//******************************************************************************
#define uchar unsigned char
//******************************************************************************
/* Bit Address Assignment*/
/*
sbit LedIn1=P0^0; //LED光感应输入
sbit LedIn2=P0^1;
sbit LedIn3=P0^2;
sbit LedIn4=P0^3;
sbit LedIn5=P0^4;
sbit LedIn6=P0^5;
sbit LedIn7=P0^6;
sbit LedIn8=P0^7;
sbit LedIn9=P2^0;
sbit LedIn10=P2^1;
*/
sbit Mc14Inh1=P1^3; //P2^2; //4-16译码器禁止位
sbit Mc14Inh2=P2^3;
sbit FixUpLeft=P2^4; //P2^4;
sbit FixUpRight=P2^5;
sbit FixDownLeft=P3^2;
sbit FixDownRight=P3^3;
sbit latch1=P2^2;
sbit latch2=P2^3;
sbit EncoderA=P2^6; //译码信号输出
sbit EncoderB=P2^7;
sbit BoardPower1=P3^4;
sbit BoardPower2=P3^5;
sbit BoardPower3=P3^6;
sbit BoardPower4=P3^7;
//******************************************************************************
volatile uchar MsgOk=0x00;
volatile uchar Rs232State=0x00;
volatile uchar Rs232Timer=0; //单位:100ms
uchar ReceiveBuffer[2];
uchar SendBuffer[13];
bit w25msf; //2.5ms标志
volatile uchar Timer1s=0;
volatile uchar Timer100ms=0;
volatile uchar Timer2500us=0;
//******************************************************************************
void Send(len)
//功能:发送一帧消息,消息格式参见设计说明
//入口:len=正文信息长度
{
uchar *p;
uchar CheckSum=0;
// uchar code MSG_VER[]="200402200005";
//发送用查询方式,关闭串口中断
ES=0;
//发送2字节起始同符0xA5,0x5A
// SBUF=0xA5;while(!TI);TI=0;
// SBUF=0x5A;while(!TI);TI=0;
//发送长度字节
// SBUF=12+len;while(!TI);TI=0;
//SBUF=len;while(!TI);TI=0;
//发送版本信息
/* p=MSG_VER;
while(*p)
{
SBUF=*p;
CheckSum+=*p++;
while(!TI);TI=0;
} */
//发送正文信息
p=SendBuffer;
do
{
SBUF=*p;
CheckSum+=*p++;
while(!TI);TI=0;
}while(--len);
//发送检测和字节
//SBUF=CheckSum;
// while(!TI);
// TI=0;
//恢复串口中断
ES=1;
}
//******************************************************************************
//******************************************************************************
void Init()
{
uchar i,j;
//中断配置:本系统仅使用串口中断(高优先级)和定时中断0(低优先级),
//BIT 7 6 5 4 3 2 1 0
//IE: EA – ET2 ES ET1 EX1 ET0 EX0
// 0 0 0 1 0 0 1 0
IE=0x12;
IP=0x10;
//delay some time for stable
for(i=0;i<200;i++) for(j=0;j<250;j++);
//I/O端口初始化
P0=0xFF; //P0为给MPPC的/RESET和/REQ信号,正常状态无效置高
P1=0xFF; //P1为从MPPC输入经过74HC244缓冲的的输入信号,要求置高才能读
P2=0xFF; //P20,P21为给译码器74HC139地址信号A0和A1,其它未用置高
P3=0xFF; //P30,P31分别为串口信号RXD和TXD,
//设定串口模式为:8位波特率可鹿编程单机模式,即模式1,置接收使能
SCON=0x50;
//T0用作2.5mm定时器,T1用作9600bps的波特率发生器
TMOD=0x21; //T1为8位自动重载,T0为16位软件重载定时
TH0=0xF7; //2.5ms=0.0025=Tosc*12*(0x10000-T0)==>T0=0x10000-0.0025*Fosc/12=0xF700
TL0=0x00;
PCON=0x00; //SMOD=0
TH1=TL1=0xFD; //TH1=256-Fosc/{[2^(1-SMOD)]*16*12*9600bps}=0xFD
TCON=0x50; //0101 0000 (TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0)
//定时器2未用,设为缺省值
T2CON=T2MOD=0x00;
RCAP2L=RCAP2H=0x00;
TL2=TH2=0x00;
EA=1;
}
//******************************************************************************
//******************************************************************************
void Recieve()interrupt 4 using 3 //command recieve
//0xA5,0x5A,len,msg,cs
{
static uchar i; //len, //定义len和i为静态存贮变量,即在程序运行期间,固定分配物理空间。
// static uchar CheckSum;
if(RI&&(MsgOk!=0x55))
{
switch(Rs232State)
{
/* case 0:
{
if(SBUF==0xA5)
{
++Rs232State;
Rs232Timer=20; //设定超时值100ms*20=2S!
}
break;
}
case 1:
{
if(SBUF==0x5A) ++Rs232State;
else Rs232State=0;
break;
}
case 2:
{
len=SBUF;
if( (len==1) || (len==2) )
{
++Rs232State;
CheckSum=0;
i=0;
}
else Rs232State=0;
break;
} */
case 0:
{ i=0;
ReceiveBuffer[i]=SBUF;
++i;
++Rs232State;
// CheckSum+=ReceiveBuffer[i];
// if(++i==len) Rs232State=4;
break;
}
case 1:
{ ReceiveBuffer[i]=SBUF;
if (++i==2) Rs232State=0; MsgOk=0x55;
// uchar tmp=SBUF;
// if(CheckSum==tmp) MsgOk=0x55;
// Rs232State=0;
break;
}
default:Rs232State=0;break;
}
}
RI=TI=0;
}
//******************************************************************************
//******************************************************************************
void Timer0(void)interrupt 1 using 2
//2.5ms一次中断
{
static uchar i=40; //定义j和i为静态存贮变量,即在程序运行期间,固定分配物理空间。而不是需要才分配。
static uchar j=10;
TR0=0;TH0=0xf7;TL0=0x00;TR0=1;
w25msf=1;
if(Timer2500us) Timer2500us--;
if(--i==0)
{
i=40;
if(Timer100ms) Timer100ms--;
if(Rs232Timer) Rs232Timer--;
if(Rs232Timer==0) Rs232State=0;
if(--j==0)
{
j=10;
if(Timer1s) Timer1s--;
}
}
}
//******************************************************************************
//******************************************************************************
void main()
{
uchar ScanL1;
uchar ScanH1;
uchar LedInL1;
uchar LedInH1;
uchar DelayTime;
uchar PowerCount1;
uchar PowerCount2;
uchar OffCount1;
uchar OffCount2;
uchar HubCount1;
uchar HubCount2;
Init();
PowerCount1=0;
PowerCount2=0;
OffCount1=0;
OffCount2=0;
HubCount1=0;
HubCount2=0;
while(1)
{ latch2=0; //关闭译码器二
latch1=0; //关闭译码器一
if(MsgOk==0x55) //收到PC机命令
{
if (FixDownLeft&&FixDownRight) {SendBuffer[0]=0xA5;SendBuffer[1]=0x00;Send(2);}
else if(!(FixDownLeft||FixDownRight)) {SendBuffer[0]=0xA5;SendBuffer[1]=0x01;Send(2);}
else if (!FixDownLeft)
{
switch(ReceiveBuffer[0])
{
case 0xA0: //收到启动命令消息
{
switch (ReceiveBuffer[1])
{case 0x01:
if (PowerCount1==0)
{ ++PowerCount1;
BoardPower1=0; //BOARD1电源开
Timer2500us=200;
while(Timer2500us); //延时500ms
SendBuffer[0]=0xA0;
SendBuffer[1]=0x31;
Send(2);}
else if (PowerCount1==1)
{PowerCount1=0;
BoardPower2=0; //BOARD2电源开
Timer2500us=200;
while(Timer2500us); //延时500ms
SendBuffer[0]=0xA0;
SendBuffer[1]=0x31;
Send(2);}
break;
case 0x00:
if (OffCount1==0)
{++OffCount1;
BoardPower1=1; //BOARD1电源关
Timer2500us=200;
while(Timer2500us); //延时500ms
SendBuffer[0]=0xA0;
SendBuffer[1]=0x30;
Send(2);}
else if (OffCount1==1)
{OffCount1=0;
BoardPower2=1; //BOARD1电源关
/* FixUpLeft=0;
Timer2500us=200;
while(Timer2500us); //延时500ms
FixUpLeft=1; */
SendBuffer[0]=0xA0;
SendBuffer[1]=0x30;
Send(2);}
break;
default:
break;
}
break;
}
case 0xA1: //收到结束命令
{ switch (ReceiveBuffer[1])
{case 0x01:
Timer2500us=25;
while(Timer2500us); //延时500ms
LedInL1=P0;
LedInH1=P2;
//LedInH1=LedInH1&&0x03;
SendBuffer[0]=0xA1;
SendBuffer[1]=LedInH1;
SendBuffer[2]=LedInL1;
Send(3);
break;
case 0x00: //收到测试LED OFF命令
Timer2500us=25;
while(Timer2500us); //延时500ms
LedInL1=P0;
LedInH1=P2;
SendBuffer[0]=0xA1;
SendBuffer[1]=LedInH1;
SendBuffer[2]=LedInL1;
Send(3);
break;
default:
break;
}
break;
}
case 0xA2:
{ switch (ReceiveBuffer[1])
{case 0x01:
Timer2500us=25;
while(Timer2500us); //延时500ms
latch2=0; //关闭译码器二
latch1=1; //打开译码器一
for (ScanL1=0;ScanL1<=16;ScanL1++)
{P1=ScanL1;
Timer2500us=DelayTime;
while(Timer2500us);
}
latch1=0; //关闭译码器一
latch2=1; //打开译码器二
for (ScanH1=0;ScanH1<=11;ScanH1++)
{P1=(ScanH1<<4);
Timer2500us=DelayTime;
while(Timer2500us);
}
latch2=0; //关闭译码器二
SendBuffer[0]=0xA2;
SendBuffer[1]=0x30;
Send(2);
break;
case 0x00:
Timer2500us=25;
while(Timer2500us);
latch1=0; //关闭译码器一
latch2=0; //关闭译码器二
break;
default:
break;
}
break;
}
case 0xA3:
{
switch (ReceiveBuffer[1])
{case 0x01:
Timer2500us=10;
while(Timer2500us);
EncoderB=1;
Timer2500us=2;
while(Timer2500us);
EncoderA=1;
Timer2500us=6;
while(Timer2500us);
EncoderB=0;
Timer2500us=2;
while(Timer2500us);
EncoderA=0;
Timer2500us=6;
while(Timer2500us);
EncoderB=1;
Timer2500us=2;
while(Timer2500us);
EncoderA=1;
Timer2500us=6;
while(Timer2500us);
EncoderB=0;
Timer2500us=2;
while(Timer2500us);
EncoderA=0;
SendBuffer[0]=0xA3;
SendBuffer[1]=0x30;
Send(2);
break;
case 0x00:
Timer2500us=10;
while(Timer2500us);
EncoderA=1;
Timer2500us=2;
while(Timer2500us);
EncoderB=1;
Timer2500us=6;
while(Timer2500us);
EncoderA=0;
Timer2500us=2;
while(Timer2500us);
EncoderB=0;
Timer2500us=6;
while(Timer2500us);
EncoderA=1;
Timer2500us=2;
while(Timer2500us);
EncoderB=1;
Timer2500us=6;
while(Timer2500us);
EncoderA=0;
Timer2500us=2;
while(Timer2500us);
EncoderB=0;
SendBuffer[0]=0xA3;
SendBuffer[1]=0x30;
Send(2);
break;
default:
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -