stm32f103移植到f0_USB库STM32F0x2移植到STM32F070笔记

本文详细记录了如何将STM32F0x2的USB库移植到STM32F070上,主要涉及修改设备配置、时钟树设置、代码调整等步骤,最终实现USB功能并在NUCLEO-F070RB板上成功运行。
摘要由CSDN通过智能技术生成

1. 前言

ST官方提供的USB库STM32F0x2_USB-FS-Device_LibV1.0.0 是基于标准库的,适用于STM32F0x2系列MCU,但是对于STM32F070来说,就需要稍作修改,本文就一直到STM32F070作一个笔记。

2. 移植

从STM中文官网上下载STM32F0x2 USB库,地址:http://www.stmcu.org/document/detail/index/id-214961。用MDK打开,首先在Manager Project Items下的Project Targets下新增一项 “STM32F070”:

然后切换到”STM32F070”这个Target: 。此后对所有工程属性的修改都会使用于“STM32F070”,而不再是原先的“USBD_HID-STM32072B-EVAL”了。

接下来修改device为STM32F070RB:

工程配置弄好了后,接下来我们来修改代码部分。

首先我们来编译一下工程,发现此时是可以编译通过的。但是烧录到STM32F070的板子里(这里使用ST的NUCLEO-F070RB板)去时却不能成功运行。

STM32F072与STM32F070这两个MCU都有USB,且此IP没有什么不同,那么差异是什么呢?

对比它俩的时钟树:

如上图是STM32F072的时钟树,可知STM32F072是有一个内部48M的晶振,这个晶振是专门给USB提供时钟的。

如上图是STM32F070的时钟树,对比STM32F072,发现STM32F070是没有那个48M内部晶振的,因此在给USB提供晶振时,需要使用到外部晶振,于是,在代码处找到设置晶振的代码进行修改:

usb_bsp.c 的USB_BSP_Init函数内:

RCC_HSEConfig(RCC_HSE_Bypass);

/* Wait till HSE is ready */

while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET)

{}

/*Config the PREDIV for RCC_CFGR2*/

RCC_PREDIV1Config(RCC_PREDIV1_Div1);

/*HSE/PREDIV selected as PLL input clock*/

RCC_PLLConfig(RCC_PLLSource_PREDIV1,RCC_PLLMul_6);

/* Enable PLL */

RCC_PLLCmd(ENABLE);

/* Wait till PLL is ready */

while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)

{}

/*use the PLLCLK as system input clock*/

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

/* Wait till PLL is used as system clock source */

while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL)

{

}

RCC_HCLKConfig(RCC_SYSCLK_Div1);

RCC_PCLKConfig(RCC_HCLK_Div1);

/* Configure USBCLK from PLL clock */

RCC_USBCLKConfig(RCC_USBCLK_PLLCLK);

在usb_conf.h头文件中注释掉一些宏:

//#include "stm32072b_eval.h"

...

//#ifdef USE_STM32072B_EVAL

/* When using STM32072B_EVAL board the internal pullup must be enabled */

#define INTERNAL_PULLUP

//#endif

...

//#define USB_DEVICE_LOW_PWR_MGMT_SUPPORT   //关掉低功耗管理

...

//#define USB_CLOCK_SOURCE_CRS          //STM32F070下是没有CRS的

接下来整理一下systick:

void SysTick_Handler(void)

{

#if 0

uint8_t buf[4] ={0,10,10,0};

USBD_HID_SendReport (&USB_Device_dev,

buf,

4);

#endif

//#if 0

//  uint8_t *buf;

//

//  /* Get Joystick position */

//  buf = USBD_HID_GetPos();

//

//  /* Update the cursor position */

//  if((buf[1] != 0) ||(buf[2] != 0))

//  {

//    /* Send Report */

//    USBD_HID_SendReport (&USB_Device_dev,

//                         buf,

//                         4);

//  }

//#endif

TimingDelay_Decrement();

}

这个是延时函数:

void HAL_Delay(__IO uint32_t nTime)

{

TimingDelay = nTime;

while(TimingDelay != 0);

}

/**

* @brief  Decrements the TimingDelay variable.

* @param  None

* @retval None

*/

void TimingDelay_Decrement(void)

{

if (TimingDelay != 0x00)

{

TimingDelay--;

}

}

修改下systick的间隔时间:

在usbd_usr.c文件中的:

void USBD_USR_Init(void)

{

/* SysTick used for periodic check mouse position */

SysTick_Config(SystemCoreClock /1000);

}

最后在main函数内定时发送HID消息:

int main(void)

{

uint8_t buf[4] ={0,10,10,0};

/*!

this is done through SystemInit() function which is called from startup

file (startup_stm32f072.s) before to branch to application main.

To reconfigure the default setting of SystemInit() function, refer to

system_stm32f0xx.c file

*/

/* The Application layer has only to call USBD_Init to

initialize the USB low level driver, the USB device library, the USB clock

,pins and interrupt service routine (BSP) to start the Library*/

USBD_Init(&USB_Device_dev,

&USR_desc,

&USBD_HID_cb,

&USR_cb);

while (1)

{

#if 1

USBD_HID_SendReport (&USB_Device_dev,

buf,

4);

//delay

HAL_Delay(1000);

#endif

}

}

这样代码部分就完成了,通过以上main函数的代码可知,我们是每隔1S向PC端发送一次鼠标消息,鼠标会向右下角移动10个像素。

最后在NUCLEO板上测试OK!

更多资源地址:www.makeru.com.cn/?t=12

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值