这篇文章目标是让你知道你买的USB Host Shield能否正常工作。
我们要运行一段代码来确保板子工作正常。从经验的角度来看,这个非常必要,对于很多卖家来说,板子之间的差别只有进货价格的高低,他们对于质量一无所知。
下面例子中的代码来自 http://www.circuitsathome.com/mcu/arduino-usb-host-part-2-classes
第一个代码是测试SPI通信是否正常
/* MAX3421E USB Host controller SPI test */ /* This sketch tests SPI communication between Arduino and MAX3421E USB host controller */ #include <spi.h> #include "max3421e.h" void setup(); void loop(); byte i; byte j = 0; byte gpinpol_copy; MAX3421E Max; void setup() { Serial.begin( 9600 ); Max.powerOn(); delay(200); } void loop() { gpinpol_copy = Max.regRd( rGPINPOL ); Serial.println("SPI test. Each '.' indicates 64K transferred. Press any key to stop."); while( Serial.available() == 0 ) { for( i = 0; i < 255; i++ ) { Max.regWr( rGPINPOL, i ); if( Max.regRd( rGPINPOL ) != i ) { Serial.println("SPI transmit/receive mismatch"); } }//for( i = 0; i < 255; i++ j++; if( j == 0 ) { Serial.print("."); } }//while( Serial.available() == 0 Max.regWr( rGPINPOL, gpinpol_copy ); Serial.println("\r\nStopped."); while( 1 ); //stop here }
运行结果
下面这个代码测试的是 MAX3421E 寄存器是否正常
/* This sketch dumps MAX3421E registers */ #include <spi.h> #include "max3421e.h" MAX3421E Max; //MAX3421E instance /* Regiser names/numbers for MAX3421E register dump */ typedef struct { const char* name; char number; } REGISTER_OUTPUT; REGISTER_OUTPUT max_register[] = { { "\r\nRCVFIFO:\t", rRCVFIFO }, { "\r\nSNDFIFO:\t", rSNDFIFO }, { "\r\nSUDFIFO:\t", rSUDFIFO }, { "\r\nRCVBC:\t", rRCVBC }, { "\r\nSNDBC:\t", rSNDBC }, { "\r\nUSBIRQ:\t", rUSBIRQ }, { "\r\nUSBIEN:\t", rUSBIEN }, { "\r\nUSBCTL:\t", rUSBCTL }, { "\r\nCPUCTL:\t", rCPUCTL }, { "\r\nPINCTL:\t", rPINCTL }, { "\r\nREVISION:\t", rREVISION }, { "\r\nIOPINS1:\t", rIOPINS1 }, { "\r\nIOPINS2:\t", rIOPINS2 }, { "\r\nGPINIRQ:\t", rGPINIRQ }, { "\r\nGPINIEN:\t", rGPINIEN }, { "\r\nGPINPOL:\t", rGPINPOL }, { "\r\nHIRQ:\t", rHIRQ }, { "\r\nHIEN:\t", rHIEN }, { "\r\nMODE:\t", rMODE }, { "\r\nPERADDR:\t", rPERADDR }, { "\r\nHCTL:\t", rHCTL }, { "\r\nHXFR:\t", rHXFR }, { "\r\nHRSL:\t", rHRSL } }; void setup() { Serial.begin( 9600 ); Max.powerOn(); } void loop() { unsigned char i; unsigned char numregs = sizeof( max_register )/sizeof( REGISTER_OUTPUT); for( i = 0; i < numregs; i++ ) { Serial.print( max_register[ i ].name); print_hex( Max.regRd( max_register[ i ].number ), 8 ); } while(1); } /* prints hex numbers with leading zeroes */ // copyright, Peter H Anderson, Baltimore, MD, Nov, '07 // source: http://www.phanderson.com/arduino/arduino_display.html void print_hex(int v, int num_places) { int mask=0, n, num_nibbles, digit; for (n=1; n<=num_places; n++) { mask = (mask << 1) | 0x0001; } v = v & mask; // truncate v to specified number of places num_nibbles = num_places / 4; if ((num_places % 4) != 0) { ++num_nibbles; } do { digit = ((v >> (num_nibbles-1) * 4)) & 0x0f; Serial.print(digit, HEX); } while(--num_nibbles); }
运行结果
下面这个代码测试的是 USB 当前状态
/* MAX3421E interrupt loop */ #include <spi.h> #include "max3421e.h" MAX3421E Max; byte rcode; byte vbus_state; void setup() { Serial.begin( 9600 ); Serial.println("Start"); Max.powerOn(); } void loop() { Max.Task(); print_vbus_state(); } void print_vbus_state( void ) { char* vbus_states[] = { "Disconnected", "Illegal", "Full speed", "Low speed" }; byte tmpbyte; static byte last_state = 4; tmpbyte = Max.getVbusState(); if( tmpbyte != last_state ) { last_state = tmpbyte; Serial.println( vbus_states[ tmpbyte ] ); } return; }
刚开始没有插任何设备,显示为 Disconnected 状态。之后插入一个USB鼠标,识别为Low Speed设备。拔掉之后再插入两个不同的U盘,因为IC本身不支持High Speed,所以都显示为Full Speed设备。
最后,三个修改后的完整代码可以在这里下载:
经过上述测试,可以确定你的板子没问题。
楼主您好,我用这三个程序测试,前两个都没问题,第三个当我插一个双飞燕的有线鼠标的时候它开始没反应,过会出现Disconnected 和 Full speed 之间来回跳,然后我换了一个罗技的无线鼠标的接收器插上去就只稳稳的一个Full speed,这说明有线鼠标带不动吗?还是说这个牌子的鼠标有问题呢?
双飞燕的我还真没测试过,有可能是供电不足,你检查一下电压看看?
另外,你可以试试把有问题的鼠标放在独立供电的 USB Hub 后面看看。
Max.powerOn();第一个代码这里编译错误!
这篇文章用的是老的USB Host Shield库,现在的库已经是 2.0 了,和之前的代码不兼容。