找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1940|回复: 5
打印 上一主题 下一主题
收起左侧

关于单片机模拟键盘初始化的问题

[复制链接]
跳转到指定楼层
楼主
ID:305998 发表于 2018-4-24 14:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
50黑币
刚开始学习PS2协议,写了PS2设备发送到PC的函数,和PS2设备接收PC的函数, 但是在开机自检的时候出了问题,我认为是接收函数 可能写错了。然后我用串口监测接收,按理来说我按下cap键,设备应该会接收到PC发送过来的命令吧,但是却没有。所有想请大佬帮我看下,哪里出错了

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:305998 发表于 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);

       
               
               


               
        }  

}
回复

使用道具 举报

板凳
ID:305998 发表于 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();
       
}

回复

使用道具 举报

地板
ID:305998 发表于 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;
        }
回复

使用道具 举报

5#
ID:305998 发表于 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;
}
回复

使用道具 举报

6#
ID:305998 发表于 2018-4-25 08:09 | 只看该作者
有没有大神能解答下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表