首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

STM32的USB多包数据传送

STM32的USB多包数据传送

因为我看到STM32的USB都没有对发送状态进行检测,当多于传送缓冲器的数据要传送时,估计就会出错了,所以找下这篇文章,但没有找到原始作者,但也在此谢过了!
STM32的多包数据传送(转贴)
SMT32F103,根据例程 Custom_HID 修改,利用 EP1  以EP_INTERRUPT  的方式发送包,
原来的例程每次发送 2 个字节,现在修改后包的长度不超过 64 字节时发送是正常的,但当
一个包长超过 64 字节时就发送失败,没有数据出来(程序没有死机),该改的地方都已经修
改了,不知道哪个地方还没有改到位,谢谢!

现 象 就 是    超 过  63   字 节 的 包 死 活 也 发 不 出 去 , 而且 发 送 包 的 大 小    还与
CustomHID_ConfigDescriptor 里面的  EP1 INendpoint  描述里包大小有关 ,没道理啊,其他
的 MCU  这地方设置为 8  照样发送 256B 以上的包。

在 Custom_HID 例程上修改了如下代码:
1.usb_proc.c  的 CustomHID_Reset()里 SetEPTxCount(ENDP1, 64);
2.关闭  DMA 中断,不让 ADC 采样后发送 EP1包
3.在 main.c 里  重复发送一个 128B的包,
   while(1){
     for(i=0;i<2;i++)
         { SetEPTxAddr(ENDP1,ENDP1_TXADDR+i*64);
       SetEPTxValid(ENDP1);      
         Delay(10000);      
         }
      }         
4.  由于一个包是 128B,最大包长是64B,所以分两次发送出来,奇怪的是所有例程发送包
时都没有查发送状态的处理,也没有找到相应的状态等待函数,这样的话,是不是出现第一
个包还没有发送完,第二个包就冲掉了第一个包的数据?
5. 所以问题很简单,就是如何发送一个多数据包,发送函数要如何写?

以下是关于这个问题的解答:
分两次发送是对的,但关键是每次发送前需要检查上次发送是否完成。

检查一个端点的发送是否结束有 2 种方法,第一种方法是当发送结束(设备收到ACK)时,有
一个发送结束中断,这个中断由 USB 库处理,并通过EP1_IN_Callback 这个回调函数交由
用户程序确认,你可以搜索一下,例子中把 EP1_IN_Callback 定义为NOP_Process,没有处
理这个回调事件。如果要用这种方法检测端点发送结束,你需要自己定义回调函数并做相应
处理。

检 测 端 点 发 送 结 束 的 另 一 个 方 法 是 查 询 这 个 端点 的 状 态 , 如 果 端 点 状 态 处 于
EP_TX_VALID,说明发送未结束,如果端点状态处于EP_TX_NAK,说明发送结束。使用
下述调用可以得到端点 1 的发送状态:
   GetEPTxStatus(ENDP1)

按照你的思路,可以使用第二种方法实现发送多个数据包的功能。

假定要发送 150 个字节的 MyBuffer,EP1 的最大包长设为 64字节。

u8 MyBuffer[150];
int packetN;
packetN = 3;
while (1) {
    if (packetN< 3) { //  有数据需要发送时置 packetN为'0'
      if(GetEPTxStatus(ENDP1) == EP_TX_NAK) {
         if (packetN == 0) { // 拷贝头 64 字节到发送缓冲区
          UserToPMABufferCopy(MyBuffer, ENDP1_TXADDR,64);
          SetEPTxCount(ENDP1, 64);
         }
         else if (packetN == 1) { // 拷贝第 2 个 64 字节到发送缓冲区
          UserToPMABufferCopy(MyBuffer+64, ENDP1_TXADDR,64);
          SetEPTxCount(ENDP1, 64);
         }
         else if (packetN == 2) { // 拷贝最后 22 字节到发送缓冲区
          UserToPMABufferCopy(MyBuffer+128, ENDP1_TXADDR,22);
          SetEPTxCount(ENDP1, 22);
         }
        packetN++;
         SetEPTxStatus(ENDP1,EP_TX_VALID);
     }
   }
    ...... // 其它操作
}
继承事业,薪火相传
返回列表