📄 ps2键盘(at45db011).c
字号:
//这是专为黄启光设计的PS2键盘称序
//MCU使用STC12C51 PLCC封装
//时钟=18.432MHZ
//设计师: 杨本雄
//联系电话:26735990 13602675760
//email: postmaster@sunsonsea.net
//公司名称: 深圳市雄洋电子科技有限公司
//编制时间 2007年09月17日 修改时间: 2009年09月19日
//*************************************************************************
//编程说明:
//系统工作模式
//键盘定义左上角键值=00(LOCK_9AND_KB2_6,KB1_1),右下角键值=65(LOCK_4AND_KB2_1,KB1_11)
//键盘特点:1. Caps Lock、Scroll Lock、Num Lock相当于状态选择请求键,其状态是记忆在PC端的,计算机启动或单击
// 这3个键时才把状态下发到键盘
// 2. 如果是在大写状态,单击a~z是大写,而shift+(a~z)会变成小写
// 如果是在小写状态,单击a~z是小写,而shift+(a~z)会变成大写
// 3. 对于上下可选键,通过shift选择,要是这个键不发断码,下一个选择将继续起作用。
//****************************************************
//修改说明
//****************************************************
//烧录说明:
//选择6T模式
//0xe8 --> 0xe4
//0xe7 --> 0xe3
//****************************************************
//寄存器定义
//#include <STDIO.H>
#include <intrins.h>
#include <STC89C51.H>
#include "PS2KeyScanCoded2.h"
//MCU管脚定义
//P0口初始化 P0=0xff
sbit LOCK_9AND_KB2_1 = P0^0; //第1行键 reset=1
sbit LOCK_8AND_KB2_2 = P0^1; //第2行键 reset=1
sbit LOCK_7AND_KB2_3 = P0^2; //第3行键 reset=1
sbit LOCK_6AND_KB2_4 = P0^3; //第4行键 reset=1
sbit LOCK_5AND_KB2_5 = P0^4; //第5行键 reset=1
sbit LOCK_4AND_KB2_6 = P0^5; //第6行键 reset=1
sbit LOCK_3 = P0^6; //? reset=1
sbit LOCK_2 = P0^7; //? reset=1
//P1口初始化 P1=0xff
sbit KB1_5 = P1^0; //第5列键 reset=1
sbit KB1_4 = P1^1; //第4列键 reset=1
sbit KB1_3 = P1^2; //第3列键 reset=1
sbit KB1_2 = P1^3; //第2列键 reset=1
sbit KB1_1 = P1^4; //第1列键 reset=1
sbit BUZZ = P1^5; //蜂鸣器输出 reset=1
sbit LED26 = P1^6; //D26 LED指示灯输出 reset=1
sbit LED25 = P1^7; //D25 LED指示灯输出 reset=1
//P2口初始化 P2=0xff
sbit KB1_13 = P2^0; //第6行键 reset=1
sbit KB1_12 = P2^1; //第6行键 reset=1
sbit KB1_11 = P2^2; //第6行键 reset=1
sbit KB1_10 = P2^3; //第6行键 reset=1
sbit KB1_9 = P2^4; //第6行键 reset=1
sbit KB1_8 = P2^5; //第6行键 reset=1
sbit KB1_7 = P2^6; //第6行键 reset=1
sbit KB1_6 = P2^7; //第7行键 reset=1
//P3口初始化 P3=0x67
sbit PS2_RXD = P3^0; //Pin=5(L7) 串口接收 reset=1
sbit PS2_TXD = P3^1; //Pin=7(L8) 串口发送 reset=1
sbit SPI45DB041_SO = P3^2; //Flash的SO reset=1
sbit SPI45DB041_SI = P3^3; //Flash的SI reset=0
sbit SPI45DB041_SCK = P3^4; //Flash的SCLK reset=0
sbit SPI45DB041_RST = P3^5; //Flash的RST reset=1
sbit SPI45DB041_CS = P3^6; //Flash的CS reset=1
sbit MCR_SCLK = P3^7; //MCR接口的SCLK reset=0
//P4口初始化 P4=0xff
sbit LOCK_1 = P4^0; // reset=1
sbit LKB_SDA = P4^1; //Pin=28(L3) 大键盘数据线
sbit MCR_SDA = P4^2; // MCR接口的SDA
sbit LKB_SCLK = P4^3; //Pin=6(L4) 大键盘时钟线
//=======================================================================================
bit Buzz_Rs232_Flag; //
bit Keycoded_Table; //按键重定义下载标识;0=已下载
bit Nop_Key_Flag; // 0= 空键标识
//========================================================================================
unsigned char bdata System_Status_Reg; //系统状态控制字
//其中:
sbit Tr1_Enable=System_Status_Reg^7; // bit7=1 Tr1_Enable 磁轨1数据使能
sbit Beep_Nop_Key=System_Status_Reg^6; // bit6=1 Beep_Nop_Key 空键发声允许
sbit Send_Break_Code=System_Status_Reg^5; // bit5=1 Send_Break_Code 允许发送断码
sbit Beep_Enable=System_Status_Reg^4; // bit4=1 Beep_Enable 按键发声允许
sbit Tr3_Enable=System_Status_Reg^3; // bit3=1 Tr3_Enable 磁轨3数据使能
sbit Tr2_Enable=System_Status_Reg^2; // bit2=1 Tr2_Enable 磁轨2数据使能
sbit Send_Enter=System_Status_Reg^1; // bit1=1 Send_Enter 每道磁轨数据发送结束后允许发送回车符
sbit Send_Format_Code=System_Status_Reg^0; // bit0=1 Send_Format_Code 允许刷卡数据的首尾符格式化
//=====================================================================================================
unsigned char bdata Caps_Scroll_Num_Status; //当前PC状态
//其中:
sbit CapsLock=Caps_Scroll_Num_Status^2; //CapsLock状态
sbit ScrollLock=Caps_Scroll_Num_Status^1; //ScrollLock状态
sbit NumLock=Caps_Scroll_Num_Status^0; //NumLock状态
//=====================================================================================================
unsigned int bdata Ms_Timer;
unsigned char bdata Lock_Lum; //锁匙状态
unsigned int bdata Buzz_Timer; //蜂鸣器响停定时器
unsigned int bdata gWait_Process_Timer;
unsigned char data Last_Send_To_Ps2_Word; //上一次发送到PS2口的字节(以备收到0xFE时重发)
unsigned char data Send_1Byte_To_PS2_Timer; //发送字节到PC的间隙定时器
unsigned char data Pro_Key_Step; //处理键盘的步骤
//0 = 扫描键盘
//1 = 处理判断
//2 = 第3键单击、释放的的处理
//3 = 第2键单击、释放的的处理
//4 = 第1键单击、释放的的处理
unsigned char data Code_Reci_Data_Timing; //限时读PS2口
unsigned char data S_Timing; //秒定时器
/*
CAPSLOCK_LED; //0x04 1=CapsLock亮
NUMLOCK_LED; //0x02 1=NumLock亮
SCROLLLOCK_LED; //0x01 1=ScrolLock亮
*/
//使用Flash 的Buffer作为发送缓冲区
unsigned char data Key_Reciver_Buffer; //
unsigned int data Key_Send_Buffer_Point=0; //键盘发送数据缓冲区指针,指向将要发送的字节
unsigned int data Key_Send_Buffer_PlacPoint=0; //键盘发送数据缓冲区放数指针
unsigned char data First_Key_Number[3]; //第1次按下的键
unsigned char data Second_Key_Number[3]; //第2次按下的键
unsigned char data Third_Key_Number[3]; //第3次按下的键
unsigned char idata TEMP_DATA[124]; //处理临时数据
//串口仿真相关变量
unsigned char xdata Key_Scan_Row[13]; //扫描键盘从P0口读到的列值
unsigned int xdata Send_RS_Data; //模拟串口输出移位寄存器(临时)
unsigned char xdata Send_RS_Bit_Num; //模拟串口输出移位计数器(临时)
unsigned char xdata READER_1LENGTH; //1轨长度(8BIT长度,包括引导码)
unsigned char xdata READER_2LENGTH; //2轨长度(8BIT长度,包括引导码)
unsigned char xdata READER_3LENGTH; //3轨长度(8BIT长度,包括引导码)
unsigned char xdata READER_1BUF[76]; //1轨数据
unsigned char xdata READER_2BUF[76]; //2轨数据
unsigned char xdata READER_3BUF[76]; //3轨数据
void myasm(void);
void ScanKey(void);
void Process_Key(void);
void Process_BreakCode(unsigned char KeyNumber); //断码的处理
void Process_MakeCode(unsigned char KeyNumber); //通码的处理
void Find_OnKey_Position(unsigned char Key_SWitch);
void Find_OffKey_Position(unsigned char Key_SWitch);
unsigned char Load_TKey_Define(unsigned char Key_Num);
void Ini_KeyBoard(void);
void Read_Lock(void);
bit Check_PC_Cancle_Send(void);
void Drived_Buzz(unsigned int HLen);
bit Read_PS2_Port(void); //从PS2口读一个字节
bit TRead_PS2_Port(unsigned char RDPS2Time); //限时从PS2口读一个字节
//void Shift_Store_Data(unsigned char *StoreAddr,unsigned char StoreData);
bit Send_1Byte_To_PS2_Port(unsigned char SendData); //往PS2口发送一个字节数据,发送成功返回“1”
void Send_1Bit_To_PS2_Port(unsigned char Send_Bit); //往PS2口发送一个bit
void DelayTime(unsigned int DelayVolu); //任意定时函数
void Delay_uS_Time(unsigned char Delay_Time); //定时40uS函数
//下载处理函数
void RD_PRO_ea_Frame(void);
void RD_PRO_eb_Frame(void);
bit Reciver_Data_Check(unsigned char CMDMode);
void Send_Recode_To_Ps2(void);
//大键盘处理函数
bit Send_LKB_Data(unsigned char DataofSend); //发送成功返回“1”
unsigned char Read_LKB_Data(unsigned char RDTime);
bit Wait_LKB_Sclk_H_To_L(void);
bit Wait_LKB_Sclk_L_To_H(void);
//磁卡解码和处理函数
void Read_MegaCARD(void); //读磁卡头函数
bit FindStartSign_Decode(unsigned char *Array,unsigned char *Temp_Array,unsigned char length,unsigned char BIT_7_5,unsigned char Direction,unsigned char READER,unsigned char READER_NUM);
unsigned char XOR_STR1_STR2(unsigned char *Array,unsigned char length,unsigned char leng); //异或数组
void Pretreatment(unsigned char *Array1,unsigned char *Array2,unsigned char length); //数组倒序
void Process_nCard (void);
bit Get_NByte_MCR_Data(unsigned char NByte,unsigned char *STore_Addr);
void Tr1_Recoded_OK_Prog(unsigned char Reader_End);
void Recoded_OK_Prog(unsigned char Reader_End,unsigned char TraceNum);
//有关Flash的操作函数
void SPI45D041_WriteBits(unsigned int byte,unsigned char num_of_bits);
unsigned char SPI45D041_ReadByte(void);
void ReadOnePageToBuffer(unsigned int PageAddress);
unsigned char ReadByteFromBuffer(unsigned int ByteAddress);
unsigned char ReadNextFromBuffer(void);
void WriteOneByteToBuffer(unsigned int ByteAddress,unsigned char WriteOneByte );
void WriteNextByteToBuffer(unsigned char WriteNextOne);
void WriteClearAllBuffer(void);
void WriteBufferToPageWithErase(unsigned int PageAddress);
//锁状态表
unsigned char code LOCK_VOL[] = {0xfd,0xfe,0x7f,0xbf,0xdf,0xef,0xf7,0xfb};
//void Emluator_RS232(unsigned char SendData);
void main(void)
{
unsigned char i;
unsigned char k;
EA=0;
WDT_CONTR=0x37; //开看门狗
//Bit5 = EN_WDI=1 --看门狗启用
//Bit4 = CLR_WDI=1 --看门狗重新计数
//Bit3 = IDLE_WDI=0 --看门狗“空闲模式”不计数
//Bit2 = PS2=1 --看门狗分频位
//Bit1 = PS1=1 --看门狗分频位
//Bit0 = PS0=1 --看门狗分频位
//本机看门狗定时 T= (6x256x32768)/18432000=2.73秒
//===================================================================================
//初始化各端口,因为复位后端口为0xff,所以,凡是要求为0xff的都不必设置
//d=0xff;
//P1=0xff;
//P2=0xff;
P3=0x67;
//P4=0xff;
//===================================================================================
//SP=SP_POINT;
PCON=0x00; //PCON地址=87H
//SMOD=PCON.7=1,串口波特率加倍
//SMOD0=PCON.6=1
//LVDF=PCON.5=1
//POF=PCON.4=1
//GF1=PCON.3=1
//GF0=PCON.2=1
//PD=PCON.1=1,进入掉电模式,即POWER DOWN
//IDL=PCON.0=1,进入休眠模式,IDL
PSW=0x00;
TCON=0x05; //外部中断都使用下降沿触发方式,但本程序没用到
TMOD=0x11; //T0、T1都为16位定时器
SCON=0x50; //
TH0=0xfc; //T0定时器基本定时=100mS
TL0=0x65; //实际调试值,勿更改!!!!
//时钟=4MHz时
/*
MOV TL1,#0F3H //设置波特率=9600
MOV TH1,#0F3H //
*/
//时钟=4.9152MHz时
/*
MOV TL1,#0F0H //设置波特率=9600
MOV TH1,#0F0H //
*/
//时钟=18.432MHz时
///*
TL1=0xfe; //设置定时=104uS
TH1=0xc0; //
//*/
//TL1=0xee; //设置定时20uS
//TH1=0xee; //
//P1M0=0x00; //将P1口设置普通I/O模式
//P1M1=0x00;
//P3M0=0x00; //将P3口设置为普通51准双向口
//P3M1=0x00;
AUXR=0x01; //T0x12=AUXR.7=1,定时T0输入时钟不12分频
//T1x12=AUXR.6=1,定时T1输入时钟不12分频
//UART_M0x6=AUXR.5=1,串口速度加倍
//EADCI=AUXR.4=1,允许A/D中断
//ESPI=AUXR.3=1,允许SPI中断
//ELVDI=AUXR.2=1,允许低压中断
//
//ALEOFF=AUXR.0=1,关闭ALE
//*********工作暂存器初始化*******************
//********************************************
//*
IP=0x10; //串口中断级别最高
IPH=0x10; //
//*/
/*
IP=0x02; //T1中断级别最高
IPH=0x02; //
*/
IE=0x8a; //EA=IE.7=1,开总中断
//ET2=IE.5=0,禁止定时器2溢出或捕获中断
//ES=IE.4=1,允许串行口中断
//ET1=IE.3=0,禁止T1定时中断,用作波特率发生器
//EX1=IE.2=0,禁止外部中断1
//ET0=IE.1=1,允许T0定时中断
//EX0=IE.0=0,禁止外部中断0
REN=0; //由于已将RXD,TXD改为PS2,所以关闭串口功能
//*********初始化定时器T0**********************
Send_1Byte_To_PS2_Timer=0;
Ms_Timer=0;
S_Timing=0;
TR0=1;
//*********初始化定时器T1**********************
TR1=0; //
LOCK_1=0;
//Lock_Lum=0xff;
Lock_Lum=P0;
LOCK_1=1;
Caps_Scroll_Num_Status=0;
WriteClearAllBuffer();
Key_Send_Buffer_Point=0; //指向发送缓冲区首地址
Key_Send_Buffer_PlacPoint=0;
SPI45DB041_RST=0;
for(i=0;i<13;i++)
{
WDT_CONTR=0x37;
Key_Scan_Row[i]=0xff; //此过程中顺便复位
}
SPI45DB041_RST=1;
for(i=0;i<3;i++)
{
First_Key_Number[i]=0xff; //第1次按下的键
Second_Key_Number[i]=0xff; //第2次按下的键
Third_Key_Number[i]=0xff; //第3次按下的键
}
Ini_KeyBoard();
WDT_CONTR=0x37;
Drived_Buzz(1000);
while(PS2_TXD==0) {WDT_CONTR=0x37;}
while(PS2_RXD==0) {WDT_CONTR=0x37;}
while(LKB_SDA==0) {WDT_CONTR=0x37;}
while(LKB_SCLK==0) {WDT_CONTR=0x37;}
Pro_Key_Step=0;
Send_LKB_Data(0xff);
//#pragma ASM
// nop
//#pragma ENDASM
myasm();
//S_Timing=0;
//while(S_Timing<10) {}
//while(Send_1Byte_To_PS2_Port(0xaa)==0) {}
/*
ReadOnePageToBuffer(SYSTEM_PARA_PAGE_FLASH);
WriteOneByteToBuffer(SYSYTEM_STATUS_BYTE,0x23);
SPI45DB041_CS=1;
WriteBufferToPageWithErase(255);
WriteClearAllBuffer();
Emluator_RS232(ReadByteFromBuffer(SYSYTEM_STATUS_BYTE));
SPI45DB041_CS=1;
ReadOnePageToBuffer(255);
Emluator_RS232(ReadByteFromBuffer(SYSYTEM_STATUS_BYTE));
SPI45DB041_CS=1;
*/
//====================以下测试模拟波特率====================================
/*
while(1)
{
Emluator_RS232(0xaa);Emluator_RS232(0x37);
}
*/
//====================以下测试模拟波特率====================================
//====================以下测试锁的各挡状态====================================
/*
LOCK_1=0;
while(1)
{
Read_Lock(); WDT_CONTR=0x37;
}
*/
//====================以上测试锁的各挡状态====================================
//====================以下测试Read_PS2_Port()函数的正确性====================================
/*
while(1)
{
Read_PS2_Port();
}
*/
//====================以上测试Read_PS2_Port()函数的正确性====================================
LKB_SCLK=0;
//====================以下测试Send_1Byte_To_PS2_Port()函数的正确性====================================
/*
while(1)
{
Send_1Byte_To_PS2_Port(0xaa);
Delay_uS_Time(200);
}
*/
//====================以上测试Send_1Byte_To_PS2_Port()函数的正确性====================================
//====================以下测试Send_LKB_Data()和Read_LKB_Data()函数的正确性====================================
/*
Send_LKB_Data(0xff);
Emluator_RS232(Read_LKB_Data(20));
Send_LKB_Data(0xed);
Emluator_RS232(Read_LKB_Data(20));
Send_LKB_Data(0x02);
Emluator_RS232(Read_LKB_Data(20));
while(1)
{
Emluator_RS232(Read_LKB_Data(20));
}
*/
//====================以上测试Send_LKB_Data()和Read_LKB_Data()函数的正确性====================================
//==================以下测试Send_1Byte_To_PS2_Port()和TRead_PS2_Port()函数的正确性============================
// FF ED 00 ED FF F3 00 ED 00 ED 00 F3 ED F3 ED 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0D 0A
/*
for(i=0;i<30;i++) READER_1BUF[i]=0;
i=0;
S_Timing=0;
while(S_Timing<180)
{
if(Read_PS2_Port()==1)
{
READER_1BUF[i]=Key_Reciver_Buffer;
while(Send_1Byte_To_PS2_Port(0xfa)==0) {}
if(Key_Reciver_Buffer==0xff)
while(Send_1Byte_To_PS2_Port(0xaa)==0) {}
i++;
}
}
//S_Timing=0;
//while(S_Timing<180) {}
for(i=0;i<30;i++) Emluator_RS232(READER_1BUF[i]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -