历史上的今天
返回首页

历史上的今天

今天是:2024年10月29日(星期二)

正在发生

2020年10月29日 | STM32的USB多包数据传送

2020-10-29 来源:eefocus

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);//发送递增计数 看模拟的串口数据有没有漏掉的

}

}

}


推荐阅读

史海拾趣

Focus公司的发展小趣事

Focus科技股份有限公司(虚构)在深耕外贸电商领域的同时,也敏锐地捕捉到了教育与医疗行业的数字化转型机遇。公司利用自身在互联网技术和大数据分析方面的优势,研发了智慧教育平台和移动医疗应用。智慧教育平台通过提供个性化学习资源和在线互动教学服务,有效提升了教育资源的利用率和学生的学习效果;移动医疗应用则通过远程医疗咨询、健康管理等功能,为用户提供了便捷的医疗服务体验。这些跨界融合的产品不仅丰富了公司的业务线,也进一步提升了公司的品牌影响力和市场竞争力。

GarrettCom公司的发展小趣事

研发:GarrettCom(现为Belden的一部分)始终将技术创新作为企业发展的核心驱动力。公司不断投入研发资源,致力于开发更加先进、可靠的工业网络通信产品。通过持续的技术创新,GarrettCom不仅推动了工业通信技术的进步,还为客户提供了更加高效、便捷的通信解决方案。

应用:这些创新产品被广泛应用于工业自动化、交通监控、能源管理等多个领域,为客户创造了巨大的价值。同时,GarrettCom还积极参与国际标准的制定和推广工作,为行业的标准化发展做出了积极贡献。

Conexcon Group公司的发展小趣事

在电子行业的快速发展中,Conexcon Group以其前瞻性的技术视野,成功研发出一款新型智能芯片,这款芯片不仅性能卓越,而且功耗极低,迅速赢得了市场的青睐。公司凭借这一技术突破,逐步扩大了在国内外市场的份额,成为了行业内技术创新的领军者。随着产品线的不断丰富,Conexcon Group逐渐形成了从芯片设计到整机制造的完整产业链,进一步巩固了其在电子行业的领先地位。

AMSCO [Austria micro systems AG]公司的发展小趣事

随着全球化进程的加速,Conexcon Group积极实施国际化战略,将业务拓展至海外市场。公司通过在海外设立研发中心和生产基地,进一步提升了自身的研发能力和生产效率。同时,公司还加强了与国际知名品牌的合作,通过共同推广和营销活动,提升了自身品牌在国际市场的知名度和影响力。这些举措不仅为公司带来了丰厚的利润回报,也为公司的长远发展奠定了坚实的基础。

Hilscher Gesellschaft für Systemautomation mbH公司的发展小趣事

随着在高压电源领域的深入发展,HVPSI逐渐参与到行业标准的制定工作中。公司凭借其在技术上的深厚积累和市场经验,为行业标准的制定提供了宝贵的建议和数据支持。这些标准的出台不仅规范了市场秩序,也进一步巩固了HVPSI在行业内的领先地位。

Amphenol Thermometrics公司的发展小趣事

HVPSI成立于本世纪初,起初是一家小型的技术初创企业,专注于研发高效、可靠的高压电源模块。在创始人及核心团队的带领下,公司迅速在MOV(金属氧化物压敏电阻)模块领域取得了突破。这些模块在电力电子设备中起到了关键的过压保护作用,有效提高了系统的稳定性和安全性。通过不断的技术迭代和产品优化,HVPSI逐渐在行业内树立了技术领先的形象。

问答坊 | AI 解惑

有关现时显示的疑问

我是个外行!初到本站。由于总是用到示波器(模拟的)来观察一些变化的信号,对实时显示的这个问题很关心!以前也听说数字示波器不能实时显示要测的波形,所以一直也不敢问津高贵的数字示波器(卖示波器的大都只知道卖问也问不明白)!看到诸位大 ...…

查看全部问答>

运放相关资料

本帖最后由 paulhyde 于 2014-9-15 08:59 编辑 运放 滤波 等相关资料  …

查看全部问答>

锁相环(PLL)详解

锁相环是指一种电路或者模块,它用于在通信的接收机中,其作用是对接收到的信号进行处理,并从其中提取某个时钟的相位信息。或者说,对于接收到的信号,仿制一个时钟信号,使得这两个信号从某种角度来看是同步的(或者说,相干的)。 由于锁定情 ...…

查看全部问答>

LM3S1601最小系统电路图

该电路也适合于其它100管脚芯片LM3S1000、2000、8000系列。 相关芯片资料下载: LM3S615:       SPX1117: CAT811: LM3S系列Protel元件库(rar): [ 本帖最后由 clark 于 2010-1-18 13:39 编辑 ]…

查看全部问答>

NVR与DVR比较

dvr即是digital video recorder(也叫: personal video recorder 即pvr)——数字视频录像机或数字硬盘录像机,我们习惯上称为硬盘录像机。     它是一套进行图像存储处理的计算机系统,具有对图像/语音进行长时间录像、录音、远程监视和 ...…

查看全部问答>

关于双机热备技术

  双机热备技术起源于国外,国外大都是双机热备软件,都是很成熟的了。我用的是双机MCU的系统,也应该属于双机热备?   请问:国外双机MCU的系统应用的现状如何?   …

查看全部问答>

关于keil

各位大虾,请问下面是怎么回事? Build target \'Target 1\' compiling test.c... TEST.C(32): warning C291: not every exit path returns a value linking... BL51 BANKED LINKER/LOCATER V6.20 - SN: Eval Version COPYRIGHT KEIL ELEKTRO ...…

查看全部问答>

BUS HOUND报medium changed

现在给USB设备发送私有命令(当然固件也是有自己开发的),用BUS HOUND查看数据,发现发送一个私有命令后,报medium changed,不知道这个现象是为什么,希望高手解释一下!~~~~~~~~~~~~~~~~~~~~~~~~~…

查看全部问答>

有用MCU连接WIFI做通讯吗?

比如用WIFI模块的SDIO接口连接MCU应用。…

查看全部问答>

]基于JZ4755的网络电视机项目运行测试

经过3个多月的努力,现在板子已经可以正常运行了。调试过程可谓坎坷,有硬件的也有软件的。现在SDRAM跑在136MHZ上,总的来说还算是比较稳定的。下面是该板子运行时的图片:                 &nb ...…

查看全部问答>