本文是将官网的USB驱动库文件移植到自己的工程里面,实现USB功能的具体移植步骤说明,实现Custom_HID功能。
获取工程:STM32F1-V1-工程模版 提取码:p6rg
官网USB驱动固件库下载
百度云下载地址 提取码:osk1
在下载的工程包里面,我们可以看到很多个相关工程,我们选取其中一个工程Custom_HID,然后获取和USB相关的文件出来:
获取文件: USB库文件整理提取码:62p2
USB的通讯是靠中断完成的,所以需要加入两个中断函数,我将它放在stm32f10x_it.c文件里面
void USB_LP_CAN1_RX0_IRQHandler(void)
{
USB_Istr();
}
void USBWakeUp_IRQHandler(void)
{
}
修改文件hw_config.c/hw_config.h/platform_config.h,这三个文件基本都是官方开发板的硬件配置。
//hw_config.c
/**
******************************************************************************
* @file hw_config.c
* @author MCD Application Team
* @version V4.1.0
* @date 26-May-2017
* @brief Hardware Configuration & Setup
******************************************************************************
* @attention
*
* © COPYRIGHT(c) 2017 STMicroelectronics
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "hw_config.h"
#include "usb_lib.h"
#include "usb_desc.h"
#include "usb_pwr.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Extern variables ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
static void IntToUnicode (uint32_t value , uint8_t *pbuf , uint8_t len);
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : Set_System
* Description : Configures Main system clocks & power.
* Input : None.
* Return : None.
*******************************************************************************/
void Set_System(void)
{
}
/*******************************************************************************
* Function Name : Set_USBClock
* Description : Configures USB Clock input (48MHz).
* Input : None.
* Output : 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);
}
/*******************************************************************************
* Function Name : Leave_LowPowerMode.
* Description : Restores system clocks and power while exiting suspend mode.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void Leave_LowPowerMode(void)
{
DEVICE_INFO *pInfo = &Device_Info;
/* Set the device state to the correct state */
if (pInfo->Current_Configuration != 0)
{
/* Device configured */
bDeviceState = CONFIGURED;
}
else
{
bDeviceState = ATTACHED;
}
/*Enable SystemCoreClock*/
SystemInit();
}
/*******************************************************************************
* Function Name : USB_Interrupts_Config.
* Description : Configures the USB interrupts.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void USB_Interrupts_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* 2 bit for pre-emption priority, 2 bits for subpriority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* Enable the USB interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the USB Wake-up interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USBWakeUp_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/*******************************************************************************
* Function Name : Get_SerialNum.
* Description : Create the serial number string descriptor.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void Get_SerialNum(void)
{
uint32_t Device_Serial0, Device_Serial1, Device_Serial2;
Device_Serial0 = *(uint32_t*)ID1;
Device_Serial1 = *(uint32_t*)ID2;
Device_Serial2 = *(uint32_t*)ID3;
Device_Serial0 += Device_Serial2;
if (Device_Serial0 != 0)
{
IntToUnicode (Device_Serial0, &CustomHID_StringSerial[2] , 8);
IntToUnicode (Device_Serial1, &CustomHID_StringSerial[18], 4);
}
}
/*******************************************************************************
* Function Name : HexToChar.
* Description : Convert Hex 32Bits value into char.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
static void IntToUnicode (uint32_t value , uint8_t *pbuf , uint8_t len)
{
uint8_t idx = 0;
for( idx = 0 ; idx < len ; idx ++)
{
if( ((value >> 28)) < 0xA )
{
pbuf[ 2* idx] = (value >> 28) + '0';
}
else
{
pbuf[2* idx] = (value >> 28) + 'A' - 10;
}
value = value << 4;
pbuf[ 2* idx + 1] = 0;
}
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
//platform_config.h
/**
******************************************************************************
* @file platform_config.h
* @author MCD Application Team
* @version V4.1.0
* @date 26-May-2017
* @brief Evaluation board specific configuration file.
******************************************************************************
* @attention
*
* © COPYRIGHT(c) 2017 STMicroelectronics
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __PLATFORM_CONFIG_H
#define __PLATFORM_CONFIG_H
#include "stm32f10x.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Define if Low power mode is enabled; it allows entering the device into
STOP mode following USB Suspend event, and wakes up after the USB wakeup
event is received. */
//#define USB_LOW_PWR_MGMT_SUPPORT
/*Unique Devices IDs register set*/
#define ID1 (0x1FFFF7E8)
#define ID2 (0x1FFFF7EC)
#define ID3 (0x1FFFF7F0)
#endif
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
修改usb_pwr.c 这个文件是电源管理部分,我们只需要屏蔽函数USB_Cable_Config(DISABLE);
USB_Cable_Config(ENABLE);
USB_Cable_Config()这函数硬件上下拉配置usb的通讯脚位,起到usb插入断开的作用,我的板子上没有这个,所以屏蔽就好了,大家根据自己的情况来配置。
修改usb_prop.c 这个文件有两个函数是对开发板硬件的配置处理函数,删掉相关代码。
void CustomHID_SetConfiguration(void)
{
if (pInformation->Current_Configuration != 0)
{
/* Device configured */
bDeviceState = CONFIGURED;
}
}
void CustomHID_Status_In(void)
{
}
修改usb_endp.c 这文件是对应的端点处理函数,同样将关于开发板的代码删除。
__IO uint8_t PrevXferComplete;
void EP1_OUT_Callback(void)
{
BitAction Led_State;
/* Read received data (2 bytes) */
USB_SIL_Read(EP1_OUT, Receive_Buffer);
SetEPRxStatus(ENDP1, EP_RX_VALID);
}
然后我们再观察Custom_HID这个原工程,发现它是一个用户自定义HID设备,可以设备(STM32)与主机(电脑)通讯的,主机可以向设备发送两个字节的数据,STM32可以收到,我们可以通过串口打印是否收到了数据,进一步证实我们的移值时OK的。
修改usb_endp.c
void EP1_OUT_Callback(void)
{
BitAction Led_State;
/* Read received data (2 bytes) */
USB_SIL_Read(EP1_OUT, Receive_Buffer);
SetEPRxStatus(ENDP1, EP_RX_VALID);
printf("HID收到数据:%d %d\r\n",Receive_Buffer[0],Receive_Buffer[1]);
}
可以下载Bus Hound工具下发数据,或者其他工具都行。这里我们发现通讯是正常,那么我们的移植是Ok的,后面我们可以通过这个工程修改部分代码,实现对应的功能:比分说USB鼠标,USB键盘,多媒体控制器等。
获取工程:STM32F1-V2-导入USB文件 提取码:hjk0