USB 虚拟串口无法向PC发送数据

[复制链接]
6636|20
 楼主| quyifei 发表于 2013-6-8 09:03 | 显示全部楼层 |阅读模式
本帖最后由 quyifei 于 2013-6-8 11:17 编辑

最近在调试USB虚拟串口,想每隔1秒向上位机发送一个字符串。 上位机是“串口调试助手”。

开始发送是没有问题的,大概发送3或4次之后就停止发送了。 此时接收数据是正常的,我从上位机发送数据可以正常接收。

观察USB寄存器的值, USB_EP1R的 STAT_TX=0x03, 说明已经准备好发送了,只要PC发送一个IN的指令,字符串就能发送出去。 问题是好像PC停止发送IN的指令了。 我怀疑是不是ST的虚拟串口驱动有问题了?

大家怎么看?
 楼主| quyifei 发表于 2013-6-8 11:06 | 显示全部楼层
本帖最后由 quyifei 于 2013-6-8 11:12 编辑

我把Systick给关了,发送就正常了。
可是systick总要用的吧?这个中断太基本了。 systick的优先级是0xF0,已经是最低的了。是不是ST的这个USB库和systicck无法共存呢?或者是ST的虚拟串口驱动有问题呢?
mmuuss586 发表于 2013-6-8 12:10 | 显示全部楼层
用的什么芯片啊???
 楼主| quyifei 发表于 2013-6-8 12:56 | 显示全部楼层
mmuuss586 发表于 2013-6-8 12:10
用的什么芯片啊???

STM32103C8T6
 楼主| quyifei 发表于 2013-6-8 13:02 | 显示全部楼层
本帖最后由 quyifei 于 2013-6-8 13:06 编辑
mmuuss586 发表于 2013-6-8 12:10
用的什么芯片啊???

我把systick打开了,1000Hz。
我发现延时的不同结果也不同

    TimingDelay = 1000;
      while(TimingDelay);  //Delay 1s
就不行, Systick中断函数就是 TimingDelay--;

但这样延时就没有问题
    tmp=10000000;
    while(tmp--);

真的是莫名其妙呀!
grasswolfs 发表于 2013-6-8 14:59 | 显示全部楼层
   TimingDelay = 1000;
      while(TimingDelay);  //Delay 1s
就不行, Systick中断函数就是 TimingDelay--;
看看全局变量有没有不同函数里面变量名不同吧
 楼主| quyifei 发表于 2013-6-8 15:06 | 显示全部楼层
grasswolfs 发表于 2013-6-8 14:59
TimingDelay = 1000;
      while(TimingDelay);  //Delay 1s
就不行, Systick中断函数就是 TimingDela ...

在所有项目文件中搜了一遍,确定是没有重名的。
 楼主| quyifei 发表于 2013-6-8 15:32 | 显示全部楼层
真的是想不通呀, USB_EP1R的 STAT_TX=0x03, 为啥等不到PC发出的IN的指令呢?
jiaxinhui 发表于 2013-6-8 15:45 | 显示全部楼层
你发送的字符串有多少个字节。看看跟你USB中设置的数据包长度是否一样
 楼主| quyifei 发表于 2013-6-8 16:14 | 显示全部楼层
jiaxinhui 发表于 2013-6-8 15:45
你发送的字符串有多少个字节。看看跟你USB中设置的数据包长度是否一样

应该不是这个问题,我觉得应该是中断的问题。如果把Systick关掉就可以正常发送了。官方的例子里是没有打开Systick中断的。
grasswolfs 发表于 2013-6-8 16:48 | 显示全部楼层
quyifei 发表于 2013-6-8 15:06
在所有项目文件中搜了一遍,确定是没有重名的。

我是说中断和主函数里面的 TimingDelay是同样的么?
 楼主| quyifei 发表于 2013-6-8 17:35 | 显示全部楼层
本帖最后由 quyifei 于 2013-6-8 17:42 编辑
grasswolfs 发表于 2013-6-8 16:48
我是说中断和主函数里面的 TimingDelay是同样的么?


是一样的。 我把程序贴出来,这样更加清楚。 延时用的是Delay_ms(1000),延时1秒。如果用Delay_ms(1000);上面注释掉的方法延时就没有问题。

  1. /* Includes ------------------------------------------------------------------*/
  2. #include "main.h"
  3. #include "usb_lib.h"
  4. #include "usb_pwr.h"
  5. #include "hw_config.h"
  6. #include <stdio.h>
  7. /*private viariables declaration----------------------------------------------*/
  8. __IO uint32_t TimingDelay;
  9. static uint8_t USBData[]="Hello 21ic ";
  10. /**
  11.   * @Breif Main program.
  12.   * @param  None
  13.   * @retval None
  14.   */
  15. int main(void)
  16. {
  17.     /*Configuration Systick as 1000Hz*/
  18.   if (SysTick_Config(SystemCoreClock / 1000))
  19.   {  
  20.     while (1);
  21.   }
  22.   Set_System();
  23.   USB_Interrupts_Config();
  24.   Set_USBClock();
  25.   USB_Init();
  26.   while (1)
  27.   {
  28.     if (bDeviceState == CONFIGURED)
  29.     {
  30.       UserToPMABufferCopy(USBData, ENDP1_TXADDR, 11);
  31.       SetEPTxCount(ENDP1, 11);
  32.       SetEPTxValid(ENDP1);  //Valid ENDP1 to start sending "Hello 21ic " to PC
  33.     }
  34.     /*
  35.     volatile uint32_t tmp=0;
  36.     tmp=10000000;
  37.     while(tmp--);  //delay 1s
  38.     */
  39.     Delay_ms(1000); //delay 1s
  40.   }
  41. }

  42. /**
  43.   * [url=home.php?mod=space&uid=247401]@brief[/url] Inserts a delay time.
  44.   * @param  nTime: specifies the delay time length, in milliseconds.
  45.   * @retval None
  46.   */
  47. void Delay_ms(uint32_t nTime)
  48. {
  49.   TimingDelay = nTime;
  50.   while(TimingDelay != 0);
  51. }
  52. /**
  53.   * @brief Decrements the TimingDelay variable. called by SysTick_Handler()
  54.   * @param  None
  55.   * @retval None
  56.   */
  57. void TimingDelay_Decrement(void)
  58. {
  59.   if (TimingDelay != 0x00)
  60.   {
  61.     TimingDelay--;
  62.   }
  63. }
grasswolfs 发表于 2013-6-8 17:47 | 显示全部楼层
if (SysTick_Config(SystemCoreClock / 1000)) {  
    while (1);
  }
这个貌似没什么效果啊,最后的void TimingDelay_Decrement(void)显然没被调用
grasswolfs 发表于 2013-6-8 17:48 | 显示全部楼层
 楼主| quyifei 发表于 2013-6-8 17:51 | 显示全部楼层
本帖最后由 quyifei 于 2013-6-8 18:04 编辑
grasswolfs 发表于 2013-6-8 17:47
if (SysTick_Config(SystemCoreClock / 1000)) {  
    while (1);
  }


if (SysTick_Config(SystemCoreClock / 1000)) {  
    while (1);
  }
是配置Systick, 配置是1ms产生一次Systick中断。

void TimingDelay_Decrement(void)是在文件stm32f10x_it.c中的void SysTick_Handler(void)调用,如下(ST官方给的例子都是这么写的)
  1. /**
  2.   * [url=home.php?mod=space&uid=247401]@brief[/url] This function handles SysTick Handler.
  3.   * @param  None
  4.   * @retval None
  5.   */
  6. void SysTick_Handler(void)
  7. {
  8.     TimingDelay_Decrement();
  9. }
zeluo 发表于 2013-6-8 20:45 | 显示全部楼层
感觉应该是标志位没有清除   需要好好看看    及时把标志位清除   应该可以解决
grasswolfs 发表于 2013-6-8 20:56 | 显示全部楼层
quyifei 发表于 2013-6-8 17:51
if (SysTick_Config(SystemCoreClock / 1000)) {  
    while (1);
  }

应该是还有哪里的设置没有注意到,那你用在线调试看看可以进中断么?
 楼主| quyifei 发表于 2013-6-9 16:34 | 显示全部楼层
grasswolfs 发表于 2013-6-8 20:56
应该是还有哪里的设置没有注意到,那你用在线调试看看可以进中断么?

认真看了ST官方的例子,没有发现有什么遗漏的。
如果用tmp=1000000; while(tmp--)做延时,就没有问题。
如果用systick做延时,开始几秒种是好的,几秒钟后就出错。
感觉似乎是ST的一个bug。
Simon21ic 发表于 2013-6-9 21:41 | 显示全部楼层
之前记得碰到过2次stm32的USB库的BUG,都不知道现在修复了没有
记得有一个BUG在usb中断响应不及时的情况下,会引起端口关闭,貌似和LZ的不一样
LZ可以用USB逻辑分析仪看一下底层的实际通信
he19880406 发表于 2013-11-25 18:21 | 显示全部楼层
我也遇见同样的问题。不过我的发送数据是在EP1_IN_Callback()里面写的。

void EP1_IN_Callback()
{
         uint8_t *pBuf;
         uint32_t rst;       
          
         *pBuf = 0xAA;
         rst = USB_SIL_Write(ENDP1_TXADDR,pBuf,1);                       
         SetEPTxValid(ENDP1);
}
也是跟你一样,上位机发送数据,下位机能够接收到。下位机发送数据,上位机接收不到。使用平台STM32F103R8T6,USB固件库
不知楼主问题解决了吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:最小STM32开发板-攸米板淘宝: yifei-stm.taobao.com 博客: blog.sina.com.cn/yifeistm

29

主题

146

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部