打印
[应用相关]

高手请帮忙,usb块传输的问题

[复制链接]
2109|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
kthhai|  楼主 | 2009-3-5 10:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
采用万利的板子EK-STM32F

自己编写的两个函数,请高手帮忙看看有什么问题

usb接收数据函数
void USBCom_RecvPacket(u8 *Data)
{
  pUSBRecvData = Data;
  USBRecvLen = GetEPRxCount(ENDP3);
  PMAToUserBufferCopy(pUSBRecvData,ENDP3_RXADDR,USBRecvLen);
  SetEPRxValid(ENDP3);
}

usb发送数据函数
void USBCom_SentData(u8 *Data, u16 USBSentLen)
{
  pUSBSendData = Data;
  UserToPMABufferCopy(pUSBSendData, ENDP1_TXADDR, USBSentLen);
  SetEPTxValid(ENDP1);
}

采用的是ViturlComPort 程序更改过来的,
主函数为
int main(void)
{

#ifdef DEBUG
  debug();
#endif
 
  Set_System();
  Set_USBClock();
  USB_Interrupts_Config();
  USB_Init();

  while(1)
  {
    USBCom_RecvPacket(RecvBuffTemp);
     
    USBCom_SentData(RecvBuffTemp, USBRecvLen);
  }
}

#ifdef  DEBUG

为什么第一次设备接收数据后,设备一直在给PC发送数据?
沙发
vigia| | 2009-3-5 11:11 | 只看该作者

RX

在ST提供的VCD DEMO的源代码中,要通过端点1发送数据,是写以下3句代码,你少了1句。

  UserToPMABufferCopy(buffer_in, ENDP1_TXADDR, count_in);
  SetEPTxCount(ENDP1, count_in);
  SetEPTxValid(ENDP1);

使用特权

评论回复
板凳
kthhai|  楼主 | 2009-3-6 17:17 | 只看该作者

RX vigia

我测试过了,发送函数是有问题的,后面我更改了,
/// @param Data  Input the byte array containing the bytes to be sent to USB Port
/// @param pDataLength  Length of Data to be sent
/// @return  None
void USBCom_SendPacket(u8 *Data, u16 DataLength)
{
  u32 Counter = 0x0000FFFF;
  
  USBSendLen = DataLength;
  USBSentLen = Min(USBSendLen, VIRTUAL_COM_PORT_DATA_SIZE);
  pUSBSendData = Data;
  USBSendStatus = TRUE;
  
  UserToPMABufferCopy(pUSBSendData, ENDP1_TXADDR, USBSentLen);
  SetEPTxCount(ENDP1, USBSentLen);
  SetEPTxValid(ENDP1);
  
  do{
    Counter--;
    
    if (Counter == 0)
    {
      return;
    }
  }while (USBSendStatus);
}

这个函数是十分好用的,但是还是存在 第一次设备接收数据后,设备一直在给PC发送数据的问题,这个问题应该是接收函数的问题。

使用特权

评论回复
地板
vigia| | 2009-3-6 17:46 | 只看该作者

晕,没看懂

端点1是用来向PC发送数据的,你现在改了,又说函数十分好用,又说设备一直给PC发送数据,那到底是好用还是不好用阿?



还有,设备向PC发送数据的问题为什么是接收函数的问题?

使用特权

评论回复
5
elecbug| | 2009-3-6 22:06 | 只看该作者

re

while(1)
  {

    ...     
    USBCom_SentData(RecvBuffTemp, USBRecvLen);
  }
当然一直发。

使用特权

评论回复
6
kthhai|  楼主 | 2009-3-9 09:31 | 只看该作者

re

使用特权

评论回复
7
kthhai|  楼主 | 2009-3-9 09:34 | 只看该作者

re

我的想法是,让主机给设备发一次数据,设备回一次数据,然后设备在次等待主机发送数据,设备再回一次数据,如此反复。第一个函数为设备接收函数,第二个函数为设备发送函数,发送函数测试过,没有问题,接收函数是有问题的。

使用特权

评论回复
8
vigia| | 2009-3-9 11:22 | 只看该作者

RX

刚又仔细看了下你的代码,汗,整个流程都错了。

void USBCom_RecvPacket(u8 *Data)
{
  pUSBRecvData = Data;
  USBRecvLen = GetEPRxCount(ENDP3);
  PMAToUserBufferCopy(pUSBRecvData,ENDP3_RXADDR,USBRecvLen);
  SetEPRxValid(ENDP3);
}
你的这段代码中的  
USBRecvLen = GetEPRxCount(ENDP3);
PMAToUserBufferCopy(pUSBRecvData,ENDP3_RXADDR,USBRecvLen);
这两句话,都应该是在端点3的接收完成后执行的,所以不能放在启动接收的代码中,而应放在端点3的OUT中断中,即EP3_OUT_Callback()中。而启动接收的代码应该是最简单的SetEPRxValid(ENDP3);

整个过程应该是使能端点3的RX -> PC发送数据 -> STM32产生端点3的OUT中断 -> 在中断中把PC发送的数据保存到用户管理的存储区中。-> 配置用户标志位,表示接收完成,同时再次使能端点3的RX,允许下次的数据接收。

简单说你的代码应该是:
main()
{
  ....
  SetEPRxValid(ENDP3);
  while(1){
    if(ReceiveFlag){
      USBCom_SentData(RecvBuffTemp, USBRecvLen);
      ReceiveFlag = 0;
    } 
  }
}

EP3_OUT_Callback()
{
  USBRecvLen  = GetEPRxCount(ENDP3);
  PMAToUserBufferCopy((pUSBRecvData, ENDP3_RXADDR, USBRecvLen );
  SetEPRxValid(ENDP3);
  ReceiveFlag = 1;
}


使用特权

评论回复
9
kthhai|  楼主 | 2009-3-16 13:57 | 只看该作者

NB,谢谢,感动。

谢谢,太感动了,高手就是高手!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

10

帖子

0

粉丝