打印
[USB编程]

STM32 USB虚拟串口如何实现流控。

[复制链接]
5606|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
he19880406|  楼主 | 2013-12-6 15:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用平台:STM32F103R8T6.
USB虚拟串口已经成功,想实现PC机端软件发送数据到 EP3,接收到的数据直接写入FLASH。EP1来实现向PC机发送0XAA,实现流控制。
但是一直有问题。不知道什么原因。

端点配置如下:

usb_prob.c文件:

/* Initialize Endpoint 0 */
  SetEPType(ENDP0, EP_CONTROL);
  SetEPTxStatus(ENDP0, EP_TX_STALL);
  SetEPRxAddr(ENDP0, ENDP0_RXADDR);
  SetEPTxAddr(ENDP0, ENDP0_TXADDR);
  Clear_Status_Out(ENDP0);
  SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
  SetEPRxValid(ENDP0);

  /* Initialize Endpoint 1 */
  SetEPType(ENDP1, EP_BULK);
  SetEPTxAddr(ENDP1, ENDP1_TXADDR);
  SetEPTxStatus(ENDP1, EP_TX_NAK);
  SetEPRxStatus(ENDP1, EP_RX_DIS);

  /* Initialize Endpoint 2 */
  SetEPType(ENDP2, EP_INTERRUPT);
  SetEPTxAddr(ENDP2, ENDP2_TXADDR);
  SetEPRxStatus(ENDP2, EP_RX_DIS);
  SetEPTxStatus(ENDP2, EP_TX_NAK);

  /* Initialize Endpoint 3 */
  SetEPType(ENDP3, EP_BULK);
  SetEPRxAddr(ENDP3, ENDP3_RXADDR);
  SetEPRxCount(ENDP3, VIRTUAL_COM_PORT_DATA_SIZE);
  SetEPRxStatus(ENDP3, EP_RX_VALID);
  SetEPTxStatus(ENDP3, EP_TX_DIS);

usb_endp.c文件:

void EP1_IN_Callback()
{  
         uint8_t pDat[64];
          
           pDat[0] = 0xAA;
       
                 UserToPMABufferCopy(pDat, ENDP1_TXADDR, 64);
                 SetEPTxCount(ENDP1, 64);
               
}

/*******************************************************************************
* Function Name  : EP3_OUT_Callback
* Description    :
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void EP3_OUT_Callback(void)
{

  /* Get the received data buffer and update the counter */
  USB_Rx_Cnt = USB_SIL_Read(EP3_OUT, USB_Rx_Buffer);

  FLASH_Unlock();       
  EE_BufferWrite(WriteAddr,USB_Rx_Cnt,USB_Rx_Buffer);        
  WriteAddr +=  USB_Rx_Cnt;       
        //USBSendDataFlag = 1;
        SetEPTxStatus(ENDP1, EP_TX_NAK);
        SetEPTxValid(ENDP1);

  /* Enable the receive of data on EP3 */
  SetEPRxValid(ENDP3);

}
出现PC机端软件读取虚拟串口数据,不能读到0XAA。PC机软件采用C#编写。





相关帖子

沙发
li880wert| | 2013-12-6 17:21 | 只看该作者
1。你确定你数据发送出去了。

使用特权

评论回复
板凳
john_lee| | 2013-12-7 21:37 | 只看该作者
往PC发0xAA做啥,CDC的流控依赖USB本身的ACK/NAK机制。

使用特权

评论回复
地板
he19880406|  楼主 | 2013-12-8 09:01 | 只看该作者
奥,对了。void EP3_OUT_Callback(void)中的SetEPTxStatus(ENDP1, EP_TX_NAK);是我测试用的,应该注释掉。往PC机发送0xAA是用于与上位机软件交互。也就是说,上位机每发送64字节数据,就等待串口收到0xAA,收到之后再继续发送数据。这样做主要是因为EP3_OUT_Callback中把接收到的数据直接写入FLASH。写入速度比较慢,如果不加流控,数据会被覆盖。

使用特权

评论回复
5
he19880406|  楼主 | 2013-12-8 09:50 | 只看该作者
如果把SetEPTxValid(ENDP1);放在EP1_IN_Callback()中,PC机端确实能收到数据。但是放在void EP3_OUT_Callback(void)中就不能收到0xAA了。
0xAA只是用来告诉PC机,先不要再发数据了。等把USB缓冲区的64字节数据写入FLASH,完成后再发送。

使用特权

评论回复
6
he19880406|  楼主 | 2013-12-8 10:05 | 只看该作者
不知道STM32内部FLASH写入速度是多少?如果大概能估算出来,还不如直接让PC机每发送64B,delay以下,继续发送。

使用特权

评论回复
7
john_lee| | 2013-12-8 20:17 | 只看该作者
不需要EP1了,EP3接收数据后,只管写Flash就是了,写完后再执行 SetEPRxValid(ENDP3);

使用特权

评论回复
8
john_lee| | 2013-12-8 20:25 | 只看该作者
在 SetEPRxValid(ENDP3) 执行之前(就是正在写Flash时),如果host又发了下一个packet过来,那么device会给host应答一个NAK,host收到NAK后,会在下个SOF时重发这个packet,而执行了 SetEPRxValid(ENDP3) 后,device 收到了 packet,就会给 host 应答 ACK。这就是usb的流控机制。

使用特权

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

本版积分规则

3

主题

13

帖子

0

粉丝