混淆输出到控制台,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 库中有很多示例
我有一个问题,可能是我这边的一个简单误解。 我有一个带有 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 库中有很多示例