打印
[应用方案]

自制USB键盘转载于圈圈

[复制链接]
1248|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
捉虫天师|  楼主 | 2016-2-11 19:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
哈哈,终于搞了一回USB HID设备,做了一个USB键盘来玩玩~~~~其中的报告描述符让我晕了几天~~~~~几份HID相关的协议还是蛮长的~~~~~~明天再弄个USB鼠标设备玩玩~~~~~~~有空的话再搞个红外遥控器玩玩~~~
这回是拿以前做的Mass storage来改的,所以比较快,修改了一下描述符以及端点处理等,就行了。用了一个4*4的小键盘,有0-9十个数字键,Num Lock键,Caps Lock键,Shift键,Ctrl键,Alt键,回车键等。

最多可以有三个键同时按下,如果相交的话,最多只能两个键按下。


以下是通过串口返回的调试信息:

系统启动................................
断开USB连接........................
USBD12芯片初始化
   设置地址.....................
       地址为:  0
连接USB...............
USB总线复位................................
USB总线挂起................................
USB总线复位................................
USB总线挂起................................
USB总线复位................................
USB标准请求................................
    获取描述符................................
        获取设备描述符................................
USB总线复位................................
USB标准请求................................
   设置地址.....................
       地址为:  2
USB标准请求................................
    获取描述符................................
        获取设备描述符................................
USB标准请求................................
    获取描述符................................
USB标准请求................................
    获取描述符................................
        获取配置描述符................................
USB标准请求................................
    获取描述符................................
        获取字符串描述符................................
            获取语言ID................................
USB标准请求................................
    获取描述符................................
        获取字符串描述符................................
            获取设备序列号................................
USB标准请求................................
    获取描述符................................
USB标准请求................................
    获取描述符................................
        获取配置描述符................................
USB标准请求................................
    获取描述符................................
USB标准请求................................
    获取描述符................................
USB标准请求................................
    获取描述符................................
        获取字符串描述符................................
            获取语言ID................................
USB标准请求................................
    获取描述符................................
        获取字符串描述符................................
            获取产品字符串................................
USB标准请求................................
    获取描述符................................
USB标准请求................................
    获取描述符................................
USB标准请求................................
    获取描述符................................
USB标准请求................................
    获取描述符................................
USB标准请求................................
    获取描述符................................
USB标准请求................................
    获取描述符................................
        获取字符串描述符................................
            获取语言ID................................
USB标准请求................................
    获取描述符................................
        获取字符串描述符................................
            获取产品字符串................................
USB标准请求................................
    获取描述符................................
USB标准请求................................
    获取描述符................................
USB标准请求................................
    获取描述符................................
USB标准请求................................
    获取描述符................................
USB标准请求................................
    获取描述符................................
USB标准请求................................
    获取描述符................................
        获取设备描述符................................
USB标准请求................................
    获取描述符................................
USB标准请求................................
    获取描述符................................
        获取配置描述符................................
USB标准请求................................
    获取描述符................................
        获取配置描述符................................
USB标准请求................................
    获取描述符................................
USB标准请求................................
    获取描述符................................
USB标准请求................................
    设置配置................................
USB类请求................................
    设置空闲................................
USB标准请求................................
    获取描述符(从接口)..............................
        获取报告描述符................................
USB标准请求................................
    获取描述符(从接口)..............................
USB标准请求................................
    获取描述符(从接口)..............................
USB标准请求................................
    获取描述符(从接口)..............................
USB标准请求................................
    获取描述符(从接口)..............................
USB标准请求................................
    获取描述符(从接口)..............................
USB标准请求................................
    获取描述符(从接口)..............................
USB标准请求................................
    获取描述符(从接口)..............................
端点2输出................................
    端点2的数据是  0x01
端点2输出................................
    端点2的数据是  0x03
端点2输出................................
    端点2的数据是  0x01
端点2输出................................
    端点2的数据是  0x00
端点2输出................................
    端点2的数据是  0x02
端点2输出................................
    端点2的数据是  0x03


在设备管理器里看到的图:



原理图
(用的是以前做IDE转USB的板,所以上面还有个IDE接口和573锁存器,可以不用理会它们):

(注意:原理图上所标的晶体值是以前的,这个程序中使用的是22.1184M的晶体.它关系到串口波特率,如果你不使用串口,那么可以不用理会它.)


注意:图中串口电平转换部分的C8和C10接反了,C11负端应接VDD。D12的SUSPEND(12脚)应该接地。USB接头的D+和D-跟芯的D+和D-之间应该串联22欧姆的匹配电阻。片由于图得比较匆忙,所以没留意。右击选择图片另存为可以看到完整图片了.
实物图片(键盘是外接的):
  


沙发
捉虫天师|  楼主 | 2016-2-11 19:32 | 只看该作者
/******************************************************************
   本程序只供学习使用,未经作者许可,不得用于其它任何用途
      http://www.fxdzw.com

KEY.C  file

作者:Computer-lov
建立日期: 2007.03.20
修改日期: 2007.03.22
版本:V1.1
版权所有,盗版必究。
Copyright(C) Computer-lov 2007-2017
All rights reserved            
*******************************************************************/


#include "Key.h"
#include "my_type.h"

uint16 idata KeyMapCurrent,KeyMapOld,KeyMapOk,KeyNoChangedTime;
uint8 KeyMapCanChange;

#define KeyIO P1

/*************************定时器0初始化***************************************/
void InitTimer0(void)
{
TMOD&=0xF0;
TMOD|=0x01;
TH0=0xDC;
ET0=1;
TR0=1;
}
/******************************************************************************/

/*************************定时器0中断处理***************************************/
void Timer0Isr(void) interrupt 1
{
uint8 temp;
TH0=0xDC;         //定时器0重装
KeyIO=0x0F;
if((KeyIO&0x0F)==0x0F)  //如果现在没有按键按下
  {
   KeyMapCurrent=0;   //没有键按下
  }
else
  {
   //开始键盘扫描

   //扫描第一行
   KeyIO=~0x10;

   //保存四个开关状态       
   temp=KeyIO&0x0F;

   //扫描第二行          
   KeyIO=~0x20;

   //保存四个开关状态                  
   temp|=KeyIO<<4;

   //保存按键状态到当前按键情况      
   KeyMapCurrent=(~temp)&0xFF;

   //扫描第三行
   KeyIO=~0x40;       

   //保存四个开关状态          
   temp=KeyIO&0x0F;

   //扫描第四行         
   KeyIO=~0x80;

   //保存四个开关状态          
   temp|=KeyIO<<4;
     
   //保存全部16个开关的状态
   //KeyMap总共有16个bit,当某个开关按下时,
   //对应的bit为1
   KeyMapCurrent|=(((uint16)~temp)<<8);
  }

if(KeyMapCurrent!=KeyMapOld)  //说明按键情况发生了改变
  {
   KeyNoChangedTime=0;       //键盘按下时间为0
   KeyMapOld=KeyMapCurrent;  //保存当前按键情况
   return;
  }
else
  {
   KeyNoChangedTime++;          //按下时间累计
   if(KeyNoChangedTime>=1)         //如果按下时间足够
    {
         KeyNoChangedTime=1;
         if(KeyMapCanChange)
          {
           KeyMapOk=KeyMapOld;  //保存按键
          }
        }
  }
}
/******************************************************************************/


使用特权

评论回复
板凳
捉虫天师|  楼主 | 2016-2-11 19:33 | 只看该作者
/******************************************************************
   本程序只供学习使用,未经作者许可,不得用于其它任何用途
      http://www.fxdzw.com

UART.C  file

作者:Computer-lov
建立日期: 2007.03.20
修改日期: 2007.03.22
版本:V1.1
版权所有,盗版必究。
Copyright(C) Computer-lov 2007-2017
All rights reserved            
*******************************************************************/

#include <at89x52.H>

#include "UART.h"
#include "my_type.h"

uint8 Sending;


//**************************************************************************************
void InitUART(void)  //串口初始化函数,使用22.1184M晶体
{
EA=0;
TMOD&=0x0F;
TMOD|=0x20;    //定时器1工作在模式2
SCON=0x50;    //串口工作在模式1
TCON=0x05;
TH1=0xF4;     //9600bps
TL1=0xF4;
PCON=0x80;    //串口波特率加倍
ES=1;         //串行中断允许
TR1=1;        //启动定时器1
REN=1;        //允许接收
EA=1;         //允许中断
}
//****************************************************************************************


//*******************************   串口中断处理        ***********************************
void SerialPort(void) interrupt 4
{
if(RI)    //收到数据
  {
   RI=0;                     //清中断请求
  }
else  //发送完一字节数据
  {
   TI=0;
   Sending=0;               //清正在发送标志
  }
}
//*****************************************************************************************

//*****************************************************************************************
void SendToComport(unsigned char d)       //往串口发送一字节数据
{
Sending=1;
SBUF=d;
while(Sending);
}
//*****************************************************************************************

//*****************************************************************************************
//发送一个字符串
void prints(uint8 * pd,uint8 line_feed)
{
while((*pd)!='\0')
  {
   SendToComport(*pd);
   pd++;
  }
if(line_feed)
{
  SendToComport(13);
  SendToComport(10);
}
}
//****************************************************************************************



//*****************************************************************************************
void PrintLongInt(uint32 x)  //将整数转按十进制字符串发送
{
int8 i;
uint8 display_buffer[10];
display_buffer[10]=0;
for(i=9;i>=0;i--)
  {
   display_buffer[i]='0'+x%10;
   x/=10;
  }
for(i=0;i<9;i++)
  {
   if(display_buffer[i]!='0')break;
  }
for(;i<10;i++)SendToComport(display_buffer[i]);
}
//*****************************************************************************************


code uint8 HexTable[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
//*****************************************************************************************
/*
void PrintLongIntHex(uint32 x)  //将整数按十六进制发送
{
uint8 i;
uint8 display_buffer[11];
display_buffer[10]=0;
display_buffer[0]='0';
display_buffer[1]='x';
for(i=9;i>=2;i--)
  {
   display_buffer[i]=HexTable[(x&0xf)];
   x>>=4;
  }
prints(display_buffer,0);
}
*/
//*****************************************************************************************


//*****************************************************************************************
void Printc(uint8 x)  //发送一个byte的数据
{
Sending=1;
SBUF=x;
while(Sending);
}
//*****************************************************************************************


//*****************************************************************************************
void PrintHex(uint8 x)  //以HEX格式发送一个byte的数据
{
Printc('0');
Printc('x');
Printc(HexTable[x>>4]);
Printc(HexTable[x&0xf]);
Printc(' ');
}
//*****************************************************************************************


使用特权

评论回复
地板
Thethree| | 2016-2-14 10:01 | 只看该作者
我前段时间也制作了USB键盘,不过用的是带USB的芯片

使用特权

评论回复
5
wahahaheihei| | 2016-2-14 12:06 | 只看该作者
图中串口电平转换部分的C8和C10接反了,C11负端应接VDD。

使用特权

评论回复
6
dentsgot| | 2016-2-14 17:50 | 只看该作者
这个USB做的hid 键盘在仪器上还是很实用的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

193

主题

3057

帖子

7

粉丝