混淆输出到控制台,C / USB CDC / PIC18F2550

Confused with output to console, C / USB CDC / PIC18F2550

我有一个问题,可能是我这边的一个简单误解。 我有一个带有 USB CDC 固件的 PIC18F2550 设备。我想向它发送一个命令,每秒向控制台输出一些东西。但是,它似乎不起作用。我放入一个循环以迭代 5 秒并每秒显示一条输出消息,但它实际上不会输出任何内容。它通过 5 秒的循环,直到它在循环执行后显示最终消息的结尾。它不会在循环期间输出任何内容。

我包含了我的整个 ProcessIO 函数,因为我认为它对这个问题很重要,但我评论了我放置我试图找出的确切命令的位置。

感谢你们的任何建议,我很感激。我是一名机械工程师,正在尝试学习一些嵌入式的东西。

/********************************************************************
* Function:        void ProcessIO(void)
* Overview:        This function is a place holder for other user
*                  routines. It is a mixture of both USB and
*                  non-USB tasks.
*******************************************************************/
void ProcessIO(void)
{
BYTE numBytesRead;

// User Application USB tasks
if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return;

if (USBUSARTIsTxTrfReady())
{
    if((CDCattached == 0x01) && (CDCattachedcount == 2))
    {
        putUSBUSART((char*)"Text Message\r\n",49);
        CDCTxService();
        CDCattachedcount = 0;
        CDCattached = 0x00;
    }
    numBytesRead = getsUSBUSART(USB_Out_Buffer, 64);
    if (numBytesRead == 1)
    {
        if ((USB_Out_Buffer[0] == '\r'))                      //Received ENTER? Ues-> End of Command
        {
            if (pos >0)
            {
                command_recvd = 0x01;
                Command[pos++] = '[=10=]';
                pos = 0;
            }
        }
        else if ((USB_Out_Buffer[0] == 0x7F) || (USB_Out_Buffer[0] == 0x08))
        {
            if (pos > 0) pos--;
            Command[pos] = '[=10=]';
            putUSBUSART ((char*) USB_Out_Buffer, 1);
        }
        else
        {
            Command[pos++] = USB_Out_Buffer[0];
            putUSBUSART((char*) USB_Out_Buffer, 1);
            Command[pos]='[=10=]';
        }       //No:- Store Character to String
    }
    else if ((numBytesRead > 1))
    {
        strncpy(Command,USB_Out_Buffer,numBytesRead);
        for(int indx = numBytesRead; indx < 64; indx++)
        {
            Command[indx]='[=10=]';
        }
        pos = numBytesRead--;
        command_recvd = 0x01;
        Command[pos++] = '[=10=]';
        // putUSBUSART((char*) USB_Out_Buffer, 1);
        pos = 0;
    }

    if (command_recvd == 0x01)
    {
        for (int aaa = 0; aaa <= 63; aaa++)
        {
            output_message[aaa]= '[=10=]';
        }


************** THIS IS WHERE MY TEST COMMAND IS ***************

        if (strnicmp((char*) Command, (char*) "test", 4) == 0)
        {
            sprintf(output_message, "\r\nStarting loop...\r\n");
            for int bbb = 0; bbb < 5; bbb++)
            {
                sprintf(output_message, "\r\nLooping...\r\n");
                for (delayIndex = 0; delayIndex < 1000; delayIndex++)
                {
                     __delay_ms(1);
                }
            }
            sprintf(output_message, "\r\nLoop finished!\r\n");
        }
        else
        {
            invalidCommand:
            sprintf(output_message, "\r\nInvalid Command Received. Please Retry.\r\n[=10=]");
        }
        command_recvd = 0x00;
    }
}
CDCTxService();
}

简短版本:此方法行不通。你需要重新考虑你是如何做的。

USB 设备在处理事件时不能延迟——它们必须能够迅速响应主机发送的每个请求。延迟一秒钟通常会导致主机假定设备已断开连接。

了解 USB 设备模型(几乎)完全基于主机向设备发送请求,然后设备回复,这一点很重要。设备无法生成未经请求的响应。

现在,您在这里看不到预期结果的原因是 sprintf() 没有将结果发送到主机;它所做的只是将一条消息放入缓冲区,准备 将其发回。多次调用它会覆盖该缓冲区,而不是发回多条消息。

您应该在覆盖 output_message 之前调用 putUSBUSART()CDCTxService() 还有,CDCTxService()需要经常调用,所以要在延迟循环的时候调用。

        for int bbb = 0; bbb < 5; bbb++)
        {
            sprintf(output_message, "\r\nLooping...\r\n");
            putsUSBUSART(output_message);

            for (delayIndex = 0; delayIndex < 1000; delayIndex++)
            {
                 __delay_ms(1); 

                 if(USBUSARTIsTxTrfReady()) {
                      sprintf(output_message, "\r\nInside inner loop\r\n");
                      putsUSBUSART(output_message);
                 }
                 CDCTxService();
            }
        }

尽管这种阻塞延迟可能有效(__delay_ms()),但更好的方法是检查超时计时器或时间戳。类似于:

        for int bbb = 0; bbb < 5; bbb++)
        {
            sprintf(output_message, "\r\nLooping...\r\n");
            putsUSBUSART(output_message);

            timestamp = TickGet(); 
            while (TickDiff(timestamp, TickGet()) < TICK_SECOND)
            {
                 if(USBUSARTIsTxTrfReady()) {
                      sprintf(output_message, "\r\nInside inner loop\r\n");
                      putsUSBUSART(output_message);
                 }
                 CDCTxService();
            }
        }

TickGet 和 TickDiff 是您必须自己实现的函数,但是 Microchip 库中有很多示例