×
单片机 > 单片机程序设计 > 详情

STM32 USB虚拟串口调试总结

发布时间:2020-06-16 发布时间:
|

官方代码移植有修改请参考以下链接,我们只针对其不足做补充说明。


1、参考链接:

STM32虚拟串口移植(提供了可用的源码,需要简单修改):https://www.cnblogs.com/hiker-blogs/p/stm32_usb.html


官网虚拟串口里程移植,虚拟串口用到的文件介绍:https://blog.csdn.net/sz189981/article/details/65948071


USB较为详细的介绍、以及虚拟串口移植:https://blog.csdn.net/rannar/article/details/81589472


配置内部时钟方式:https://blog.csdn.net/qhw5279/article/details/77016341


STM32各种时钟说明、配置方式说明:https://www.cnblogs.com/worldsing/p/3433529.html


使用内部RC振荡为系统提供时钟,HSI倍频设置:https://blog.csdn.net/qq_22520215/article/details/72846555   


STM32外部时钟稳定性问题:https://blog.csdn.net/unsv29/article/details/40947639


2、虚拟串口硬件说明

     USBF103自带的USB符合USB2.0规范。


        在USB主机上(电脑上),D-和D+都接了15K下拉电阻到地,所以没有设备接入时,D+和D-都是低电平。


        在USB设备中(STM32主板),如果是高速设备,D+上接一个1.5K上拉电阻到VCC;如果是低速设备,D-上接入一个1.5k


上拉电阻到VCC。这样主机就能判断是否有设备接入,接入的设备是高速还是低速设备。


我们将STM32的USB口当高速设备使用:D+必须有一个1.5K上拉。



2.1、程序中无需配置硬件的设计:D+直接接了3.3V的上拉电阻。


2.2、需要程序中配置D+上拉电阻使能的设计:可以软件模拟USB插拔,便于固件更新后自动重启。

 

    需要修改hw_config.c 文件中的函数:


void Set_System(void)函数中配置PD6引脚为输出PP模式


#define USB_DISCONNECT                      GPIOD

 

#define USB_DISCONNECT_PIN                  GPIO_Pin_6

 

#define RCC_APB2Periph_GPIO_DISCONNECT      RCC_APB2Periph_GPIOD

 

 

/*******************************************************************************

* Function Name  : Set_System

* Description    : Configures Main system clocks & power

* Input          : None.

* Return         : None.

*******************************************************************************/

void Set_System(void)

{

 

  GPIO_InitTypeDef GPIO_InitStructure;

 

  QUEUE_PacketCreate(&m_QueueUsbComRx, m_UsbComRxBuf, sizeof(m_UsbComRxBuf));

 

  QUEUE_PacketCreate(&m_QueueUsbComTx, m_UsbComTxBuf, sizeof(m_UsbComTxBuf));

 

  /* Enable USB_DISCONNECT GPIO clock */

 

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIO_DISCONNECT, ENABLE);

 

 

  /* Configure USB pull-up pin */

 

  GPIO_InitStructure.GPIO_Pin = USB_DISCONNECT_PIN;

 

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

 

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

 

  GPIO_Init(USB_DISCONNECT, &GPIO_InitStructure);

 

 

  /* Configure the EXTI line 18 connected internally to the USB IP */

 

  EXTI_ClearITPendingBit(EXTI_Line18);

 

  EXTI_InitStructure.EXTI_Line = EXTI_Line18;

 

  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;

 

  EXTI_InitStructure.EXTI_LineCmd = ENABLE;

 

  EXTI_Init(&EXTI_InitStructure);

 

}

配置ENABLEUSB线的函数:一定要在ENABLE的时候让D+的上拉电阻是使能状态,也就是PNP的上激光的B级(1脚)给低电平


/*******************************************************************************

* Function Name  : USB_Cable_Config

* Description    : Software Connection/Disconnection of USB Cable

* Input          : None.

* Return         : Status

*******************************************************************************/

void USB_Cable_Config (FunctionalState NewState)

{

  if (NewState ==ENABLE) //(NewState == DISABLE)   //使能的时候D+ 上拉有效

  {

    GPIO_ResetBits(USB_DISCONNECT, USB_DISCONNECT_PIN);

  }

  else

  {

    GPIO_SetBits(USB_DISCONNECT, USB_DISCONNECT_PIN);

  }

}

 


 


3、不同时钟源(内部RC、外部晶振)的USB时钟的配置方式

3.1、直接使用外部时钟8M晶振

    系统时钟倍频为72M,配置USB时钟分频为1.5倍,72/1.5 = 48M (USB时钟是48M)


 


hw_config.c 文件中USB时钟配置如下:


/*******************************************************************************

* Function Name  : Set_USBClock

* Description    : Configures USB Clock input (48MHz)

* Input          : None.

* Return         : None.

*******************************************************************************/

void Set_USBClock(void)

{

  /* Select USBCLK source */

  RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5);

  

 

  /* Enable the USB clock */

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE);

}

 


 


3.2、时钟内部RC电路做系统时钟源

    内部RC输出8M,我们倍频为48M。


    然后设置USB时钟分频为1倍。


 


hw_config.c 文件中USB时钟配置如下:


/*******************************************************************************

* Function Name  : Set_USBClock

* Description    : Configures USB Clock input (48MHz)

* Input          : None.

* Return         : None.

*******************************************************************************/

void Set_USBClock(void)

{

  /* Select USBCLK source */

  RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div1);

 

 

  /* Enable the USB clock */

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE);

}

 


4、配置内部RC并倍频的方式说明:

参考了几位博主的方式,均失败,直接程序无法运行。


之后用以下方式解决:


1、不改变原来系统时钟配置方式;


2、按照博客在main.c定义这个博客的前两个函数:https://blog.csdn.net/qhw5279/article/details/77016341


3、删除其中中断向量表的设置。


4、在main函数开始位置调用此函数,进行系统时钟配置。 Stm32_Clock_Init(12);


5、为使delay_ms()等函数时钟准确,应在system_stm32f10x.c中将#define SYSCLK_FREQ_48MHz  48000000解除屏蔽



关键字:STM32  USB  虚拟串口 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多