📄 atkeyboard.c
字号:
//
//
// 键盘监控出来,每个位之间间隔约为315T,即高70us低70us
// 一个码发出总时间为3450T,约为1.5ms
// 键盘发出的码为:通码 + 断码
// 如数字1:16 (间145000T,约为62ms) F0 (间3250T,约为1.5ms) 16
//
// 即每发一个码了去后,即要等一个码的时间去检查主机是否有发送数据过来
// 通码与断码间
// 机打第一个间隔约为466303T,约为200ms;后每个隔约为59250T,约为26.6ms
// 最后断码同无机打模式一样
#include <REG52.H>
#include <string.h>
#include <INTRINS.H>
#include "ATKeyboard.H"
#define _DEBUG
#ifdef _DEBUG
#include "..\Debug\Debug.H"
#endif
//-------------------------IO Define---------------------------
sbit Actual_Keyboard_CLK = P3^2; //实际键盘时钟IO
sbit Actual_Keyboard_Data = P3^4; //实际键盘数据IO
sbit Virtual_Keyboard_CLK = P1^1; //虚拟键盘时钟IO
sbit Virtual_Keyboard_Data = P1^2; //虚拟键盘数据IO
sbit Keyboard_Switch = P1^0; //键盘切换控制IO
//-------------------------------------------------------------
typedef union BIT_CHAR_DATA
{
struct _BIT_DATA
{
unsigned char Bit0:1;
unsigned char Bit1:1;
unsigned char Bit2:1;
unsigned char Bit3:1;
unsigned char Bit4:1;
unsigned char Bit5:1;
unsigned char Bit6:1;
unsigned char Bit7:1;
}Bits;
unsigned char Value;
}BitCharData;
bit bKeyParityBit; //奇偶校验位值
unsigned char data cKeyBufferBitCount; //当前接收数据位计数
BitCharData bcRecKeyData; //收到的键盘数据
sttKeyboardData stKeyboardData; //键盘数据
extern void Delay50us(unsigned char _50us);
extern void Delay1ms(unsigned char _1ms);
//控制实际键盘通讯IO通断
//bit KeyboardType:键盘选择,ACTUAL_KEYBOARD-实际键盘,VIRTUAL_KEYBOARD-虚拟键盘
void SelectKeyboard(bit KeyboardType)
{
Keyboard_Switch = KeyboardType;
}
//复位键盘监控
void ResetKeyboardMonitor()
{
IT0 = 1; // 设置外部中断0为边沿触发
PX0 = 1; // 设置外部中断0为高优先级
cKeyBufferBitCount = 0;
stKeyboardData.Length = 0;
memset(stKeyboardData.cKeyBuffer,0,KEYBOARD_BUFFER_SIZE);
bcRecKeyData.Value = 0;
}
void Keyboard_GetBit() interrupt 0
{
if(!Actual_Keyboard_CLK)
{
switch(cKeyBufferBitCount)
{
case 0: //起始位
if(Actual_Keyboard_Data) return; //不是正确的起始数据
cKeyBufferBitCount = 1; //收到一位起始位
bKeyParityBit = 1; //初始为1
break;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8: //数据位
//保存当前位数据
bcRecKeyData.Value >>= 1; //准备接收下一位数据
if(Actual_Keyboard_Data)
{
bcRecKeyData.Bits.Bit7 = 1;
bKeyParityBit ^= 1; //计算校验值
}
break;
case 9: //奇偶校验位
bKeyParityBit ^= Actual_Keyboard_Data;
cKeyBufferBitCount ++;
break;
case 10: //停止位
#ifdef _DEBUG
DebugData(1,1,&bcRecKeyData.Value);
#endif
cKeyBufferBitCount = 0; //准备接收下一键码
if(!Actual_Keyboard_Data) return; //没收到正确的停止位
if(bKeyParityBit) return; //奇校验出错
if(stKeyboardData.cKeyBuffer[stKeyboardData.Length] == bcRecKeyData.Value)
return; //收到的数据同上一次收到的值一样
//若不一样,则保存当前键码
//stKeyboardData.cKeyBuffer[stKeyboardData.Length++] = bcRecKeyData.Value;
}
}
}
void SendKeyCode(unsigned char KeyData)
{
unsigned char rst;
while(1)
{
#ifdef _DEBUG
DebugString("KeyData=");
DebugData(1,1,&KeyData);
#endif
rst = ATKeyboard_SendByte(KeyData);
#ifdef _DEBUG
DebugString("rst=");
DebugData(1,1,&rst);
#endif
if(rst!=KEYBOARD_RESENT) return ;//除重响应0xFE外,其它均不理
}
}
void SendKey(unsigned char KeyCode)
{
StopMonitorKeyboard(); //关闭键盘监控
SelectKeyboard(VIRTUAL_KEYBOARD); //选取虚拟键盘
SendKeyCode(KeyCode); //发送通码
Delay1ms(10); //硬件越差的设备,这里的延时要越长
SendKeyCode(KEYUP); //发送断码
SendKeyCode(KeyCode); //这个码同前一个码只要间1.5ms即可,在接收ECHO里已经有这时长了
SelectKeyboard(ACTUAL_KEYBOARD); //选取实际键盘
StartMonitorKeyboard(); //开键盘监控程序,接收数据
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -