⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ps2键盘(at45db011).c

📁 键盘针对78键的键盘开发的针对PS2的程序
💻 C
📖 第 1 页 / 共 5 页
字号:
//这是专为黄启光设计的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 + -