请教香水城和各位,每块STM32板子,都要重装USB虚拟串口驱动

[复制链接]
 楼主| nicholasldf 发表于 2012-2-29 09:41 | 显示全部楼层 |阅读模式
本帖最后由 nicholasldf 于 2012-2-29 11:34 编辑

在程序里实现了USB虚拟串口,烧录了几台STM32板子,电脑安装好虚拟串口驱动之后,
第一块板子插到电脑,查找USB虚拟串口驱动,成功,串口号是COM10;
第二块板子插到电脑,又要查找USB虚拟串口驱动,成功,串口号是COM11;
第三块板子插到电脑,又要查找USB虚拟串口驱动,成功,串口号是COMxx;
可能第X块板子,也是一样的问题
而且每块板子只需第一次插上去要找一下驱动,后面插上就不用找了。

我的问题是,为什么每块板子,都要重找一下驱动呢。
一般正常情况是:安装好驱动,插上任何一块板子,PC提示找到新硬件,然后手动查找一下USB驱动,就OK了,后面任何板子插到电脑,就能自动正常使用了。


奇怪的是,我的笔记本和我上班的电脑,都没有这个问题,每一块板子,插上就能用,串口号会变,但不用每次都重找驱动。

我怀疑跟STM32板子本身没关系,是跟电脑系统有关系。因为我的笔记本是用XP光盘安装的,没有这个问题。但我家里的另一台台式电脑,是维修过的,好像是修店的ghostXP系统,也有上述问题。
香水城 发表于 2012-2-29 11:38 | 显示全部楼层
如果每个USB设备的序列号不一样,则会有这种现象。
 楼主| nicholasldf 发表于 2012-2-29 11:41 | 显示全部楼层
这个序列号跟STM32芯片有关系吗?
香水城 发表于 2012-2-29 11:42 | 显示全部楼层
可以有关系也可以没有关系。
 楼主| nicholasldf 发表于 2012-2-29 11:43 | 显示全部楼层
:)还有就是测试的电脑当中,有2台电脑是正常的,相信其他更多电脑应该也是正常的,:)
 楼主| nicholasldf 发表于 2012-2-29 11:45 | 显示全部楼层
4# 香水城

不大明白:(
香水城 发表于 2012-2-29 11:49 | 显示全部楼层
序列号是软件的事情,不是芯片的功能,如果你的软件中有相应的程序,就会有序列号。
 楼主| nicholasldf 发表于 2012-2-29 11:51 | 显示全部楼层
用的芯片是STM32F103ZE,,程序是ST的官方例子Virtual_COM_Port,看了下USB描述符usb_desc.c文件,好像没有什么东西是跟具体芯片有关系的,比如读取芯片的序列号或者某些信息,作为USB信息传给电脑,没看到这个
 楼主| nicholasldf 发表于 2012-2-29 11:53 | 显示全部楼层
7# 香水城

如果软件有这个序列号,程序是ST的官方例子,程序不会变,序列号页应该不会变,也就是说换一块板子,序列号也不会变吧,按这样说,是不是不应该出现这个问题呢?
谢谢:handshake
香水城 发表于 2012-2-29 11:56 | 显示全部楼层
7# 香水城  

如果软件有这个序列号,程序是ST的官方例子,程序不会变,序列号页应该不会变,也就是说换一块板子,序列号也不会变吧,按这样说,是不是不应该出现这个问题呢?
谢谢:handshake ...
nicholasldf 发表于 2012-2-29 11:53


在ST的官方例子中,USB设备的序列号是与芯片的唯一ID挂钩,如果你没有改过,则每个设备的序列号都应该是不一样的。
 楼主| nicholasldf 发表于 2012-2-29 12:30 | 显示全部楼层
哦,我先找一下USB虚拟串口例子中跟芯片ID挂钩的那段代码,,如果找不到,还请你方便指明一下是哪一段?
如果我把他改成固定的不知道行不行?
谢谢
 楼主| nicholasldf 发表于 2012-2-29 13:34 | 显示全部楼层
看到程序里面
PID和VID是固定的   
0x83,
0x04,   /* idVendor = 0x0483 */
0x40,
0x57,   /* idProduct = 0x7540 */

三串描述符也是固定的,其中第三串应该就是“SB设备的序列号”?serial number?
const uint8_t Virtual_Com_Port_StringVendor[VIRTUAL_COM_PORT_SIZ_STRING_VENDOR] =
  {
    VIRTUAL_COM_PORT_SIZ_STRING_VENDOR,     /* Size of Vendor string */
    USB_STRING_DESCRIPTOR_TYPE,             /* bDescriptorType*/
    /* Manufacturer: "STMicroelectronics" */
    'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0,
    'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0,
    'c', 0, 's', 0
  };

const uint8_t Virtual_Com_Port_StringProduct[VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT] =
  {
    VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT,          /* bLength */
    USB_STRING_DESCRIPTOR_TYPE,        /* bDescriptorType */
    /* Product name: "STM32 Virtual COM Port" */
    'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0, ' ', 0, 'V', 0, 'i', 0,
    'r', 0, 't', 0, 'u', 0, 'a', 0, 'l', 0, ' ', 0, 'C', 0, 'O', 0,
    'M', 0, ' ', 0, 'P', 0, 'o', 0, 'r', 0, 't', 0, ' ', 0, ' ', 0
  };

uint8_t Virtual_Com_Port_StringSerial[VIRTUAL_COM_PORT_SIZ_STRING_SERIAL] =
  {
    VIRTUAL_COM_PORT_SIZ_STRING_SERIAL,           /* bLength */
    USB_STRING_DESCRIPTOR_TYPE,                   /* bDescriptorType */
    'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0, '1', 0, '0', 0
  };
香水城 发表于 2012-2-29 13:43 | 显示全部楼层
在hw_config.c中有这个函数:

  1. /*******************************************************************************
  2. * Function Name  : Get_SerialNum.
  3. * Description    : Create the serial number string descriptor.
  4. * Input          : None.
  5. * Output         : None.
  6. * Return         : None.
  7. *******************************************************************************/
  8. void Get_SerialNum(void)
  9. {
  10.   uint32_t Device_Serial0, Device_Serial1, Device_Serial2;
  11. #ifdef STM32L1XX_MD
  12.   Device_Serial0 = *(uint32_t*)(0x1FF80050);
  13.   Device_Serial1 = *(uint32_t*)(0x1FF80054);
  14.   Device_Serial2 = *(uint32_t*)(0x1FF80064);
  15. #else  
  16.   Device_Serial0 = *(__IO uint32_t*)(0x1FFFF7E8);
  17.   Device_Serial1 = *(__IO uint32_t*)(0x1FFFF7EC);
  18.   Device_Serial2 = *(__IO uint32_t*)(0x1FFFF7F0);
  19. #endif /* STM32L1XX_MD */  
  20.   Device_Serial0 += Device_Serial2;
  21.   if (Device_Serial0 != 0)
  22.   {
  23.     IntToUnicode (Device_Serial0, &Virtual_Com_Port_StringSerial[2] , 8);
  24.     IntToUnicode (Device_Serial1, &Virtual_Com_Port_StringSerial[18], 4);
  25.   }
  26. }

 楼主| nicholasldf 发表于 2012-2-29 13:50 | 显示全部楼层
本帖最后由 nicholasldf 于 2012-2-29 13:51 编辑

好,非常谢谢,

此外我发现usb_desc.h定义了各个描述符长度,usb_desc.c是各个描述符的定义,,
我发现,其他定义都是精确的,只有#define VIRTUAL_COM_PORT_SIZ_STRING_SERIAL      26是不一样,是不是定义错了,实际上Virtual_Com_Port_StringSerial数组只有16个字节,如果错了的话,紧跟Virtual_Com_Port_StringSerial后面的数据是不可预知的。不知道这个也会不会是一个原因,到时也试一下。还有就是你上面提到的Get_SerialNum函数,这两个我都试一下。
uint8_t Virtual_Com_Port_StringSerial[VIRTUAL_COM_PORT_SIZ_STRING_SERIAL] =
  {
    VIRTUAL_COM_PORT_SIZ_STRING_SERIAL,           /* bLength */
    USB_STRING_DESCRIPTOR_TYPE,                   /* bDescriptorType */
    'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0, '1', 0, '0', 0
  };

#define VIRTUAL_COM_PORT_SIZ_DEVICE_DESC        18
#define VIRTUAL_COM_PORT_SIZ_CONFIG_DESC        67
#define VIRTUAL_COM_PORT_SIZ_STRING_LANGID      4
#define VIRTUAL_COM_PORT_SIZ_STRING_VENDOR      38
#define VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT     50
#define VIRTUAL_COM_PORT_SIZ_STRING_SERIAL      26
香水城 发表于 2012-2-29 13:54 | 显示全部楼层
定义VIRTUAL_COM_PORT_SIZ_STRING_SERIAL = 26,就是为13楼那个函数预留空间的。
 楼主| nicholasldf 发表于 2012-3-5 16:52 | 显示全部楼层
谢谢香水城:handshake

上周做了验证,如下解决:

将序列号长度改为16,
//解决每块板子第一次插入电脑时都要查找驱动的问题,原是26
#define VIRTUAL_COM_PORT_SIZ_STRING_SERIAL      16//26


所有板子序列号都一样,采用默认的即可
uint8_t Virtual_Com_Port_StringSerial[VIRTUAL_COM_PORT_SIZ_STRING_SERIAL] =
  {
    VIRTUAL_COM_PORT_SIZ_STRING_SERIAL,           /* bLength */
    USB_STRING_DESCRIPTOR_TYPE,                   /* bDescriptorType */
    'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0, '1', 0, '0', 0
  };


在void Virtual_Com_Port_init(void)函数里面,屏蔽Get_SerialNum()函数调用
/* Update the serial number string descriptor with the data from the unique  ID*/
//解决每块板子第一次插入电脑时都要查找驱动的问题
//Get_SerialNum();
哲哲55 发表于 2012-3-6 09:01 | 显示全部楼层
占位留下来以后看
nongfuxu 发表于 2012-5-9 09:37 | 显示全部楼层
学习了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

61

主题

261

帖子

10

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

61

主题

261

帖子

10

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