您的位置 首页 方案

怎么运用STM32的USB非操控端点发送多个数据包

以下是网友提出的问题和我对这个问题的说明。SMT32F103,根据例程Custom_HID修改,利用EP1以EP_INTERRUPT的方式发送包,原来的例程每次

以下是网友提出的问题和我对这个问题的阐明。

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的地址。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/fangan/254492.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部