AVR-C:可以成功检测到USB连接,而不是USB断开连接
它在ATMega32U4 MCU上工作正常,但是.....当电池供电时,它无法检测到与USB断开连接。它可以检测到重新连接(false),并在此之后成为真实状态,但不会断开连接。AVR-C:可以成功检测到USB连接,而不是USB断开连接
例如:
bool TEnjoyPad::isUSBConnected()
{
#if defined(UDADDR) && defined(_BV) && defined(ADDEN)
//setDelay(1000);
Serial1.println("--------");
Serial1.println(UDADDR & _BV(ADDEN), HEX);
//Serial1.println(UDADDR, HEX); // 97 or 98 hex
//Serial1.println(_BV(ADDEN), HEX);
return (UDADDR & _BV(ADDEN));
#else
return false;
#endif
}
当你看看行:
Serial1.println(UDADDR & _BV(ADDEN), HEX);
它打印:
Connected: 0x80 (function result = true)
Not connected: 0x00 (function result = false)
它可以探测到这一变化,从没有连接到连接但未连接到未连接(断开连接)。
有没有简单的解决方案呢?
编辑13十月2017年:
只是弄清楚这一点,它的工作原理却并非总是如此。在这里找到它: http://forum.arduino.cc/index.php?topic=28567.0
它是UDINT寄存器,它连接时报告16十进制(0x10十六进制)。
修改以上这个函数的第一个版本的版本:
bool TEnjoyPad::isUSBConnected()
{
#if defined(UDADDR) && defined(_BV) && defined(ADDEN) && defined(UDINT) && defined(USBCON)
return ((UDADDR & _BV(ADDEN)) && (UDINT));
#else
return false;
#endif
}
它的工作原理但是只有当这些条件都满足:
- Device is connected to computer, phone etc
- Device is disconnected from computer, phone etc
如果使用例如一个USB蓄电池组,它会报告真实的,有些电池组断开时,状态仍然为真。公交车很困惑?当你再次连接到计算机,电话等时,它报告错误,然后是真实的,当断开连接时,它报告错误(它应该)。
任何想法?与建筑USB数据线有什么关系?
在这个例子中,他们使用这一行。它不会有所作为,我当我说的:
USBCON = USBCON | B00010000;
编辑14十月2017年:
感谢@ralph HTP,请参阅下面我发布的答案,也许它可以帮助别人。
最后,它作品完美无瑕,感谢“@ralf htp”。他正确USBSTA
寄存器更改为1
连接到USB和0
时,未连接。你必须include pins_arduino.h
否则寄存器是未知的。所以这使得检测USB电源状态非常容易。
但是,当您想知道USB总线的状态,数据线是否连接,建立连接时,它会稍微复杂一些。当MCU需要作为USB HID设备运行时,您需要知道USB连接已建立。
我不知道这是一个错误或只是方式USB作品,USB设备的地址由MCU保存,即使设备断开或连接到一个USB蓄电池组。一些寄存器甚至在“无效”状态下保持它们的值。
但是,建立连接时地址会发生变化。因此可以确定存在真正的连接,建立连接,MCU可以被USB主机识别。
以我下面的代码我可以检测:
- 它被连接到外部USB电源;
- 建立数据连接,设备被识别与否;
- 结合这些事情很容易弄清楚它是如何供电和/或连接。
现在您可以决定设备功能是否可用,或者向用户报告设备的状态。
我的更新代码如下所示:
// enjoypad.h
#include <pins_arduino.h> // Required to access some register defines
..........
..........
..........
// Via pins_arduino.h => defined in avr/iom32u4.h
#ifdef USBSTA
#define TEP_USB_VBUS_CONNECTED (USBSTA == 3)
#define TEP_USB_VBUS_DISCONNECTED (USBSTA == 2)
#endif
#ifdef UDADDR
#define TEP_USB_ADDRESS (isOnUSBPower()?UDADDR:0)
#endif
#if defined(ADDEN) && defined(UDINT)
#define TEP_USB_ADDRESS_ESTABLISHED (_BV(ADDEN)== 0x80 && UDINT > 0)
#endif
..........
..........
..........
// enjoypad.cpp
uint8_t TEnjoyPad::getUSBaddress()
{
#ifdef TEP_USB_ADDRESS
return TEP_USB_ADDRESS;
#else
return 0;
#endif
}
bool TEnjoyPad::isOnUSBPower()
{
#ifdef TEP_USB_VBUS_CONNECTED
return TEP_USB_VBUS_CONNECTED;
#else
return false;
#endif
}
bool TEnjoyPad::isUSBDataEstablished()
{
#ifdef TEP_USB_ADDRESS_ESTABLISHED
static uint8_t iLastAddress = 0;
static uint8_t bUSBDataEstablished = false;
// The address changes from 0 to something (byte) or increases
// with one each time you plugin the device, when this is an USB host.
// If the VBUS not connected, it returns always 0 (zero)
uint8_t iAddress = getUSBaddress();
if(iAddress > 0)
{
//Serial1.println(_BV(ADDEN), HEX);
//Serial1.println(UDINT, HEX);
if(TEP_USB_ADDRESS_ESTABLISHED)
{
//Serial1.println(iAddress);
// Need update? On USB Battery for example, address stays the same
// so it never perform an update and never reports there is a
// data connection established.
if(iAddress != iLastAddress)
{
bUSBDataEstablished = true;
iLastAddress = iAddress;
}
}
}
else { bUSBDataEstablished = false; }
return bUSBDataEstablished;
#else
return false;
#endif
}
bool TEnjoyPad::isOnUSBPowerBattery() // Or something else providing power
{ return (isOnUSBPower() && !isUSBDataEstablished()); }
bool TEnjoyPad::isOnBatteryPower()
{ return !isOnUSBPower(); }
在行动:-)代码:
在第261页和279页的数据表中说有VBUSTI
中断为USB插入删除。有一个在LUFA堆(EVENT_USB_Host_DeviceUnattached()
如果在主机模式和EVENT_USB_Device_Disconnect()
如果在设备模式)的实施
编辑
仅在USB设备模式中有效:
如果您想要检测是否连接或分离纯电压源(如电池模块),您可以使用VBUS
(电压总线)焊盘。其状态可以在USBSTA
(USB状态)在VBUS
位/标志进行访问,这是第268
做到这一点渔获VBUSTI
中断,每当发生中断检查VBUS
位/对数据表国旗在USBSTA
注册。如果VBUS
为高(1)的电池附接(在VBUS
焊盘电压是> 1.4 V,数据表页面265),如果它是低电池未连接(上VBUS焊盘电压是< 1.4V)
海,感谢您的答案,但没有按链接” t工作:404他发生以下错误: 未找到请求的URL o在这台服务器上。 请检查网址或与网站管理员联系。 – Codebeat
固定链接和LUFA堆栈在设备和主机模式下有不同的功能... –
谢谢,我看看它,但没有导致解决方案,至少不适合我。另请参阅我在我的问题编辑。 – Codebeat