标题:
关于单片机模拟键盘初始化的问题
[打印本页]
作者:
yzcook
时间:
2018-4-24 14:52
标题:
关于单片机模拟键盘初始化的问题
刚开始学习PS2协议,写了PS2设备发送到PC的函数,和PS2设备接收PC的函数, 但是在开机自检的时候出了问题,我认为是接收函数 可能写错了。然后我用串口监测接收,按理来说我按下cap键,设备应该会接收到PC发送过来的命令吧,但是却没有。所有想请大佬帮我看下,哪里出错了
作者:
yzcook
时间:
2018-4-24 14:54
这是我的主函数
#include <reg51.h>
#include "ps2.h"
#include "delay.h"
#include "usart.h"
#include "key.h"
#include<intrins.h>
sbit BEEP = P1^7;
void main ( )
{
ConfigUART(9600);
while(1)
{
ps2_rec();
receive_process();//处理PC命令
// delay_ms(5000);
}
}
作者:
yzcook
时间:
2018-4-24 14:54
这是我的发送函数
发送应该是没有问题的
因为我发送0x58 能实现让灯亮
void ps2_send(unsigned char value)
{
unsigned char i;
unsigned char char_temp,temp;
unsigned char PARITY = 1 ;
temp = value;
last_s = value;
for(i=0;i<8;i++)
{
char_temp = temp&0x01; //奇效验,找出发送的数据中1的个数,如果为偶数,则置标志位为1,反之为0
if(char_temp == 0x01)
{
PARITY = !PARITY;
}
temp = temp>>1;
}
PS2_CLK = 1;
PS2_DAT = 1;
while(!PS2_CLK) //等待clock为高
{
PS2_CLK = 1;
PS2_DAT = 1;
Delay50us();
}
PS2_CLK = 1;
PS2_DAT = 1;
if(PS2_CLK)
{
if(PS2_DAT)
{
PS2_DAT = 0; //PC在PS2_CLK的下降沿读取数据,起始位
Delay20us();
PS2_CLK = 0;
Delay40us();
for (i=0; i<8;i++) //发送数据位
{
PS2_CLK = 1;
Delay20us();
char_temp = value&0x01;
if(char_temp == 0x01)
PS2_DAT = 1;
else
PS2_DAT = 0;
char_temp = 0;
Delay20us();
PS2_CLK = 0;
Delay40us();
value = value>>1;
}
PS2_CLK = 1;
Delay20us();
PS2_DAT = PARITY; //发送奇校验
Delay20us();
PS2_CLK = 0;
Delay40us();
PS2_CLK = 1;
Delay20us();
PS2_DAT = 1; // 发送停止位
Delay20us();
PS2_CLK = 0;
Delay40us();
PS2_CLK = 1;
}
}
Delay50us();
}
作者:
yzcook
时间:
2018-4-24 14:55
这是我的接收函数
感觉在这里出了问题
unsigned char ps2_rec( )//返回接收到的字节,接收错误则返回0
{
unsigned char i,STOPBIT;
unsigned char PARITY,temp ;
PS2_CLK = 1;
PS2_DAT = 1;
Delay100us();
PS2_DAT = 0;
PS2_CLK = 1;
if (PS2_DAT)//PS2_DAT应该为低 如果此时PS2_DAT为高,则退出并发送错误状态字0xfe
{
ps2_send(0xfe);
return 0;
}
else
{
Delay40us();
for(i=0;i<8;i++)
{
Delay20us();
PS2_CLK = 0;
Delay40us();
PS2_CLK = 1;
Delay20us();
temp = temp>>1;
if(PS2_DAT)
{
temp |=0x80;
}
}
// SendByte(0X30+temp);
// delay_ms(3000);
if(!PS2_CLK) //每读完一个位都检测时钟线是否被拉低
{
ps2_send(0xfe);
return 0;
}
//======================================================
Delay20us();
PS2_CLK = 0;
Delay40us();
PS2_CLK = 1;
Delay20us();
PARITY = PS2_DAT;
if(!PS2_CLK) //每读完一个位都检测时钟线是否被拉低
{
ps2_send(0xfe);
return 0;
}
// SendByte(0x30+PARITY);
// SendStr("4");
//======================================================
Delay20us();
PS2_CLK = 0;
Delay40us();
PS2_CLK = 1;
Delay20us();
STOPBIT = PS2_DAT;
if(!PS2_CLK)//接收停止位,此时PS2_DAT应该为高,否则发送0xfe报错
{
ps2_send(0xfe);
return 0;
}
//======================================================
Delay15us();
PS2_DAT = 0;
Delay5us();
PS2_CLK = 0;
Delay40us();
PS2_CLK = 1;
Delay5us();
PS2_DAT = 1;
ACC = temp;
SendByte(P);
if(P == PARITY) //进行奇校验
{
// ps2_send(0xfe);
return 0;
}
// SendStr("0x33");
Delay40us();
Delay5us();
}
// SendByte(0X30+temp);
return temp;
}
作者:
yzcook
时间:
2018-4-24 14:56
这是命令处理函数
unsigned char receive_process()
{
unsigned char command,led_rec;
// if(!KB_START()) return;//如果当前的PS2_CLK和PS2_DAT不都为低,表明没有命令
command = ps2_rec();
// SendStr("pass");
switch(command)
{
case 0xff: //复位命令
ps2_send(0xfa);
delay_ms(50);
ps2_send(0xaa); //自检通过返回0xaa
//执行复位
break;
case 0xfe:
ps2_send(0xfa);
ps2_send(last_s); //发送上一次的命令
break;
case 0xf6: //设置缺省值
ps2_send(0xfa);
break;
case 0xf5: //设置缺省值和停止键盘 ,等待进一步命令
ps2_send(0xfa);
break;
case 0xf4: //重新使能键盘
ps2_send(0xfa);
break;
case 0xf3: //设置机打速率和延迟
ps2_send(0xfa);
break;
case 0xee://回应命令
ps2_send(0xee);
case 0xed: //指示灯参数
ps2_send(0xfa);
led_rec = ps2_rec();
SendByte(led_rec);
ps2_send(0xfa);
break;
default:
ps2_send(0xfa); //对于其他命令发送完成标志
break;
}
return command;
}
作者:
yzcook
时间:
2018-4-25 08:09
有没有大神能解答下
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1