EDN首页   博客首页

日志档案

发表于 2007-8-31 18:26:09

1

标签: AVR  USB  

对AVR-USB的初步研究(二)

    自己搞AVR-USB的开发已经是第五天了,现学现卖,网上的资料似多非多:源代码很多、USB规范很多,但是这么多东西,都很长、枯涩,这么几天能看懂、理解的东西微乎其微。

    自己的目标很明确,做一下HID摇杆。我首先去大概浏览了如下资料:

USB1.1 Specification,USB in a NutshellAVR309三个文档

这样,自己对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设备就可以正常在控制面板中查看了。

待续... ...

系统分类: 单片机   |   用户分类: AVR   |   来源: 原创   |   【推荐给朋友】   |   【添加到收藏夹】

    阅读(2268)    回复(3)  

投一票您将和博主都有获奖机会!

最新评论

  • computer00

    2007-9-24 10:25:56

    兄弟,玩得不错嘛,有空也去我这里坐坐:

    USB专区:http://group.ednchina.com/93/

  • Aqee

    2008-3-14 17:13:20

    你好,我也在研究AVR-USB,在网上搜到你这篇文章.其实研究目的都差不多,我是为了做一个模拟飞行用的设备,我也是模拟飞行的爱好者,呵呵! 你有兴趣的话,希望能交个朋友,一起交流. 请加我MSN:Aqee@msn.com。

  • rocky1793

    2008-7-25 13:44:17

    为什么使8MHZ晶振与PC连接不成功呢?