This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CCS/TM4C123GH6PM:发送/接收 USB 消息。

Guru**** 2442090 points
Other Parts Discussed in Thread: TM4C123GH6PM

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/612353/ccs-tm4c123gh6pm-send-recieve-usb-messages

器件型号:TM4C123GH6PM

工具/软件:Code Composer Studio

您好!

我正在尝试使用 TM4C123GH6PM 创建一个小应用、目前使用的是 LaunchPad、但一旦程序完成、我将把设计变成单个 PCB。

因此、我要尝试的是、通过 USB 从 PC 向电路板发送一些线路、 它应该识别命令、执行它并回显 OK 或错误代码。  

命令如下所示:  

  • Rxxx
  • LXXX
  • Zxxx
  • Txxx
  • 等等

X-s 表示数字时、始终为3位数字。  

到目前为止、我已设法修改 USB_DEV_BULK、我已更改部件 "EchoNewDataToHost"

静态 uint32_t
EchoNewDataToHost (tUSBDBulkDevice * psDevice、uint8_t * pui8Data、
uint32_t ui32NumBytes)
{
uint32_t ui32Loop、ui32Space、ui32Count;
uint32_t ui32ReadIndex;
uint32_t ui32WriteIndex;
tUSBRingBufObject sTxRing;

//
//获取当前缓冲区信息,以便我们直接写入
//发送缓冲区(我们已经从中获得了足够的信息
//直接访问接收缓冲区的参数)。
//
USBBufferInfoGet (&g_sTxBuffer、&sTxRing);

//
//传输缓冲区中有多少空间?
//
ui32Space = USBBufferSpaceAvailable (&g_sTxBuffer);

//
//我们可以处理这一整段时间的字符数?
//
ui32Loop =(ui32Space < ui32NumBytes)? ui32Space:ui32NumBytes;
ui32Count = ui32Loop;

//
//更新接收计数器。
//
G_ui32RxCount += ui32NumBytes;

//
//转储调试消息。
//
debug_print ("接收到的%d 字节\n"、ui32NumBytes);

//
//设置为通过直接访问 USB 缓冲区来处理字符。
//
ui32ReadIndex =(uint32_t)(pui8Data - g_pui8USBRxBuffer);
ui32WriteIndex = sTxRing.ui32WriteIndex;

while (ui32Loop)
{
//
//从接收缓冲区复制到发送缓冲区转换
//途中出现字符大小写。
//

//
//这是小写字符吗?
//
if ((g_pui8USBRxBuffer[ui32ReadIndex]='L')
{
GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_3、GPIO_PIN_3);
UARTprintf (“左”);

}
否则、if ((g_pui8USBRxBuffer[ui32ReadIndex]='R')
{
GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_2、GPIO_PIN_2);
UARTprintf (" right ");

}
其他
{

GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_3、0);
GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_2、0);
//
//这是大写字符吗?
//
if ((g_pui8USBRxBuffer[ui32ReadIndex]>='a')&&
(G_pui8USBRxBuffer[ui32ReadIndex]<='Z')
{
//
//转换为小写并写入发送缓冲区。
//
G_pui8USBTxBuffer[ui32WriteIndex]=
(g_pui8USBRxBuffer[ui32ReadIndex]-'Z')+'z';
}
其他
{
//
//将接收到的字符复制到发送缓冲区。
//
G_pui8USBTxBuffer[ui32WriteIndex]=
G_pui8USBRxBuffer[ui32ReadIndex];
}
}

//
//移动到下一个字符,注意调整指针
//必要时缓冲区换行。
//
ui32WriteIndex++;
ui32WriteIndex =(ui32WriteIndex == bulk_buffer_size)?
0:ui32WriteIndex;

ui32ReadIndex++;
ui32ReadIndex =(ui32ReadIndex == bulk_buffer_size)?
0:ui32ReadIndex;

ui32loop--;
}

//
//我们已对数据进行处理,因此现在发送已处理的数据
//返回到主机。
//
USBBufferDataWritten (&g_sTxBuffer、ui32Count);

debug_print ("写入%d 个字节\n"、ui32Count);

//
//我们处理了尽可能多的直接来自接收缓冲区的数据
//我们需要返回允许较低层的字节数
//适当地更新其读取指针。
//
return (ui32Count);
} 

现在,我知道程序将前两条命令分开,但我想请您在以下方面提供帮助:

  • 如何获取命令后的接下来3位数字
  • 如何将这3个数字作为数字(int s)
  • 如何轻松回显字符串(UARTprintf 或其他内容)

感谢您的帮助!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您的问题是非常通用的 C 问题。 要访问字母后发送的三位数字,只需将索引递增到接收缓冲区即可。 有多种方法可以将三个 ASCII 数字转换为数字。 可以使用 sscanf()或 atoi()。

    #include 
    

    if ((g_pui8USBRxBuffer[ui32ReadIndex]='L')
    {
    GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_3、GPIO_PIN_3);
    UARTprintf (“左”);
    值= atoi ((char *) g_pui8USBRxBuffer+ui32ReadIndex+1U);
    
    }
    

    您可以使用 sprintf()创建字符串以发回。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Bob、您好!

    感谢您的参与、我在 C 语言中不是很专业、老实说、在我等待管理员打开该主题时、我想说以下几句:

    if ((g_pui8USBRxBuffer[ui32ReadIndex]='L')
    {
    ui32ReadIndex++;
    ui32ReadIndex =(ui32ReadIndex == bulk_buffer_size)?
    0:ui32ReadIndex;
    GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_3、GPIO_PIN_3);
    UARTprintf (“左”);
    char buffer[3];
    uint32_t i;
    对于(i = 0;i<3;i++){
    Buffer[i]= g_pui8USBRxBuffer[ui32ReadIndex];
    ui32ReadIndex++;
    ui32ReadIndex =(ui32ReadIndex == bulk_buffer_size)?
    0:ui32ReadIndex;
    }
    number = atoi ((char *) buffer);
    UARTprintf ("\n %I"、编号);
    for (i = 0;i < sizeof (buffer);i++)
    {
    G_pui8USBTxBuffer[ui32WriteIndex]= buffer[i];
    ui32WriteIndex++;
    ui32WriteIndex =(ui32WriteIndex == bulk_buffer_size)?
    0:ui32WriteIndex;
    }
    
    
    
    } 

    这基本上是相同的。  

    我已经用 sprintf 尝试了您的技巧、出现了以下情况:

    代码:  

    if ((g_pui8USBRxBuffer[ui32ReadIndex]='C')
    {
    
    GPIOPinWrite (GPIO_PORTF_BASE、GPIO_PIN_2、GPIO_PIN_2);
    UARTprintf ("命令");
    uint32_t 值;
    valueec = atoi ((char *) g_pui8USBRxBuffer+ui32ReadIndex+1U);
    UARTprintf ("\n %i"、valueec);
    
    switch (valueec){
    案例100:
    //todo
    sprintf (g_pui8USBTxBuffer、"command OK");
    中断;
    
    默认值:
    sprintf (g_pui8USBTxBuffer、"无效命令");
    中断;
    
    }
    
    
    
    } 

    我通过示例 USB 应用程序发送以下消息:“C101”我得到的响应是:“I101”?!?!

    因此、我怀疑原始代码的剩余部分可能会在那里进行一些更改、这会导致这个问题。

    现在、我收到4个字符长的消息

    C101 ->"INVA" - 命令无效

    C100 ->"and "- 命令 OK

    C101 ->"COMM"-命令无效

    对此、有何权变措施?  

    每次刷新 TX 缓冲区并发送整个缓冲区。 我想。

    //
    //我们已对数据进行处理,因此现在发送已处理的数据
    //返回到主机。
    //
    USBBufferDataWritten (&g_sTxBuffer、ui32Count); 

    并将 ui32Count 替换为缓冲区长度...、但以下内容不起作用:

    //
    //我们已对数据进行处理,因此现在发送已处理的数据
    //返回到主机。
    //
    USBBufferDataWritten (&g_sTxBuffer、sizeof (g_pui8USBTxBuffer[bulk_buffer_size]); 

    也许我会从 C 程序的角度提出一些愚蠢的问题、但通信的另一面将是 C#、这使得事情变得更加容易。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我在这里提到的 AZ e2e.ti.com/.../2258704 发送回消息有一些错误。 “使用 sprintf()”在我看来不是一个解决方案。