自己搞AVR-USB的开发已经是第五天了,现学现卖,网上的资料似多非多:源代码很多、USB规范很多,但是这么多东西,都很长、枯涩,这么几天能看懂、理解的东西微乎其微。
自己的目标很明确,做一下HID摇杆。我首先去大概浏览了如下资料:
USB1.1 Specification,USB in a Nutshell和AVR309三个文档
这样,自己对USB的工作原理有了一个了解(没能细看,特别是USB1.1规范。刚才看了一个人学习USB的过程,他花了两、三个月才能把它消化掉。USB in a Nutshell是一本非常不错的入门书)。
之后我下载了PowerSwitch。看了一下代码,根据自己的情况修改了一下(我用的是atmega8),编译,Flash——OK,成功在自己的板子上运行了。
然后发现,PS并不适合自己,它没有使用标准的驱动程序,和我做的东西并不一样。然后我就下载了HID Keys代码——这个接近我的目标了!同样修改、编译,Flash——错误!
仔细看资料,看我的电路板和他使用的电路板——原来我们使用的电路不是很一样。HIDKeys使用的是PORTD的PD0和PD2脚,而我的电路(是根据另一个项目作的电路板)使用的是PB0,PB1,PB2和PD2四个引脚。
为什么它的电路使用两个口而我的使用四个口呢?
首先,USB数据接口的D+和D-两个接口对应在单片机上,必须是同一个端口。这里,HIDKeys使用PD0接D-,PD2接D+,作为数据口。而我的电路则使用PB0接D-,PB1接D+,同时D+接在PD2上。
PD2在单片机为外部中断INT0的接口,接在D+,AVR-USB程序使用INT0作为USB事件外部中断(具体的代码我没有看,我分析是这样的)。
那我的PB2是作什么用的呢?根据USB规范,在D-上接一个1K5的电阻,可以控制USB设备的连接和卸载。我这个电路上,PB2就是通过一个2K2的电阻接在D-上,控制设备连接。
电路连接不同,那么反映在程序中也不同。AVR-USB在usbconfig.h文件有所定义:
/* ---------------------------- Hardware Config ---------------------------- */
#define USB_CFG_IOPORTNAME B
#define USB_CFG_DMINUS_BIT 0
#define USB_CFG_DPLUS_BIT 1
#define USB_CFG_PULLUP_IOPORTNAME B
#define USB_CFG_PULLUP_BIT 2
宏的功能可以顾名思义了。
最后两行是选填的。根据你的电路,可以注释掉。
当你选用了这一个控制用的上拉电阻以后,你还需要在USB初始化代码之后、循环开始之前增加一个函数:usbDeviceConnect();
这样,设备就正常连接到系统驱动了。
不过,对于HIDKeys还有许多的东西要修改的。
主要是数据处理方面。这时,我又找到了一个avr-hid项目,这两个项目相互参考。我发现avr-hid的数据处理要简单得多,我就按avr-hid的数据处理方式,把HIDKeys的修改了。
static uchar reportBuffer[1];
PROGMEM char usbHidReportDescriptor[26] = { /* USB report descriptor */
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x04, // USAGE (Joystick)
0xa1, 0x01, // COLLECTION (Application)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x01, // USAGE (Pointer)
0xa1, 0x00, // COLLECTION (Physical)
0x15, 0x0, // LOGICAL_MINIMUM (-128)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x01, // REPORT_COUNT (1)
0x09, 0x30, // USAGE (X)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0, // END_COLLECTION
0xc0 // END_COLLECTION
};
uchar usbFunctionSetup(uchar data[8])
{
usbMsgPtr = reportBuffer;
if(data[1] == 1) /* GET REPORT */
{
reportBuffer[0] = 0;
return sizeof(reportBuffer);
}
return 0;
}
int main(void)
{
wdt_enable(WDTO_1S);
hardwareInit();
odDebugInit();
usbInit();
sei();
usbDeviceConnect();
DBG1(0x00, 0, 0);
for(;;){ /* main event loop */wdt_reset();
usbPoll();
reportBuffer[0]=你需要的数据;//实际中使用ADC读取的值usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
if(TIFR & (1 << TOV0)){
TIFR |= 1 << TOV0; /* clear pending flag */
}
}
return 0;
}
这样,做的USB HID设备就可以正常在控制面板中查看了。
待续... ...
用户24183 2009-12-17 21:36
用户234759 2009-10-8 13:43
用户214947 2009-6-28 18:30
用户840673 2008-7-25 13:44
用户13991 2007-12-31 13:40
computer00 2007-9-24 10:25
兄弟,玩得不错嘛,有空也去我这里坐坐:
USB专区:http://group.ednchina.com/93/
用户1151698 2007-8-28 16:44
非常感谢楼主,希望给我发一份资料,不盛感谢.
yxw713@163.com
用户1064269 2007-5-22 20:18
我正在找RF的资料,特别是射频芯片外接的天线设计部分,请给我一份,多谢!
我的邮箱:lofeng@126.com
用户5927 2007-4-1 19:22
我的邮箱是64914502@163.com 先谢谢你了。
用户1170549 2007-3-28 20:01