这篇文章目标是让你知道你买的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 后面看看。
我可以問一下嗎 因為前兩步都沒有問題
到第三步他卻無法做使用 電壓量了事輸出5.06V
你说的是这个芯片的供电电压是 5v吗? 这个芯片只能吃 3.3V 的电,另外 spi 信号线也都必须是 3.3v的
我是說他輸出到要檢測的東西上面時電壓輸出正常但是就是無法檢測有東西輸入到USB Host Shield 裡面
如果可以的話我可以加一下您的聯絡方式嗎
可以的話
dc:luo_yu_bin_xin
你直接给我写邮件吧,带上照片 2925059@qq.com
我是接在arduino uno版上的
Max.powerOn();第一个代码这里编译错误!
这篇文章用的是老的USB Host Shield库,现在的库已经是 2.0 了,和之前的代码不兼容。