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

📄 ps2.c.bak

📁 一个以前开发的实际应用的交通灯控制器程序
💻 BAK
字号:
// korfi整理修改 [3/13/2007]
//因为P/2的时钟由设备发出,如果受到干扰将会出现致命错误
//因此,使用中断接收数据,并使用了T2计数器来防止发送、接收出错
//2007-3-24 10:58

#include "PS2.h"

unsigned char KbBuf[KBBUF_SIZE];
unsigned char KbCnt=0;//缓存位置
unsigned char KbFlagSta=0;
	//标记不同状态:无新按键需处理0,新接收数据1,接收延迟错误2
bit KbOverTimeFlag=0;

#define KBBUF_NOKEY 	0
#define KBBUF_GOTKEY	1
#define KBBUF_BREAKKEY	2

unsigned char code KbCode[18]={
	0x77,0x4a,0x7c,0x7b,
	0x6c,0x75,0xrd,
	0x6b,0x73,0x74,0x79,
	0x69,0x72,0x7a,
	0x66,0x70,0x71,0x5a
};

unsigned char GetKey()
{//外部应用接口
	unsigned char xdata i,k;
	if(KbSta==KBBUF_NOKEY)
	{
		for(i=0;i<KBBUF_SIZE;i++)
			if(KbBuf[i]!=0)
			{
				for(k=0;k<18;k++)
					if(KbBuf[i]==KbCode[k])
					{
						KbSta=KBBUF_GOTKEY;
						return KbCode[k];
					}
				KbBuf[i]=0;
			}
	}
	else if(KbSta==KBBUF_GOTKEY)
	{
		for(i=0;i<18;i++)
		if(KbBuf[i]==0xF0)
			KbSta=KBBUF_BREAKKEY;
		KbBuf[i]=0x00;
	}
	else
	{
		for(i=0;i<18;i++)
			if(KbBuf[i]!=0)
			{
				KbBuf[i]=0;
				KbSta=KBBUF_NOKEY;		
			}
	}
	
	return KEY_NOKEY;	
}

void KbWait4High()
{
	while(!KB_CLK)
	if(DelayCnt==0)
		break;
}

void KbWait4Low()
{
	while(KB_CLK)
	if(DelayCnt==0)
		break;
}

void PS2_SendChar(unsigned char dat)//ps2主设备向从设备发送数据
{
	unsigned char SendCnt;
	unsigned char SendChk=0x00;
	EX0=0;
	EA=0;
	DelayCnt=2;//100ms
	//发起一个传送,发起始位
	KB_CLK=0;//将时钟线拉低并保持100us
	for(SendCnt=0;SendCnt<150;SendCnt++);
	KB_DAT=0;//起始位
	KB_CLK=1;
	//发送Data0-7
	for(SendCnt=0;SendCnt<8;SendCnt++)
	{
		KbWait4Low();//while(KB_CLK);//等待时钟线变为低
		KB_DAT=dat & 0x01;//发送数据
		if(KB_DAT)
			SendChk++;//计算校验
		KbWait4High();//while(!KB_CLK);//等待时钟线变高
		dat>>=1;//待发送数据右移一位
	}
	//发送校验位
	KbWait4Low();//while(KB_CLK);//等待时钟线变为低
	switch(SendChk)
	{
	case 0:
	case 2:
	case 4:
	case 6:
		KB_DAT=1;
		break;//奇校验
	case 1:
	case 3:
	case 5:
	case 7:
		KB_DAT=0;
		break;//奇校验
	default:
		break;
	}
	KbWait4High();//while(!KB_CLK);//等待时钟线变高
	KbWait4Low();//while(KB_CLK);//等待时钟线变为低
	KB_DAT=1; //发送停止位 停止位总为1
	KbWait4High();//while(!KB_CLK);//等待时钟线变高
	KbWait4Low();//while(KB_CLK);//等待时钟线变为低
	KbWait4High();//while(!KB_CLK);//等待时钟线变高
	KB_CLK=1;
	KB_DAT=1;
	EX0=1;
	EA=1;
}

void PS2_RecChar(void) interrupt INT_SOURCE_EX1//外部中断1
{
	
	unsigned char IntNum = 0; //中断次数计数
    unsigned char KeyV=0; //键值
	bit Kbparity;//奇校验

	EX0=0;
    EA=0;
    DelayCnt=2;
    //while (KB_CLK);//等待时钟线变低
    KbWait4High();//while(!KB_CLK);//等待PS/2CLK拉高:起始位不要
    for(IntNum=0;IntNum<8;IntNum++)
    {
		KbWait4Low();//while(KB_CLK);//等待PS/2CL拉低
		KeyV=KeyV>>1; //因键盘数据是低>>高,结合上一句所以右移一位
		if(KB_DAT)
			KeyV=KeyV | 0x80; //当键盘数据线为1时为1到最高位
		KbWait4High();//while(!KB_CLK);  //等待PS/2CLK拉高
    }
    KbWait4Low();//while(KB_CLK); //等待PS/2CLK拉低
	Kbparity=KB_DAT;//奇校验位
    KbWait4High();//while(!KB_CLK);//等待时钟线变高
    KbWait4Low();//while(KB_CLK);//等待PS/2CLK拉低:停止位不要
    KbWait4High();//while(!KB_CLK);//等待时钟线变高
	
	KbBuf[KbCnt]=KeyV;//存入缓存中
    KbCnt++;
	if(KbCnt>=KBBUF_SIZE)
		KbCnt=0;
    KbFlagSta=1;//标记新接收到一个编码
    EX0=1;
    EA=1;    
}

void PS2_Init()
{
	unsigned char xdata i;
	KB_CLK=1;
	KB_DAT=1;
	EX1=1;//
	//EA=1;//kf
//使用键盘上电时的默认设置
	//PS2_SendChar(KB_RESET);//复位
	//PS2_SendChar(KB_ALLKEY_MASK);//只用通码,禁止机打、断码
	//PS2_SendChar(KB_SETLED);//设置键盘Led
	//PS2_SendChar(KB_CAPSLOCK+KB_NUMLOCK+KB_SCROLLLOCK);

	for(i=0;i<KBBUF_SIZE;i++)
		KbBuf[i]=0;
	KbSta=KBBUF_NOKEY;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -