基于LUFA的AT90USB162 USB字节接收问题:输出无限FF
问题:LUFA虚拟串口回显时无限输出FF字符
我基于LUFA的VirtualSerial示例(路径/Demos/Device/ClassDriver/VirtualSerial/)修改了代码,移除了摇杆、LED相关冗余代码,只保留核心虚拟串口功能。现在微控制器能被电脑识别,串口终端可以显示“Byte received: ”,但配置回显发送字符时,即使没有发送字符,终端也会无限输出FF。
问题代码
#include "VirtualSerial.h" USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface = { .Config = { .ControlInterfaceNumber = INTERFACE_ID_CDC_CCI, .DataINEndpoint = { .Address = CDC_TX_EPADDR, .Size = CDC_TXRX_EPSIZE, .Banks = 1, }, .DataOUTEndpoint = { .Address = CDC_RX_EPADDR, .Size = CDC_TXRX_EPSIZE, .Banks = 1, }, .NotificationEndpoint = { .Address = CDC_NOTIFICATION_EPADDR, .Size = CDC_NOTIFICATION_EPSIZE, .Banks = 1, }, }, }; /** Standard file stream for the CDC interface when set up, so that the virtual CDC COM port can be * used like any regular character stream in the C APIs. */ static FILE USBSerialStream; int main(void) { SetupHardware(); /* Create a regular character stream for the interface so that it can be used with the stdio.h functions */ CDC_Device_CreateStream(&VirtualSerial_CDC_Interface, &USBSerialStream); GlobalInterruptEnable(); for (;;) { /* Must throw away unused bytes from the host, or it will lock up while waiting for the device */ CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface); char echo = 0; echo = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface); if(echo) { fprintf(&USBSerialStream, "Byte received: %c\n\r", echo); } CDC_Device_USBTask(&VirtualSerial_CDC_Interface); USB_USBTask(); // fputs("hello\n\r", &USBSerialStream); } } /** Configures the board hardware and chip peripherals for the demo's functionality. */ void SetupHardware(void) { #if (ARCH == ARCH_AVR8) /* Disable watchdog if enabled by bootloader/fuses */ MCUSR &= ~(1 << WDRF); wdt_disable(); /* Disable clock division */ clock_prescale_set(clock_div_1); #endif /* Hardware Initialization */ USB_Init(); } /** Event handler for the library USB Connection event. */ void EVENT_USB_Device_Connect(void) { } /** Event handler for the library USB Disconnection event. */ void EVENT_USB_Device_Disconnect(void) { } /** Event handler for the library USB Configuration Changed event. */ void EVENT_USB_Device_ConfigurationChanged(void) { bool ConfigSuccess = true; ConfigSuccess &= CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface); } /** Event handler for the library USB Control Request reception event. */ void EVENT_USB_Device_ControlRequest(void) { CDC_Device_ProcessControlRequest(&VirtualSerial_CDC_Interface); } /** CDC class driver callback function the processing of changes to the virtual * control lines sent from the host.. * * \param[in] CDCInterfaceInfo Pointer to the CDC class interface configuration structure being referenced */ void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t *const CDCInterfaceInfo) { /* You can get changes to the virtual CDC lines in this callback; a common use-case is to use the Data Terminal Ready (DTR) flag to enable and disable CDC communications in your application when set to avoid the application blocking while waiting for a host to become ready and read in the pending data from the USB endpoints. */ bool HostReady = (CDCInterfaceInfo->State.ControlLineStates.HostToDevice & CDC_CONTROL_LINE_OUT_DTR) != 0; }
现象
串口终端持续输出包含FF的“Byte received: ”内容,即使未向设备发送任何字符。
解决方案
问题根源
CDC_Device_ReceiveByte的返回值为int类型:成功接收数据时返回字节值(0-255),无数据时返回-1(对应十六进制0xFFFFFFFF,截断为char类型时会变成0xFF)。- 代码中用
char类型接收返回值,且判断条件if(echo)会把0xFF(有符号char为-1)判定为非零,触发无限输出。 - 重复调用
CDC_Device_ReceiveByte会丢弃主机发送的第一字节数据。
修复后的main函数代码
int main(void) { SetupHardware(); CDC_Device_CreateStream(&VirtualSerial_CDC_Interface, &USBSerialStream); GlobalInterruptEnable(); for (;;) { // 用int类型接收,正确区分无数据(-1)和有效字节0xFF(255) int echo = CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface); // 仅当接收到有效数据时执行回显 if(echo != -1) { fprintf(&USBSerialStream, "Byte received: %c\n\r", (char)echo); } CDC_Device_USBTask(&VirtualSerial_CDC_Interface); USB_USBTask(); } }
修复说明
- 改用
int类型接收返回值,避免将“无数据”标识误判为有效字符。 - 移除多余的
CDC_Device_ReceiveByte调用,防止丢失主机数据。 - 调整判断条件为
echo != -1,仅在真正接收到数据时触发输出,解决无限循环输出FF的问题。
内容的提问来源于stack exchange,提问作者piro-s
相关产品推荐
相关产品推荐

