📄 编辑1.c
字号:
#include <reg51.h>
#include <intrins.h>
#include <string.h>
#include "Scod.h"
///////////////////////////////////////////////////////////////////
sbit DATA=P3^4; //用p3.3做数据线控制口(小键盘)
sbit CLK =P3^2; //用p3.2做时钟线控制口(小键盘)
sbit Key_Data=P3^5; //定义接受标准键盘引脚控制口(数据线)
sbit Key_CLK=P3^3; //定义接受标准键盘引脚控制口(时钟线,外部中断1)
sbit inhibit=P1^3; //定义专用键盘和标准PS2键盘控制转换(P4.3)
///////////////////////////////////////////////////////////////////
sbit a1 = P1^1; //用p4.1做语音控制口1
sbit a2 = P1^2; //用p4.1做语音控制口2
//////////////////////////////////////////////////////////////////
sbit buzzer = P0^1; //用p0.1做蜂鸣器控制口
//////////////////////////////////////////////////////////////////
sbit atxtflag = P1^0; //用p4.0做AT/XT控制口(拨码开关)
sbit bit1_6flag = P3^6; //用p3.6做1bit/6bit清除控制口(拨码开关)
sbit numberflag = P3^7; //用p3.7做液晶显示数字和*号控制口(拨码开关)
//////////////////////液晶控制位及数据接口/////////////////////////
sbit LCM_RS=P2^5;
sbit LCM_RW=P2^6;//定义LCD引脚
sbit LCM_E =P2^7;
#define LCM_Data P0
sbit Busy = P0^7; //用于检测LCM状态字中的Busy标识
//#define Busy 0x80 //用于检测LCD状态字中的Busy标识
///////////////////////////////////////////////////////////////////
#define uchar unsigned char
#define uint unsigned int
///////////////////////////////////////////////////////////////////
////////////////////////////键盘扫描定义///////////////////////////
sbit line1 P2^0;
sbit line2 P2^1;
sbit line3 P2^2;
sbit line4 P2^3;
sbit line5 P2^4; //定义列线
sbit hang1 P1^0;
sbit hang2 P1^1;
sbit hang3 P1^2;
sbit hang4 P1^3;
sbit hang5 P1^4;
sbit hang6 P1^5;
sbit hang7 P1^6;
sbit hang8 P1^7; //定义行线
unsigned char keyvartab[8][5]={'A','B','C','D','E',
'F','G','H','I','J',
'K','L','M','N','O',
'P','Q','R','S','T',
'1','2','3','U','V',
'4','5','6','W','X',
'7','8','9',' ',' ',
'~','0','!','Y','Z'
};
////////////////////////////////////////////////////////////////////
void LCMInit(void);
unsigned char ReadStatusLCM(void);
void WriteDataLCM(unsigned char WDLCM);
void WriteCommandLCM(unsigned char WCLCM,BuysC);
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
void Delay5Ms(void);
void Delay400Ms(void);
void delay(unsigned int N);
/////////////////////////////////////////////////////////////////////
void Decode(unsigned char ScanCode);
/////////////////////////////////////////////////////////////////////
void numbertocode(void);
void initkeyvariable(void);
unsigned char readkeyvar(void);
unsigned char parity(unsigned char x);
void SEND_byte(unsigned char byte_data);
/////////////////////////////////////////////////////////////////////
unsigned char code cdle_net[] = {" WELCOME! "};
unsigned char code email[] = {"we do our best!"}; //字符以ASCII码存储,不需要转换
unsigned char code Cls[] = {" "}; //清显示
/////////////////////////////////////////////////////////////////////
static unsigned char IntNum = 0; //中断次数计数
static unsigned char KeyV; //键值
static unsigned char DisNum = 0; //显示用指针
static unsigned char Key_UP=0, Ctrl = 0;//Key_UP是键松开标识,Ctrl是Ctrl键按下标识
static unsigned char BF = 0; //标识是否有字符被收到
static unsigned char biaozhiflag = 0;//表示小键盘已经有键按下标志位
/////////////////////////////////////////////////////////////////////
/////////////////////////延时子函数开始//////////////////////////////
//5ms延时函数
void Delay5Ms(void)
{
unsigned int TempCyc =5552;
while(TempCyc--);
}
/////////////////////////////////////////////////////////////////////
//400ms延时函数
void Delay400Ms(void)
{
unsigned char TempCycA = 5;
unsigned int TempCycB;
while(TempCycA--)
{
TempCycB=7269;
while(TempCycB--);
};
}
// 函数功能:延时子程序,实现(16*N+24)us的延时
// 系统采用11.0592MHz的时钟时,延时满足要求,其它情况需要改动
void delay(unsigned int N)
{
int i;
for(i=0;i<N;i++);
}
/////////////////////////延时子函数结束//////////////////////////////
/////////////////////////////////////////////////////////////////////
//////////////////////////1602-LCD驱动程序开始///////////////////////
//写数据函数
void WriteDataLCM(unsigned char WDLCM)
{
ReadStatusLCM(); //检测忙
LCM_Data = (WDLCM&0xf0)|(P0&0x0f);
//LCM_Data = WDLCM;
LCM_RS = 1;
LCM_RW = 0;
LCM_E = 1; //若晶振速度太高可以在这后加小的延时
LCM_E = 0; //延时
LCM_E = 0;
LCM_Data = ((WDLCM<<4)&0xf0)|(P0&0x0f);
LCM_RS = 1;
LCM_RW = 0;
LCM_E = 1; //若晶振速度太高可以在这后加小的延时
LCM_E = 0; //延时
LCM_E = 0;
}
/////////////////////////////////////////////////////////////////////
//写指令函数
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
{
if (BuysC) ReadStatusLCM(); //根据需要检测忙
LCM_Data = (WDLCM&0xf0)|(P0&0x0f);
//LCM_Data = WCLCM;
LCM_RS = 0;
LCM_RW = 0;
LCM_E = 1;
LCM_E = 0;
LCM_E = 0;
LCM_Data = ((WDLCM<<4)&0xf0)|(P0&0x0f);
LCM_RS = 0;
LCM_RW = 0;
LCM_E = 1; //若晶振速度太高可以在这后加小的延时
LCM_E = 0; //延时
LCM_E = 0;
}
/////////////////////////////////////////////////////////////////////
//读状态函数
unsigned char ReadStatusLCM(void)
{
Busy = 1;
//LCM_Data = 0xF0;
LCM_RS = 0;
LCM_RW = 1;
LCM_E = 1;
LCM_E = 0;
LCM_E = 0;
while (Busy & 0x01); //检测忙信号
//while (LCM_Data & Busy); //检测忙信号
return(Busy);
}
/////////////////////////////////////////////////////////////////////
//初始化函数
void LCMInit(void) //LCM初始化
{
LCM_Data = 0xff;
Delay5Ms();
WriteCommandLCM(0x30,0); //三次显示模式设置,不检测忙信号
Delay5Ms();
WriteCommandLCM(0x30,0);
Delay5Ms();
WriteCommandLCM(0x30,0);
Delay5Ms();
WriteCommandLCM(0x02,0);
Delay5Ms();
WriteCommandLCM(0x28,0); //三次显示模式设置,不检测忙信号
Delay5Ms();
WriteCommandLCM(0x28,0);
Delay5Ms();
WriteCommandLCM(0x28,0);
Delay5Ms();
WriteCommandLCM(0x28,1); //显示模式设置,开始要求每次检测忙信号
//WriteCommandLCM(0x08,1); //关闭显示
WriteCommandLCM(0x0C,1); //关闭显示
WriteCommandLCM(0x01,1); //显示清屏
WriteCommandLCM(0x06,1); // 显示光标移动设置
WriteCommandLCM(0x0F,1); // 显示开及光标设置
}
/////////////////////////////////////////////////////////////////////
//按指定位置显示一个字符函数
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
X |= 0x80; //算出指令码
WriteCommandLCM(X, 1); //发命令字
WriteDataLCM(DData); //发数据
}
/////////////////////////////////////////////////////////////////////
//按指定位置显示一串字符函数
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
unsigned char ListLength;
ListLength = 0;
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
while (DData[ListLength]!= '\0') //若到达字串尾则退出, zhao-(所以的字符码都大于(>0X19),字符串末为00,停止显示)
{
if (X <= 0xF) //X坐标应小于0xF
{
DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
ListLength++;
X++;
}
}
}
//////////////////////////1602-LCD驱动程序结束///////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////接收大键盘命令开始//////////////////////////////
//接收标准键盘扫描码命令函数
void Keyboard_out(void) interrupt 2
{
if ((IntNum > 0) && (IntNum < 9))
{
KeyV = KeyV >> 1; //因键盘数据是低>>高,结合上一句所以右移一位
if (Key_Data) KeyV = KeyV | 0x80; //当键盘数据线为1时为1到最高位
}
IntNum++;
while (!Key_CLK); //等待PS/2CLK拉高
if (IntNum > 10)
{
IntNum = 0; //当中断11次后表示一帧数据收完,清变量准备下一次接收
BF = 1; //标识有字符输入完了
EA = 0; //关中断等显示完后再开中断 (注:如这里不用BF和关中断直接调Decode()则所Decode中所调用的所有函数要声明为再入函数)
}
}
/////////////////////////////////////////////////////////////////////
//解码扫描码函数
void Decode(unsigned char ScanCode) //注意:如SHIFT+G为12H 34H F0H 34H F0H 12H,也就是说shift的通码+G的通码+shift的断码+G的断码
{
unsigned char TempCyc,i,j;//secondrow_0bit_error,在移行时,第一行的第一位在第一次移行正确,以后总是不变(错误)
unsigned char secondrow_buf[16];
if (!Key_UP) //当键盘松开时,zhao- (key_UP,shift,IntNum,DisNum,BF初值为0)
{
switch (ScanCode)
{
case 0xF0 : // 当收到0xF0,Key_UP置1表示断码开始
Key_UP = 1;
break;
if(atxtflag==1)
{
case 0x14 : // ATCtrl
Ctrl = 1;
}
else
{
case 0x1D : // XTCtrl
Ctrl = 2;
}
break;
default:
if(!Ctrl) //如果Ctrl没按下
{
if(atxtflag==1)
{
//for (TempCyc = 0;(ATunshift[TempCyc][0]!=ScanCode)&&(TempCyc<48); TempCyc++); //查表显示
//UnShifted[TempCyc][0], 键值表,对应的显示字符,UnShifted[TempCyc][1]
// if(ATunshift[TempCyc][0] == ScanCode)
// {
if((ScanCode==0x01)||(ScanCode==0x09))
{
a1 = 1;
a1 = 0;
buzzer = 1;
Delay5Ms();
buzzer = 0;
Delay5Ms();
buzzer = 1;
Delay5Ms();
buzzer = 0;
Delay5Ms();
}
else if((ScanCode==0x78)||(ScanCode==0x07))
{
a2 = 1;
a2 = 0;
buzzer = 1;
Delay5Ms();
buzzer = 0;
Delay5Ms();
buzzer = 1;
Delay5Ms();
buzzer = 0;
Delay5Ms();
}
// }//结束if(ATunshift[TempCyc][0] == ScanCode)
}//结束if(atxtflag==1)
else
{
//for (TempCyc = 0;(XTunshift[TempCyc][0]!=ScanCode)&&(TempCyc<48); TempCyc++); //查表显示
//UnShifted[TempCyc][0], 键值表,对应的显示字符,UnShifted[TempCyc][1]
//if(XTunshift[TempCyc][0] == ScanCode)
//{
if((ScanCode==0x43)||(ScanCode==0x44))
{
a1 = 1;
a1 = 0;
buzzer = 1;
Delay5Ms();
buzzer = 0;
Delay5Ms();
buzzer = 1;
Delay5Ms();
buzzer = 0;
Delay5Ms();
}
else if((ScanCode==0x57)||(ScanCode==0x58))
{
a2 = 1;
a2 = 0;
buzzer = 1;
Delay5Ms();
buzzer = 0;
Delay5Ms();
buzzer = 1;
Delay5Ms();
buzzer = 0;
Delay5Ms();
}
//} //结束 if(XTunshift[TempCyc][0] == ScanCode)
} //结束if(atxtflag==0)
} //结束if(!Ctrl)
else //按下Ctrl
{
if(Ctrl == 1)
{
//for (TempCyc = 0;(ATaddshift[TempCyc][0]!=ScanCode)&&(TempCyc<6); TempCyc++); //查表显示
//UnShifted[TempCyc][0], 键值表,对应的显示字符,UnShifted[TempCyc][1]
// if(ATaddshift[TempCyc][0] == ScanCode)
// {
if((ScanCode==0x79)||(ScanCode==0x55)||(ScanCode==0x12))
{
a1 = 1;
a1 = 0;
buzzer = 1;
Delay5Ms();
buzzer = 0;
Delay5Ms();
buzzer = 1;
Delay5Ms();
buzzer = 0;
Delay5Ms();
}
else if((ScanCode==0x7B)||(ScanCode==0x4E||(ScanCode==0x59)))
{
a2 = 1;
a2 = 0;
buzzer = 1;
Delay5Ms();
buzzer = 0;
Delay5Ms();
buzzer = 1;
Delay5Ms();
buzzer = 0;
Delay5Ms();
}
// } //结束if(ATaddshift[TempCyc][0] == ScanCode)
} //结束if(Ctrl == 1)
else if(Ctrl == 2)
{
//for (TempCyc = 0;(XTaddshift[TempCyc][0]!=ScanCode)&&(TempCyc<6); TempCyc++); //查表显示
//UnShifted[TempCyc][0], 键值表,对应的显示字符,UnShifted[TempCyc][1]
//if(XTaddshift[TempCyc][0] == ScanCode)
// {
if((ScanCode==0x4E)||(ScanCode==0x0D)||(ScanCode==0x2A))
{
a1 = 1;
a1 = 0;
buzzer = 1;
Delay5Ms();
buzzer = 0;
Delay5Ms();
buzzer = 1;
Delay5Ms();
buzzer = 0;
Delay5Ms();
}
else if((ScanCode==0x4A)||(ScanCode==0x0C)||(ScanCode==0x36))
{
a2 = 1;
a2 = 0;
buzzer = 1;
Delay5Ms();
buzzer = 0;
Delay5Ms();
buzzer = 1;
Delay5Ms();
buzzer = 0;
Delay5Ms();
}
// }//结束if(XTaddshift[TempCyc][0] == ScanCode)
} //结束if(Ctrl == 2)
} ////结束Ctrl按下
break;
} //结束switch (ScanCode)
biaozhiflag = 1;
} //结束if (!Key_UP)
else
{
Key_UP = 0;
switch (ScanCode) //当键松开时不处理判码
{
case 0x14 : // ATCTRL编码
Ctrl = 0;
break;
case 0x1D : // XTCTRL编码
Ctrl = 0;
break;
}
}
BF = 0; //标识字符处理完了
}
/////////////////////////接收大键盘命令处理完成//////////////////////
/////////////////////////////////////////////////////////////////////
// 函数名称: CAL_jiaoyan
// 函数功能: 计算校验位
//bit CAL_jiaoyan(unsigned char byte_data)
//{
//}
/////////////////////////////////////////////////////////////////////
//////////////////////////小键盘扫描驱动程序开始/////////////////////
//计算校验函数
unsigned char parity(unsigned char x)
{
x^=x;
if(P)return(1);
else return(0);
}
/*unsigned char parity2(unsigned int x){
#pragma asm
mov a,r7
xrl ar6,a
#pragma endasm
if(P)return(1);
else return(0);
}*/
/////////////////////////////////////////////////////////////////////
//发送小键盘一个字节数据函数
void SEND_byte(unsigned char byte_data)
{
unsigned char i,temp;
if(CLK==0) //时钟线为低
temp=byte_data;
CLK=1;
DATA=0;
delay(0);
CLK=0; //发送起始位
for(i=0;i<8;i++)
{
delay(0);
CLK=1;
DATA=(temp&0x01); //发送数据
byte_data=byte_data>>1;
delay(0);
CLK=0;
}
delay(0);
CLK=1;
DATA=parity(temp); //发送校验位
delay(0);
CLK=0;
delay(0);
CLK=1;
DATA=1; //发送结束位
delay(0);
CLK=0;
}
///////////////////////////////////////////////////////////////////////////
//初始化端口函数
void initkeyvariable(void)
{
P1=0x00;
//P1=0xFF;
P2=0x00;
}
//获取键值函数
/*unsigned char readkeyvar(void)
{
unsigned char i,j;
unsigned char x;
unsigned char x1;
unsigned char key_date;
key_date = P1;
x = P2;
key_date &= 0xff;
if(key_date!=0xff)
{
{
if(key_date==0xfe)x1=0;
else if(key_date==0xfd)x1=1;
else if(key_date==0xfb)x1=2;
else if(key_date==0xf7)x1=3;
else if(key_date==0x7f)x1=4;
else if(key_date==0xbf)x1=5;
else if(key_date==0xdf)x1=6;
else if(key_date==0xef)x1=7;
else {return 0x20;}
}
P2 = 0x1f;
x = P2;
x &= 0x1f;
if(x!=0x1f)
{
if(x==0x1e)i=0;
else if(x==0x1d)i=1;
else if(x==0x1b)i=2;
else if(x==0x17)i=3;
else if(x==0x0f)i=4;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -