STM32的USB多包数据传送

发布者:脑电风暴最新更新时间:2020-10-29 来源: eefocus关键字:STM32  USB  多包数据传送 手机看文章 扫描二维码
随时随地手机看文章

SMT32F103,根据例程 Custom_HID 修改,利用 EP1   以 EP_INTERRUPT   的方式发送包,原来的例程每次发送 2 个字节,现在修改后包的长度不超过 64 字节时发送是正常的,但当一个包长超过 64 字节时就发送失败,没有数据出来(程序没有死机),该改的地方都已经修改了,不知道哪个地方还没有改到位,谢谢! 

 

现象就是超过63字节的包死活也发不出去,而且发送包的大小还与 

CustomHID_ConfigDescriptor 里面的EP1 IN endpoint描述里包大小有关,没道理啊,其他的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); 

         } 

      } 

      ...... //   其它操作 

 

这里使用了一个变量记录应该发送第几个数据包,当程序的其它部分准备好数据后只要设置这个变量 packetN=0,上述发送操作就会启动,程序的其它部分只需检测 packetN==3 即可知道 MyBuffer 是否已经腾空,程序的其它部分可以使用 MyBuffer 继续其它操作,注意这时数据不一定已经全部发送完毕。 

 

你的另一个问题在于这一行:SetEPTxAddr(ENDP1, ENDP1_TXADDR+i*64); 

 

ENDP1_TXADDR 是专门的发送缓冲区,它的长度是有限的,而且是每 32 位编址中只有低

16 位有效;所以需要使用函数 UserToPMABufferCopy()操作这个发送缓冲区,这个函数已经在 USB 库的手册中说明。 

 

最后一个问题是:如果你的程序中使用了 ENDP1_RXADDR,因为你改变了 ENDP1 包的长

度,即改变了发送缓冲区的长度,需要在 usb_conf.h 中重新定义以下 ENDP1_RXADDR 的

地址。 

 

//、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

下面是我的部分程序 是在官方 USB模拟串口程序上改的,专门用于测试发送状态下连续发送数据

u8 my_string[]={"2013我们希望rn"};

u16   myint=0;

inc_my_string()

{

myint++;

if(myint>9999)myint=0;

my_string[0]=myint/1000+'0';

my_string[1]=(myint00)/100+'0';

my_string[2]=(myint0)/10+'0';

my_string[3]=(myint)+'0';

}

//通过电脑发送的数据在EP3_OUT_Callback中可以获取到

//发向电脑的数据可以在USB_Send_Data函数中传送

int main(void)

{

   Init_System();//系统初始化  

   Set_USBClock();//设置USB时钟

   USB_Interrupts_Config(); //配置USB中断

   USB_Init();//初始化USB  

   while (1)

   {

if (GetEPTxStatus(ENDP1) != EP_TX_VALID) 

//奇怪,我把这句换成if(GetEPTxStatus(ENDP1)== EP_TX_NAK)就会漏掉一些递增的数据 搞不懂?没时间深究

                  {

                  inc_my_string();

                  USB_Send_Data(my_string,14);//发送递增计数 看模拟的串口数据有没有漏掉的

}

}

}


关键字:STM32  USB  多包数据传送 引用地址:STM32的USB多包数据传送

上一篇:学习笔记----stm32的usb外设概述
下一篇:STM32 usb_prop.c文件分析与usb_core.h一些数据定义分析

推荐阅读最新更新时间:2024-11-07 04:04

USB电源适配器电路的保护解决方案
  从苹果手机的USB电源适配等为代表的小型化适配器越来越受人亲睐,越来越多的电路元器件的SMD小型化封装让以往常见的电源充电器能够做到更加的小巧玲珑,集美观与便携于一体。 本文从内部电路重要的安规器件--保险丝的应用角度,说明AEM科技推出的创新型SMD 250VAC  FUSE--MF2410系列 适应潮流,如何布局在这类小尺寸AC/DC电源适配器 上的交流应用,并如何做到我们倡导的“该断时及时断,不该断是不能断,时时保障安全!”的要求呢。   作为一款UMF通用模块型保险丝,必须让工程师在设计初考虑满足下述要求。   一、结构上最大限度满足小尺寸电源适配器对器件的小体积要求   以USB power Adapte
[嵌入式]
IR-UWB通信系统高速USB接口的设计与实现
  IR-UWB(Ultra Wide Band Impulse Radio)无线通信是一种不用载波,而采用时间间隔极短的脉冲进行通信的方式,也称作脉冲无线电(Impulse Radio)、无载波(Cartier Free)通信。 2001年4月我国发布了“十五”863计划,其中把UWB无线通信关键技术以及共存与兼容技术列为有关通信技术主体研究项目,许多高校也将对UWB的研究作为重点科研项目,取得了很多进展。其中,某高校参与研发的UWB通信演示系统,要求可在室内10 m距离内传输流媒体,文中以该UWB通信演示系统为依托,分析了UWB通信系统与终端设备的接口需求,选用高速USB接口方案,运用FPGA技术实现了USB接口硬件控制电路及
[嵌入式]
STM32定义堆栈地址到ram区顶部
本设置针对stm32f103rbt6的设置,该 芯片 RAM大小为20kB,故RAM区地址范围为0x20000000—0x20005000,芯片信息如下图所示; 第一步: 设置.sct文件; ;************************************************************* ; *** Scatter-Loading Descrip ti on Filegenerated by uVision *** ; ************************************************************* LR_IROM1 0x08000000 0x0002000
[单片机]
<font color='red'>STM32</font>定义堆栈地址到ram区顶部
STM32 BOOT0和BOOT1对于下载程序的应用
前言 本博文基于STM32F103ZET6和MDK5以及库V3.5.0编写; 本博文以原子开发板为例; 如有不足之处,还请多多指教; 其实本没有必要写这篇文章,因为只要按照开发板配套的教程去做就可以对芯片写入程序即可,而且开发板上往往设计的都有一键下载的相关电路,能够产生DTR和RTS信号,从而将程序直接下载到芯片,对于用户来说,大大多短了下载程序的时间,提高了效率;但是毕竟以后如果要做开发这块的,总不能碰见一个项目就买一个买开发板,然后才能下载程序,这简直有点不可思议,还是要懂得脱离开发板,对一个芯片进行下载程序,从而形成一个完整的系统,这算得上是一个稍微成熟的开发; STM32开发板下载程序的两种方式 一: 仿真器下载(J
[单片机]
<font color='red'>STM32</font> BOOT0和BOOT1对于下载程序的应用
STM32的ADC的原理与使用
一、ADC的原理及定义 Analog-to-Digital Converter的缩写。中文译名:模/数转换器或者模拟/数字转换器。是指将连续变量的模拟信号转换为离散的数字信号的器件。其实就是一个取样、量化、编码的一个过程。 典型的模拟数字转换器将模拟信号转换为表示一定比例电压值的数字信号。比如电量、光照传感器等常用。 ---------------------------------------------------------------------------------------------------------------------------------------------------------
[单片机]
<font color='red'>STM32</font>的ADC的原理与使用
英特尔向 Linux 6.5 提交 USB4 Version 2.0 初步支持
7 月 4 日消息,去年 9 月,USB Promoter Group 宣布了 USB4 Version 2.0 标准,可使用 USB-C 数据线实现高达 80 Gbps(10GB/s)的传输速度,并能够在一个方向上处理 120 Gbps 的数据,而在另一个方向上处理 40 Gbps 的数据。 英特尔现在已经为 Linux 6.5 内核提供了 USB4 v2 的初始支持,并在其新的 Intel Barlow Ridge 控制器上进行了初步启用。 英特尔工程师 Mika Westerberg 与众多 Linux 工程师一起参与了 USB4 v2 的启动工作,并启用了他们的 Barlow Ridge 控制器。 初始支持包括
[手机便携]
英特尔向 Linux 6.5 提交 <font color='red'>USB</font>4 Version 2.0 初步支持
stm32的gpio口的介绍
我最近在学stm32,想和大家分享自己的学习成果,也和大家一起学习交流。之前学习过15的库函数的套用,经过一段时间摸索,我对stm32的使用有了基础的了解。因为板子不是正点原子和野火,所以有些不同。 每个板子视频教学第一个介绍都是stm32的gipo口的介绍,这个io口跟51的io口定义全然不同,并且能配置自身频率,而且有些定义用到了结构体。而且stm32是32位的单片机,内部的32位寄存器太多,很难记住,所以建议使用库函数的办法,先学会套用,后来在更改参数或者做一些小项目的时候,对一些寄存器做一些更深入的理解。 首先我们讲一下gipo口void led_init(void) { GPIO_InitTypeDe
[单片机]
利用USB至JT AG 接口板编程MAX1441
引言   MAX1441为信号调理集成电路(IC),支持电容式接近检测传感器设计,适用于汽车无源遥控门禁(PKE)及其它系统。MAX1441具有两个独立的接触/接近检测通道,支持该IC的完备套件包括:   1.集成开发环境MAX-IDE,提供汇编、编译、用户界面和闪存编程器功能。   2.例程代码和典型应用固件。   3.经过完全测试的*估(EV)系统MAX1441EVSYS,包括接口硬件、应用电路和带两个触摸盘的触摸板。    用于生产测试系统的JTAG接口   生产测试系统需要利用接口板编程、测试包括MAX1441在内的终端产品,有三种方式可供选择:   1.开发一个定制接口板或从第三方购买JTAG接口板,确认能
[工业控制]
利用<font color='red'>USB</font>至JT AG 接口板编程MAX1441
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved