- 注册时间
- 2015-8-28
- 最后登录
- 2015-9-21
- 阅读权限
- 20
- 积分
- 42
- 精华
- 0
- 帖子
- 10
|
版主,你好,我用你们的板子做了一个测试程序:
1.设别描述符如下:
[code=cpp]//设备描述符
const USB_DEVICE_DESCRIPTOR DeviceDescr=
{
sizeof(USB_DEVICE_DESCRIPTOR), //设备描述符长度,= 12H
USB_DEVICE_DESCRIPTOR_TYPE, //设备描述符类型,= 01H
0x10,1, //协议版本,= 2.00
0, //设备类型由接口描述符提供
0, 0, //设备子类,设备协议
EP0_PACKET_SIZE, //端点0最大数据包大小,= 10H
0xd9,0x04, //公司的设备ID
0x33,0x11, //设备制造商定的产品ID
0x00,0x01, //设备系列号
0, 0, 0, //索引
1 //可能的配置数
};
const USB_DESCRIPTOR usb_descr =
{
//配置描述符
{
sizeof(USB_CONFIGURATION_DESCRIPTOR), //配置描述符长度,= 09H
USB_CONFIGURATION_DESCRIPTOR_TYPE, //配置描述符类型,= 02H
sizeof(USB_DESCRIPTOR),0x00, //描述符总长度
1, //只支持1个接口
1, //配置值
0, //字符串描述符指针(无)
0x80, //总线供电
0x32 //最大功耗(100mA)
},
//接口描述符
{
sizeof(USB_INTERFACE_DESCRIPTOR), //接口描述符长度,= 09H
USB_INTERFACE_DESCRIPTOR_TYPE, //接口描述符类型,= 04H
0, //接口数,只有1个
0, //可选配置,只有1个
1, //除端点0的端点索引数目,= 02H
0x03, //人机接口设备(HID)类
1, //使用的子类:(支持boot)
1, //bInterfaceProtocol为1代表键盘
0 //字符串描述符索引
},
//hid_descriptor
{
sizeof(USB_HID_DESCRIPTOR), //HID描述符的字节数大小 0x09
USB_HID_DESCRIPTOR_TYPE, //HID描述符类型编号0x21
0x10,0x01,
0x21, //固件的国家地区代号
NUM_SUB_DESCRIPTORS, //下级描述符的数量0x01
USB_REPORT_DESCRIPTOR_TYPE, //下级描述符为报告描述符0x22
sizeof(MouseReportDescriptor),0
},
//端点1输入
{
sizeof(USB_ENDPOINT_DESCRIPTOR), //端点描述符长度,= 07H
USB_ENDPOINT_DESCRIPTOR_TYPE, //端点描述符类型,= 05H
0x81, //端点1 in
USB_ENDPOINT_TYPE_INTERRUPT, //中断传输,= 03H
EP1_PACKET_SIZE,0x00, //端点最大包的大小,= 0040H
255
}
};[/code]
2、报告描述符号如下:
[code=cpp]const u8 MouseReportDescriptor[63]={
//表示用途页为通用桌面设备
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
//表示用途为键盘
0x09, 0x06, // USAGE (Keyboard)
//表示应用集合,必须要以END_COLLECTION来结束它,见最后的END_COLLECTION
0xa1, 0x01, // COLLECTION (Application)
//表示用途页为按键
0x05, 0x07, // USAGE_PAGE (Keyboard)
//用途最小值,这里为左ctrl键
0x09, 0x04, // USAGE_MINIMUM (Keyboard LeftControl) a
//用途最大值,这里为右GUI键,即window键
0x09, 0x0b, // USAGE_MAXIMUM (Keyboard Right GUI) h
//逻辑最小值为0
0x15, 0x00, // LOGICAL_MINIMUM (0)
//逻辑最大值为1
0x25, 0x01, // LOGICAL_MAXIMUM (1)
//报告大小(即这个字段的宽度)为1bit,所以前面的逻辑最小值为0,逻辑最大值为1
0x75, 0x01, // REPORT_SIZE (1)
//报告的个数为8,即总共有8个bits
0x95, 0x08, // REPORT_COUNT (8)
//输入用,变量,值,绝对值。像键盘这类一般报告绝对值,
//而鼠标移动这样的则报告相对值,表示鼠标移动多少
0x81, 0x02, // INPUT (Data,Var,Abs)
//上面这这几项描述了一个输入用的字段,总共为8个bits,每个bit表示一个按键
//分别从左ctrl键到右GUI键。这8个bits刚好构成一个字节,它位于报告的第一个字节。
//它的最低位,即bit-0对应着左ctrl键,如果返回的数据该位为1,则表示左ctrl键被按下,
//否则,左ctrl键没有按下。最高位,即bit-7表示右GUI键的按下情况。中间的几个位,
//需要根据HID协议中规定的用途页表(HID Usage Tables)来确定。这里通常用来表示
//特殊键,例如ctrl,shift,del键等
//这样的数据段个数为1
0x95, 0x01, // REPORT_COUNT (1)
//每个段长度为8bits
0x75, 0x08, // REPORT_SIZE (8)
//输入用,常量,值,绝对值
0x81, 0x03, // INPUT (Cnst,Var,Abs)
//上面这8个bit是常量,设备必须返回0
//这样的数据段个数为5
0x95, 0x05, // REPORT_COUNT (5)
//每个段大小为1bit
0x75, 0x01, // REPORT_SIZE (1)
//用途是LED,即用来控制键盘上的LED用的,因此下面会说明它是输出用
0x05, 0x08, // USAGE_PAGE (LEDs)
//用途最小值是Num Lock,即数字键锁定灯
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
//用途最大值是Kana,这个是什么灯我也不清楚^_^
0x29, 0x05, // USAGE_MAXIMUM (Kana)
//如前面所说,这个字段是输出用的,用来控制LED。变量,值,绝对值。
//1表示灯亮,0表示灯灭
0x91, 0x02, // OUTPUT (Data,Var,Abs)
//这样的数据段个数为1
0x95, 0x01, // REPORT_COUNT (1)
//每个段大小为3bits
0x75, 0x03, // REPORT_SIZE (3)
//输出用,常量,值,绝对
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
//由于要按字节对齐,而前面控制LED的只用了5个bit,
//所以后面需要附加3个不用bit,设置为常量。
//报告个数为6
0x95, 0x06, // REPORT_COUNT (6)
//每个段大小为8bits
0x75, 0x08, // REPORT_SIZE (8)
//逻辑最小值0
0x15, 0x00, // LOGICAL_MINIMUM (0)
//逻辑最大值255
0x25, 0xFF, // LOGICAL_MAXIMUM (255)
//用途页为按键
0x05, 0x07, // USAGE_PAGE (Keyboard)
//使用最小值为0
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
//使用最大值为0x65
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
//输入用,变量,数组,绝对值
0x81, 0x00, // INPUT (Data,Ary,Abs)
//以上定义了6个8bit宽的数组,每个8bit(即一个字节)用来表示一个按键,所以可以同时
//有6个按键按下。没有按键按下时,全部返回0。如果按下的键太多,导致键盘扫描系统
//无法区分按键时,则全部返回0x01,即6个0x01。如果有一个键按下,则这6个字节中的第一
//个字节为相应的键值(具体的值参看HID Usage Tables),如果两个键按下,则第1、2两个
//字节分别为相应的键值,以次类推。
//关集合,跟上面的对应
0xc0 // END_COLLECTION
};[/code]
3、做了一个测试程序,模拟键盘输入
定时器每 1.5s产生一次如下中断
[code=cpp] if((++g_app.m_time500msAcc)>=375) //1.5s
{
g_app.m_time500msAcc=0;
bEPPflags.bits.KB_KeyUp=1;
if(bEPPflags.bits.KB_KeyUpSwitch)
{
bEPPflags.bits.KB_KeyUpSwitch=0;
ControlData.m_inDataBuf[0]=8;
ControlData.m_inDataBuf[1]=0;
ControlData.m_inDataBuf[2]=0;
ControlData.m_inDataBuf[3]=0;
ControlData.m_inDataBuf[4]=0;
ControlData.m_inDataBuf[5]=0;
ControlData.m_inDataBuf[6]=0;
ControlData.m_inDataBuf[7]=0;
}
else
{
bEPPflags.bits.KB_KeyUpSwitch=1;
ControlData.m_inDataBuf[0]=0;
ControlData.m_inDataBuf[1]=0;
ControlData.m_inDataBuf[2]=0;
ControlData.m_inDataBuf[3]=0;
ControlData.m_inDataBuf[4]=0;
ControlData.m_inDataBuf[5]=0;
ControlData.m_inDataBuf[6]=0;
ControlData.m_inDataBuf[7]=0;
}
ControlData.wLength=MAX_DATA_IN_SIZE;
ControlData.wCount=0;
ControlData.pData=(u8*)&ControlData.m_inDataBuf[0];
}
[/code]
4、在中断端点向主机发送如下数据
[code=cpp] if(bEPPflags.bits.KB_KeyUp)
{
bEPPflags.bits.FIFO_WR=1;
bEPPflags.bits.ep1_test=1;
bEPPflags.bits.KB_KeyUp=0;
UsbSendDatum(1);
}[/code]
5、产生的效果是输出h字母,持续1.5s,停1.5s;后面跟着持续1.5s输出h字母;
不知道为什么?
|
|