zoologist 发表于 2015-6-22 09:54:29

Arduino 控制USB设备(2)硬件测试篇

这篇文章目标是让你知道你买的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设备。



最后,三个修改后的完整代码可以在这里下载:




经过上述测试,可以确定你的板子没问题。

suoma 发表于 2015-6-23 18:35:34

谢谢分享学习一下

小叉 发表于 2015-9-13 19:18:50

支持一下 在看lz 的Arduino 控制USB设备系列
页: [1]
查看完整版本: Arduino 控制USB设备(2)硬件测试篇