先贴上新的PS/2接口字符接收函数.
//从PS/2端口获取PS/2发送的字符 static bool PS2_ReadChar(uchar *ucGetChar) { uchar ucCount; bool ucOddValue; uchar ucTempVal; uchar ucResult; uint uiDelayCount; bool bTemp;
ucOddValue = false;
DISABLE; //Host释放总线控制权,让PS/2设备转换到数据发送状态,想发就快发,待会MCU要去干别的了. PS2DataTransEnable(); // Delay_10US(1); // PS2Kbd_Data=1; // PS2Kbd_Clk=1; // uiDelayCount = 0x1fffff; //关键时间 //捕获时钟下降沿,有超时退出机制,这段时间就是让PS/2设备响应时间 while(--uiDelayCount) { if(!GetPS2ClkStatus()) { // DISABLE; break; } }
//已经查询过了,没有数据要发上来,俺MCU去返回干别的去了. if(GetPS2ClkStatus()) //Repeat check { *ucGetChar = 0;
PS2DataTransDisable(); ENABLE; return false; }
//每位在时钟的下降沿被主机读入 //读取起始位必定为0 if(GetPS2DataStatus()) { if(GetPS2DataStatus()) { *ucGetChar = 0;
ucPS2CommErrFlag = 1; // ComShowString(COM_1,"START BIT ERR"); ENABLE; return false; } } //读完起始位开始读取数据位 ucTempVal = 0x01; ucResult = 0; for(ucCount=0; ucCount<8; ucCount++) { CaptureClkLow(); if(GetPS2DataStatus()) { ucResult |= ucTempVal; ucOddValue = !ucOddValue; //计算校验值 使用逻辑非操作 } ucTempVal <<= 1; }
//读取奇校验位 CaptureClkLow(); bTemp = GetPS2DataStatus(); // if(GetPS2DataStatus() && ucOddValue) //BUG if(GetPS2DataStatus() == ucOddValue) //奇校验,数据累加为0 ,校验位为1,累加和为1时,校验位为0 { //防抖动,不理想. // if(GetPS2DataStatus() && ucOddValue) // { ucPS2CommErrFlag = 2; // ComShowString(COM_1,"Odd Check ERR"); ENABLE; return false; // } } //获取停止位,必定为1 CaptureClkLow(); if(!GetPS2DataStatus()) { // if(!GetPS2DataStatus()) // {
ucPS2CommErrFlag = 3; // ComShowString(COM_1,"STOP BIT ERR");
ENABLE; return false; // } } //数据读取完成,置标志和结果转运 *ucGetChar = ucResult; ucPS2CommErrFlag = 0; //等待发送事件完成 CaptureClkHigh(); //禁止PS/2设备发送新数据,俺MCU有绝对控制权,要先去看看其它事件是否发生.有按键数据先自己缓存 PS2DataTransDisable(); ENABLE; return true; }
|