打印

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

[复制链接]
5404|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

使用特权

评论回复
5
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--);

真的是莫名其妙呀!

使用特权

评论回复
6
grasswolfs| | 2013-6-8 14:59 | 只看该作者
   TimingDelay = 1000;
      while(TimingDelay);  //Delay 1s
就不行, Systick中断函数就是 TimingDelay--;
看看全局变量有没有不同函数里面变量名不同吧

使用特权

评论回复
7
quyifei|  楼主 | 2013-6-8 15:06 | 只看该作者
grasswolfs 发表于 2013-6-8 14:59
TimingDelay = 1000;
      while(TimingDelay);  //Delay 1s
就不行, Systick中断函数就是 TimingDela ...

在所有项目文件中搜了一遍,确定是没有重名的。

使用特权

评论回复
8
quyifei|  楼主 | 2013-6-8 15:32 | 只看该作者
真的是想不通呀, USB_EP1R的 STAT_TX=0x03, 为啥等不到PC发出的IN的指令呢?

使用特权

评论回复
9
jiaxinhui| | 2013-6-8 15:45 | 只看该作者
你发送的字符串有多少个字节。看看跟你USB中设置的数据包长度是否一样

使用特权

评论回复
10
quyifei|  楼主 | 2013-6-8 16:14 | 只看该作者
jiaxinhui 发表于 2013-6-8 15:45
你发送的字符串有多少个字节。看看跟你USB中设置的数据包长度是否一样

应该不是这个问题,我觉得应该是中断的问题。如果把Systick关掉就可以正常发送了。官方的例子里是没有打开Systick中断的。

使用特权

评论回复
11
grasswolfs| | 2013-6-8 16:48 | 只看该作者
quyifei 发表于 2013-6-8 15:06
在所有项目文件中搜了一遍,确定是没有重名的。

我是说中断和主函数里面的 TimingDelay是同样的么?

使用特权

评论回复
12
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);上面注释掉的方法延时就没有问题。

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usb_lib.h"
#include "usb_pwr.h"
#include "hw_config.h"
#include <stdio.h>
/*private viariables declaration----------------------------------------------*/
__IO uint32_t TimingDelay;
static uint8_t USBData[]="Hello 21ic ";
/**
  * @Breif Main program.
  * @param  None
  * @retval None
  */
int main(void)
{
    /*Configuration Systick as 1000Hz*/
  if (SysTick_Config(SystemCoreClock / 1000))
  {  
    while (1);
  }
  Set_System();
  USB_Interrupts_Config();
  Set_USBClock();
  USB_Init();
  while (1)
  {
    if (bDeviceState == CONFIGURED)
    {
      UserToPMABufferCopy(USBData, ENDP1_TXADDR, 11);
      SetEPTxCount(ENDP1, 11);
      SetEPTxValid(ENDP1);  //Valid ENDP1 to start sending "Hello 21ic " to PC
    }
    /*
    volatile uint32_t tmp=0;
    tmp=10000000;
    while(tmp--);  //delay 1s
    */
    Delay_ms(1000); //delay 1s
  }
}

/**
  * [url=home.php?mod=space&uid=247401]@brief[/url] Inserts a delay time.
  * @param  nTime: specifies the delay time length, in milliseconds.
  * @retval None
  */
void Delay_ms(uint32_t nTime)
{
  TimingDelay = nTime;
  while(TimingDelay != 0);
}
/**
  * @brief Decrements the TimingDelay variable. called by SysTick_Handler()
  * @param  None
  * @retval None
  */
void TimingDelay_Decrement(void)
{
  if (TimingDelay != 0x00)
  {
    TimingDelay--;
  }
}

使用特权

评论回复
13
grasswolfs| | 2013-6-8 17:47 | 只看该作者
if (SysTick_Config(SystemCoreClock / 1000)) {  
    while (1);
  }
这个貌似没什么效果啊,最后的void TimingDelay_Decrement(void)显然没被调用

使用特权

评论回复
14
grasswolfs| | 2013-6-8 17:48 | 只看该作者

使用特权

评论回复
15
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官方给的例子都是这么写的)
/**
  * [url=home.php?mod=space&uid=247401]@brief[/url] This function handles SysTick Handler.
  * @param  None
  * @retval None
  */
void SysTick_Handler(void)
{
    TimingDelay_Decrement();
}

使用特权

评论回复
16
zeluo| | 2013-6-8 20:45 | 只看该作者
感觉应该是标志位没有清除   需要好好看看    及时把标志位清除   应该可以解决

使用特权

评论回复
17
grasswolfs| | 2013-6-8 20:56 | 只看该作者
quyifei 发表于 2013-6-8 17:51
if (SysTick_Config(SystemCoreClock / 1000)) {  
    while (1);
  }

应该是还有哪里的设置没有注意到,那你用在线调试看看可以进中断么?

使用特权

评论回复
18
quyifei|  楼主 | 2013-6-9 16:34 | 只看该作者
grasswolfs 发表于 2013-6-8 20:56
应该是还有哪里的设置没有注意到,那你用在线调试看看可以进中断么?

认真看了ST官方的例子,没有发现有什么遗漏的。
如果用tmp=1000000; while(tmp--)做延时,就没有问题。
如果用systick做延时,开始几秒种是好的,几秒钟后就出错。
感觉似乎是ST的一个bug。

使用特权

评论回复
19
Simon21ic| | 2013-6-9 21:41 | 只看该作者
之前记得碰到过2次stm32的USB库的BUG,都不知道现在修复了没有
记得有一个BUG在usb中断响应不及时的情况下,会引起端口关闭,貌似和LZ的不一样
LZ可以用USB逻辑分析仪看一下底层的实际通信

使用特权

评论回复
20
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

粉丝