📄 yxkey.bak
字号:
/******************************************************************************
* 模块名:YxKey.c
* 功 能:系统主程序部分
* 时 间:2004.4.30
*
******************************************************************************/
/*
V1.0 不带DataPos,潍纺电视台
V2.0 带DataPos
V2.1 成都:实测上电判断已初始化会不准,不再读INI的话,编号有错乱,
所以把startup.asm删除,在systemIni中总readini
V2.1 调整了单键应答命令长度05为06
*/
#include <reg51.h>
#include <intrins.h> /*nop等指令*/
#define KEY15 //
#define uint unsigned int
#define uchar unsigned char
#define NOP _nop_();_nop_();_nop_();_nop_();
sbit a0=ACC^0; /*定义ACC的位,利用ACC操作速度最快*/
sbit a1=ACC^1;
sbit a2=ACC^2;
sbit a3=ACC^3;
sbit a4=ACC^4;
sbit a5=ACC^5;
sbit a6=ACC^6;
sbit a7=ACC^7;
/*变量定义*/
sbit K0 =P1^0;
sbit K1 =P1^1;
sbit K2 =P1^2;
sbit K3 =P1^3;
sbit K4 =P1^4;
sbit K5 =P1^5;
sbit K6 =P1^6;
sbit K7 =P1^7;
sbit TR =P3^3;
sbit SCL =P3^4;
sbit SDA =P3^5;
sbit LED =P3^7;
//sbit LED2 =P1^7;
/*常数定义*/
#define C_T0H 0xB8 /*20ms=(65536-x)*12/11.0592 */
#define C_T0L 0x00
#define BANK_SERI 1
#define C_SERMAXN 16 /*串口缓冲区大小*/
/*收发转换需要2ms*/
#define C_HEADN 0 /*无线发送引导头长度 发送0x55的数目*/
/*不加延时,使用PC机接收 HeadN=60,加2ms延时,并使用无单片机的收发板时,可使用50*/
/*使用10时可以提高无线基站的扫描间隔到50ms,使用20时扫描间隔60ms效果好,但使用50时也60ms,why?*/
#define C_TIMERN 25
#define KK7 7
#define KDOT 10
#define KSPC 11
#define KPRE 12
#define KNEXT 13
#define KOK 14
#define KESC 15
#define KFUNC 16
/*内部数据*/
uchar bdata ICData; /*串行读写数据使用,可位寻址*/
sbit ICDataB0=ICData^0;
sbit ICDataB1=ICData^1;
sbit ICDataB2=ICData^2;
sbit ICDataB3=ICData^3;
sbit ICDataB4=ICData^4;
sbit ICDataB5=ICData^5;
sbit ICDataB6=ICData^6;
sbit ICDataB7=ICData^7;
uchar bdata P1Led;
sbit LED2=P1Led^7;
uchar bdata ICONS;/*液晶图标*/
sbit IconZT=ICONS^7; /*公司标徽*/
sbit IconTX=ICONS^4;
sbit IconRX=ICONS^6;
sbit IconSETUP=ICONS^0; /*设置*/
sbit IconCOL =ICONS^1;
sbit IconBATT =ICONS^2; /*弱电*/
uchar bdata Config1,Config2,Config3;
sbit bOneKey =Config1^0;/*功能限定:单按键输入*/
uchar data SerData[C_SERMAXN] ;/*串口数据区*/
uchar data SerN,SerHeadN,SerBufN;
bit bRcvOk,bSendOk;
bit bTimer,bKeyOk,bDot,bEnter,bKeyScan,bSetup,bFlash;
uchar data TimerN,PwrT,TimerTR,KonT;
uchar data AddL,AddH,SysMode;
uchar data KeyNo,InputN,IniPos;
uchar data InitOkNum,InitOkNum2;
unsigned int data TimerA,PwrTimer;
/*最后按键计时,延时关机计时,上电初始化标志*/
uchar data LcdBuf[6];/*液晶显示*/
uchar data KeyBuf[3];/*按键序列*/
uchar data IcBuf[6];/*EEPROM数据区*/
bit bAck; /*EEPROM中的应答标志*/
uchar data DataPos;
void SystemIni();
void ReadCmd();
void TstSend();
void TimerFunc();
void KeyScan();
void FuncInput();
void FuncSetup();
void PushSendBuf(uchar);
void StartSendBuf();
void Stop24();
bit WrBytes24(unsigned int,unsigned char);
bit RdBytes24(unsigned int,unsigned char);
void DelayMs(uchar);
void InputClr();
/*主程序开始*/
main()
{
SystemIni(); /*系统初始化*/
//while(1) {LED=0;LED2=0;}; //Test Current
while(1)
{
if (bRcvOk) ReadCmd();
if (bTimer) TimerFunc();
if (bKeyScan) KeyScan();
switch (SysMode)
{ case 0:
FuncInput();
break;
default:
SysMode=0;
break;
}
PCON=PCON|0x01;//IDLE模式,减少耗电
}
}
uchar LeftShift4(uchar *Source,uchar inData)/*左移4位入*/
{ uchar i;
i=*Source>>4;
*Source=(*Source<<4)|(inData & 0x0f);
return i;
}
void KeyInBuf(uchar Key)
{ uchar iCode;
iCode=LeftShift4(&KeyBuf[2],Key);
iCode=LeftShift4(&KeyBuf[1],iCode);
iCode=LeftShift4(&KeyBuf[0],iCode);
}
/*正常键盘输入*/
void FuncInput()
{ register uchar i;
if (!bKeyOk) return;
bKeyOk=0;
//LED=~LED;
TimerA=0;/*重新计时*/
KeyInBuf(KeyNo);//to按键序列
switch (KeyNo)
{
case KDOT: //dot
if (bDot) return;
bDot=1;
if (InputN==0)
{ LcdBuf[5]=0; InputN++; }
LcdBuf[5]=LcdBuf[5]|0x80;
break;
//case 11: //space
// break;
case KPRE:
case KNEXT:
if (bEnter==1) return;
if (LcdBuf[5]>0x7f) bDot=0;
for (i=0;i<5;i++) LcdBuf[5-i]=LcdBuf[4-i];
LcdBuf[0]=0x0f;
if (InputN>0) InputN--;
break;
case KOK: //OK
if (InputN>0)
{ bEnter=1;
InputN=0;//后继重新输入
bDot=0;
}
return;
case KESC: //ESC
case KFUNC: //FUNC
InputClr();
break;
default: /*数字键*/
if (InputN>5) InputN=0;//后继重新输入
for (i=0;i<5;i++) LcdBuf[i]=LcdBuf[i+1];
LcdBuf[5]=KeyNo;
InputN++;
}
if (InputN==1)/*开机缺省显示消除*/
{ for (i=0;i<5;i++) LcdBuf[i]=0x0f;
}
}
void WriteIni()
{ IcBuf[0]=0xAA;IcBuf[1]=0x55;
WrBytes24(0,2);
IcBuf[0]=AddH;IcBuf[1]=AddL;
IcBuf[2]=PwrT;IcBuf[3]=Config1;
IcBuf[4]=Config2;IcBuf[5]=Config3;
WrBytes24( 2,6);
}
void ReadIni()
{ uchar i;
Stop24();
for (i=0;i<6;i++)
{
RdBytes24(0,2);
if ((IcBuf[0]==0xAA) && (IcBuf[1]==0x55)) i=7;
DelayMs(10);
}
if ((IcBuf[0]!=0xAA) | (IcBuf[1]!=0x55))
{
AddH=99;AddL=99;//9999
//AddH=0;AddL=1;//1
PwrT=2;
Config1=0;Config2=0;Config3=0;
//WriteIni();//不改写
}
else
{ RdBytes24(2,6);
AddH=IcBuf[0];AddL=IcBuf[1];
PwrT=IcBuf[2];
Config1=IcBuf[3];
Config2=IcBuf[4];
Config3=IcBuf[5];
}
}
void TimerFunc()
{ bTimer=0;
LED2=~LED2;
//SendMoreKey();
}
/*统一的发送按键结果*/
void SendInfo(uchar iPos,uchar iMode)
{ uchar data i,Crc;
if (iPos<0x80)
{
if (iPos!=0)
{
iPos=iPos&0x0f;
if (iPos!=DataPos)
{ //收到不同的DataPos时表示已经启动新的扫描
DataPos=iPos;
InputClr();
//ShowNums();
//for (i=0;i<10;i++) IcBuf[i]=0;//多人1投票器
}
}
}
else
{//读出记录
iPos=iPos&0x0f;
//ReadKey(iPos);
//ShowNums();
bEnter=1;
}
EA=0;SerN=0;TR=1;
PushSendBuf(0xAA);
PushSendBuf(0x55);
PushSendBuf(0);
PushSendBuf(AddH);
PushSendBuf(0);
PushSendBuf(AddL);
switch (iMode)
{
case 0:
SerData[2]=0x0B;
SerData[4]=0x50;
PushSendBuf(02);
PushSendBuf(AddH);
PushSendBuf(AddL );
PushSendBuf(PwrT);
PushSendBuf(Config1);
PushSendBuf(Config2);
PushSendBuf(Config3);
break;
case 1: //多键
SerData[2]=0x0C;
if (bEnter) SerData[4]=0x52;else SerData[4]=0x51;
PushSendBuf(LcdBuf[0]);
PushSendBuf(LcdBuf[1]);
PushSendBuf(LcdBuf[2]);
PushSendBuf(LcdBuf[3]);
PushSendBuf(LcdBuf[4]);
PushSendBuf(LcdBuf[5]);
PushSendBuf(TimerA /256 );
PushSendBuf(TimerA);
break;
case 2://单键
SerData[2]=0x06;
SerData[4]=0x53;
PushSendBuf(LcdBuf[5]);
PushSendBuf(0);
break;
/* case 3://多人投票
SerData[2]=0x0E;
SerData[4]=0x56;
for (i=0;i<10;i++) PushSendBuf(IcBuf[i]);
break;*/
}
Crc=0;
for (i=1;i<SerData[2];i++)
Crc=Crc^SerData[i+2];
PushSendBuf(Crc);
EA=1;
StartSendBuf();
}
void SendIni()
{
SendInfo(0,0);
}
/*处理系统命令*/
void ReadCmd50()
{ //uchar data i;
switch (SerData[6]) /*子命令码*/
{ case 0x1:/*显示编号*/
break;
case 0x2: /*读配置*/
if ((KeyNo!=KOK)&&(KeyNo!=KK7)) break;
SendIni();
break;
case 0x3: /*写配置*/
if ((KeyNo!=KOK)&&(KeyNo!=KK7)) break;
AddH=SerData[7];
AddL=SerData[8];
PwrT=SerData[9];
Config1=SerData[10];
Config2=SerData[11];
Config3=SerData[12];
WriteIni();
ReadIni();
SendIni();
break;
case 0x4: /*延时关机*/
//PwrTimer=SerData[7]*256 + SerData[8];
break;
default: //认为是按模式扫描启动
InputClr();
break;
}
//Beep();
}
/*解读串口命令*/
void ReadCmd()
{ register uchar i,Crc;
Crc=0;
for (i=0;i<SerN-4;i++) Crc=Crc^SerData[i+3]; /*计算CRC,Len后Crc前的XOR值*/
if(Crc!=SerData[SerN-1]) /*CRC效验不正确*/
{ goto ReadClear;
}
LED2=~LED2;
P1=P1Led;
if (!((SerData[3]==AddH) && (SerData[5]==AddL)))
if (!((SerData[3]==0)&&(SerData[5]==0)))
goto ReadClear1;/*地址相同或00*/
SerN=0; //!bug 有不发送应答的处理
//所以先清除SerN,否则后继第一条指令丢失
switch (SerData[4]) /*命令码*/
{
case 0x50:
ReadCmd50();
//InputN=6; //按键不能再输入 no 会影响启动扫描命令的InputClr
bRcvOk=0;
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -