目录
2.1、程序中无需配置硬件的设计:D+直接接了3.3V的上拉电阻。
2.2、需要程序中配置D+上拉电阻使能的设计:可以软件模拟USB插拔,便于固件更新后自动重启。
官方代码移植有修改请参考以下链接,我们只针对其不足做补充说明。
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解除屏蔽