|
这是我写的一个PS2与单片机通信的程序。
但是还没有加入Shift功能,和其他功能键。
现在只能完成普通的输入。
想完成一个完整的PS2键盘程序,还请高手指点。
CPU:STC89C55RD+
编译环境:Keil C 8.0
没有奇校验
上位机可以使用串口调试助手或超级终端都行。
/*----------------------main.c---------------------------*/
#include "STC89CXXRD.H"
#include "PS2KeyBoard.H"
#define uchar unsigned char
void main(void)
{
uchar redat;
TMOD = 0x20; //定时/计数器1,工作方式2
TL1 = 0xfa; //11.0592M晶振波特率为4800bps
TH1 = 0xfa;
TR1 = 1; //启动计数器1
SCON = 0x40; //串行口工作为方式1发送
while(1)
{
redat = ReceiveDatFromPS2KeyBoard();
if(redat)
{
SBUF = redat;
while(!TI);
TI = 0;
}
}
}
/*---------------------PS2KEY.C---------------------------*/
/*
╭════════════════════════════════════╮
║ 公司名称:吉林工程技术师范学院 ║
║ ║
║ 模 块 名:PS2键盘驱动程序 驱动芯片型号:第二套键盘模版 ║
║ ║
║ 创 建 人:韩林 日期:2007-02-08 ║
║ ║
║ 修 改 人:韩林 日期:2007-02-08 ║
║ ║
║ 功能描述:将PC机的PS2键盘利用单片机读回数据,并进行译码.(查询方式) ║
║ ║
║ 其他说明:无 ║
║ ║
║ 版 本:v1.0 ║
║ ║
║ E-mail : hanlinxp@163.com QQ: 33737559 ║
║ ║
║ Copyright@2006 - 2007 ║
║ ║
╰════════════════════════════════════╯
*/
#include "STC89CXXRD.H"
#define uchar unsigned char
#define SHIFT 0x12
/*
╭════════════════════════════════════╮
║ ║
║ 硬 件 信 号 定 义 ║
║ ║
╰════════════════════════════════════╯
*/
sbit io_dat_ps2key = P1^0; //PS2键盘的数据端口
sbit io_clk_ps2key = P3^2; //PS2键盘的时钟端口
/*
╭════════════════════════════════════╮
║ ║
║ 键 码 转 换 数 组 ║
║ ║
╰════════════════════════════════════╯
*/
//没有按下Shift键时的键码转换
static unsigned char code UnShifted[59][2] = {0x1C, 'a',0x32, 'b',0x21, 'c',0x23, 'd',0x24, 'e',
0x2B, 'f',0x34, 'g',0x33, 'h',0x43, 'i',0x3B, 'j',
0x42, 'k',0x4B, 'l',0x3A, 'm',0x31, 'n',0x44, 'o',
0x4D, 'p',0x15, 'q',0x2D, 'r',0x1B, 's',0x2C, 't',
0x3C, 'u',0x2A, 'v',0x1D, 'w',0x22, 'x',0x35, 'y',
0x1A, 'z',0x45, '0',0x16, '1',0x1E, '2',0x26, '3',
0x25, '4',0x2E, '5',0x36, '6',0x3D, '7',0x3E, '8',
0x46, '9',0x0E, '`',0x4E, '-',0x55, '=',0x5D, '\\',
0x29, ' ',0x54, '[',0x5B, ']',0x4C, ';',0x52, '\'',
0x41, ',',0x49, '.',0x4A, '/',0x71, '.',0x70, '0',
0x69, '1',0x72, '2',0x7A, '3',0x6B, '4',0x73, '5',
0x74, '6',0x6C, '7',0x75, '8',0x7D, '9',};
//按下Shift键时的键码转换
/*static unsigned char code Shifted[59][2] = {0x1C, 'A',0x32, 'B',0x21, 'C',0x23, 'D',0x24, 'E',
0x2B, 'F',0x34, 'G',0x33, 'H',0x43, 'I',0x3B, 'J',
0x42, 'K',0x4B, 'L',0x3A, 'M',0x31, 'N',0x44, 'O',
0x4D, 'P',0x15, 'Q',0x2D, 'R',0x1B, 'S',0x2C, 'T',
0x3C, 'U',0x2A, 'V',0x1D, 'W',0x22, 'X',0x35, 'Y',
0x1A, 'Z',0x45, '0',0x16, '1',0x1E, '2',0x26, '3',
0x25, '4',0x2E, '5',0x36, '6',0x3D, '7',0x3E, '8',
0x46, '9',0x0E, '~',0x4E, '_',0x55, '+',0x5D, '|',
0x29, ' ',0x54, '{',0x5B, '}',0x4C, ':',0x52, '"',
0x41, '<',0x49, '>',0x4A, '?',0x71, '.',0x70, '0',
0x69, '1',0x72, '2',0x7A, '3',0x6B, '4',0x73, '5',
0x74, '6',0x6C, '7',0x75, '8',0x7D, '9',};
/*
╭════════════════════════════════════╮
║ ║
║ 函 数 原 型 声 明 ║
║ ║
╰════════════════════════════════════╯
*/
static uchar ReceiveByte(void);
static void SkipCode(void);
static uchar ReceiveDat(void); //接收一个正常键
static uchar ChangeASCII(uchar dat); //将接通码转为简码的ASCII码
uchar ReceiveDatFromPS2KeyBoard(void); //返回相应按键的ASCII码
/*
╭════════════════════════════════════╮
║ 函 数 名: static uchar ReceiveByte(void) ║
║ 功能模式: 内部 ║
║ 函数说明: 返回键盘传送的一个字节. ║
║ 调用函数: 无 ║
║ 全局变量: 无 ║
║ 端口信号: io_clk_ps2key、io_dat_ps2key ║
║ 输 入: 无 ║
║ 返 回: 11位数据中的8位数据. ║
║ 设 计 者: 韩林 日 期:2007-02-09 ║
║ 修 改 者: 韩林 日 期:2007-02-09 ║
║ E-mail : hanlinxp@163.com QQ: 33737559 ║
║ 版 本: v1.0 ║
║ ║
║ Copyright@2006 - 2007 ║
║ ║
╰════════════════════════════════════╯
*/
static uchar ReceiveByte(void)
{
uchar i,dat = 0;
while(!io_clk_ps2key); //起始位0
while(io_clk_ps2key);
for(i=0;i<8;i++) //接收8位数据
{
dat >>= 1;
if(io_dat_ps2key)
dat |= 0x80;
while(!io_clk_ps2key);
while(io_clk_ps2key);
}
//此处取出奇校验位
while(!io_clk_ps2key);
while(io_clk_ps2key);
while(!io_clk_ps2key);
return dat;
}
/*
╭════════════════════════════════════╮
║ 函 数 名: static void SkipCode(void) ║
║ 功能模式: 内部 ║
║ 函数说明: 将其余编码跳过. ║
║ 调用函数: 无 ║
║ 全局变量: 无 ║
║ 端口信号: io_clk_ps2key、io_dat_ps2key ║
║ 输 入: 无 ║
║ 返 回: 无 ║
║ 设 计 者: 韩林 日 期:2007-02-09 ║
║ 修 改 者: 韩林 日 期:2007-02-09 ║
║ E-mail : hanlinxp@163.com QQ: 33737559 ║
║ 版 本: v1.0 ║
║ ║
║ Copyright@2006 - 2007 ║
║ ║
╰════════════════════════════════════╯
*/
static void SkipCode(void)
{
(void)ReceiveByte();
(void)ReceiveByte();
}
/*
╭════════════════════════════════════╮
║ 函 数 名: static uchar ReceiveDat(void) ║
║ 功能模式: 内部 ║
║ 函数说明: 返回键盘按键对应的一个接通码. ║
║ 调用函数: ReceiveByte()、SkipCode() ║
║ 全局变量: 无 ║
║ 端口信号: 无 ║
║ 输 入: 无 ║
║ 返 回: 键盘的接通码. ║
║ 设 计 者: 韩林 日 期:2007-02-08 ║
║ 修 改 者: 韩林 日 期:2007-02-09 ║
║ E-mail : hanlinxp@163.com QQ: 33737559 ║
║ 版 本: v1.1 ║
║ ║
║ Copyright@2006 - 2007 ║
║ ║
╰════════════════════════════════════╯
*/
static uchar ReceiveDat(void)
{
uchar dat;
if(io_clk_ps2key) //如果无键按下,返回0
return 0;
dat = ReceiveByte();
SkipCode();
return dat; //返回接通码
}
/*
╭════════════════════════════════════╮
║ 函 数 名: static uchar ChangeASCII(uchar dat) ║
║ 功能模式: 内部 ║
║ 函数说明: 将接通码转为与键盘按键对应的ASCII码. ║
║ 调用函数: 无 ║
║ 全局变量: 无 ║
║ 端口信号: 无 ║
║ 输 入: 无 ║
║ 返 回: 键盘按键的ASCII码. ║
║ 设 计 者: 韩林 日 期:2007-02-08 ║
║ 修 改 者: 韩林 日 期:2007-02-08 ║
║ E-mail : hanlinxp@163.com QQ: 33737559 ║
║ 版 本: v1.0 ║
║ ║
║ Copyright@2006 - 2007 ║
║ ║
╰════════════════════════════════════╯
*/
static uchar ChangeASCII(uchar dat)
{
uchar i;
if(dat == 0)
return 0;
for(i=0;i<59;i++)
{
if(UnShifted[0] == dat) //没按Shift键
return UnShifted[1];
}
return 0;
}
/*
╭════════════════════════════════════╮
║ 函 数 名: uchar ReceiveDatFromPS2KeyBoard(void) ║
║ 功能模式: 全局 ║
║ 函数说明: 返回键盘按键的ASCII码,没有按键则为0. ║
║ 调用函数: ChangeASCII()、ReceiveDat() ║
║ 全局变量: 无 ║
║ 端口信号: 无 ║
║ 输 入: 无 ║
║ 返 回: 键盘按键的ASCII码. ║
║ 设 计 者: 韩林 日 期:2007-02-08 ║
║ 修 改 者: 韩林 日 期:2007-02-08 ║
║ E-mail : hanlinxp@163.com QQ: 33737559 ║
║ 版 本: v1.0 ║
║ ║
║ Copyright@2006 - 2007 ║
║ ║
╰════════════════════════════════════╯
*/
uchar ReceiveDatFromPS2KeyBoard(void)
{
return ChangeASCII(ReceiveDat());
}
/*-------------------------PS2KEYBOARD.H------------------------*/
extern unsigned char ReceiveDatFromPS2KeyBoard(void); //返回相应按键的ASCII码
-----此内容被hanlin于2007-02-09,14:27:07编辑过 |
阿莫论坛20周年了!感谢大家的支持与爱护!!
你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。
|