基于官方库的STM32操作U盘注意的问题

发布者:心想的45号最新更新时间:2019-06-12 来源: eefocus关键字:官方库  STM32  操作U盘 手机看文章 扫描二维码
随时随地手机看文章

前几天调试了stm32f105基于官方库STM32_USB-Host-Device_Lib_V2.2.0的示例代码读取优盘,调试成功。 

在官方库文件STM32_USB-Host-Device_Lib_V2.2.0下Project/USB_Host_Examples/MSC,打开工程。根据你的外部晶振,需要修改系统频率和USB时钟设置。 

我用的外部晶振是8M的为例,打开文件system_stm32f10x.c文件,找到函数static void SetSysClockTo72(void) 

以下为源码


/**

  * @brief  Sets System clock frequency to 72MHz and configure HCLK, PCLK2 

  *          and PCLK1 prescalers. 

  * @note   This function should be used only after reset.

  * @param  None

  * @retval None

  */

static void SetSysClockTo72(void)

{

    __IO uint32_t StartUpCounter = 0, HSEStatus = 0;


    /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    

    /* Enable HSE */    

    RCC->CR |= ((uint32_t)RCC_CR_HSEON);


    /* Wait till HSE is ready and if Time out is reached exit */

    do

    {

        HSEStatus = RCC->CR & RCC_CR_HSERDY;

        StartUpCounter++;  

    } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));


    if ((RCC->CR & RCC_CR_HSERDY) != RESET)

    {

        HSEStatus = (uint32_t)0x01;

    }

    else

    {

        HSEStatus = (uint32_t)0x00;

    }  


    if (HSEStatus == (uint32_t)0x01)

    {

        /* Enable Prefetch Buffer */

        FLASH->ACR |= FLASH_ACR_PRFTBE;


        /* Flash 2 wait state */

        FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);

        FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;    



        /* HCLK = SYSCLK */

        RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;


        /* PCLK2 = HCLK */

        RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;


        /* PCLK1 = HCLK */

        RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;


        /* Configure PLLs ------------------------------------------------------*/

        /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */

        /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */


        RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |

                                  RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);

        RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |

                                 RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);


        /* Enable PLL2 */

        RCC->CR |= RCC_CR_PLL2ON;

        /* Wait till PLL2 is ready */

        while((RCC->CR & RCC_CR_PLL2RDY) == 0)

        {

        }



        /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ 

        RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);

        RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 

                                RCC_CFGR_PLLMULL9); 

        /* Enable PLL */

        RCC->CR |= RCC_CR_PLLON;


        /* Wait till PLL is ready */

        while((RCC->CR & RCC_CR_PLLRDY) == 0)

        {

        }


        /* Select PLL as system clock source */

        RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));

        RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    


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

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

        {

        }

    }

    else

    { /* If HSE fails to start-up, the application will have wrong clock 

         configuration. User can add here some code to deal with this error */

    }

}


修改为下面代码


/**

  * @brief  Sets System clock frequency to 72MHz and configure HCLK, PCLK2 

  *          and PCLK1 prescalers. 

  * @note   This function should be used only after reset.

  * @param  None

  * @retval None

  */

static void SetSysClockTo72(void)

{

    __IO uint32_t StartUpCounter = 0, HSEStatus = 0;


    /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/    

    /* Enable HSE */    

    RCC->CR |= ((uint32_t)RCC_CR_HSEON);


    /* Wait till HSE is ready and if Time out is reached exit */

    do

    {

        HSEStatus = RCC->CR & RCC_CR_HSERDY;

        StartUpCounter++;  

    } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));


    if ((RCC->CR & RCC_CR_HSERDY) != RESET)

    {

        HSEStatus = (uint32_t)0x01;

    }

    else

    {

        HSEStatus = (uint32_t)0x00;

    }  


    if (HSEStatus == (uint32_t)0x01)

    {

        /* Enable Prefetch Buffer */

        FLASH->ACR |= FLASH_ACR_PRFTBE;


        /* Flash 2 wait state */

        FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);

        FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;    



        /* HCLK = SYSCLK */

        RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;


        /* PCLK2 = HCLK */

        RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;


        /* PCLK1 = HCLK */

        RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;


        /* Configure PLLs ------------------------------------------------------*/

        //40=8/2*10 修改后

        /* PLL2 configuration: PLL2CLK = (HSE / 2) * 10 = 40 MHz */

        /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */


        RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |

                                  RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);

        //RCC_CFGR2_PREDIV2_DIV2 | RCC_CFGR2_PLL2MUL10修改后

        RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV2 | RCC_CFGR2_PLL2MUL10 |

                                 RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);


        /* Enable PLL2 */

        RCC->CR |= RCC_CR_PLL2ON;

        /* Wait till PLL2 is ready */

        while((RCC->CR & RCC_CR_PLL2RDY) == 0)

        {

        }



        /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ 

        RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);

        RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 

                                RCC_CFGR_PLLMULL9); 

        /* Enable PLL */

        RCC->CR |= RCC_CR_PLLON;


        /* Wait till PLL is ready */

        while((RCC->CR & RCC_CR_PLLRDY) == 0)

        {

        }


        /* Select PLL as system clock source */

        RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));

        RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    


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

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

        {

        }

    }

    else

    { /* If HSE fails to start-up, the application will have wrong clock 

         configuration. User can add here some code to deal with this error */

    }

}


关键字:官方库  STM32  操作U盘 引用地址:基于官方库的STM32操作U盘注意的问题

上一篇:STM32 USB虚拟串口调试总结
下一篇:STM32F103C8T6使用MDK 4.12中Custom_HID的修改方法

推荐阅读最新更新时间:2024-11-13 11:41

STM32 串口例程之查询收发
有了STM32,使用串口简直就是玩游戏的感觉。这里鄙人就不谈STM32串口的happy了,直接上代码,读者从代码中体会乐趣。发送接受均采用查询方式,串口调试工具使用超级终端或者这货--SecureCRT 5.5(传说比超级终端还超级),在中端里面输入什么,同步接受与发送,感觉就像是在文本框里面打字。 还是甩一张工程结构图正面: 代码鄙人偷懒,所有代码在main.c里面一锅煮:
[单片机]
STM32 ADC多通道DMA传输
ADC多通道采集是在ADC单通道DMA传输的基础上写的,代码如下: volatile u16 adcconverdata ={0,0}; static void ADC_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_2;//添加PA2的GPIO初始化代码 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN; GPIO_Init(
[单片机]
STM32 之 外部开门狗(iwdg)
独立看门狗(IWDG)由专用的40kHz的低速时钟驱动, 即使主时钟发生故障它也仍然有效。 窗口看门狗由从APB1时钟分频后得到的时钟驱动, 通过可配置的时间窗口来检测应用程序非正常的过迟或过早的操作。 IWDG最适合应用于那些需要看门狗作为一个在主程序之外, 能够完全独立工作,并且对时间精度要求较低的场合。 WWDG最适合那些要求看门狗在精确计时窗口起作用的应用程序 IWDG主要性能 ●自由运行的递减计数器 ●时钟由独立的RC振荡器提供(可在停止和待机模式下工作) ●看门狗被激活后,则在计数器计数至0x000时产生复位 下面是使用代码: C语言: Codee#18865 void LSI_RCC_Co
[单片机]
<font color='red'>STM32</font> 之 外部开门狗(iwdg)
STM32开发笔记61: 解决Undefined symbol ethernetif_init (referred from lwip.
单片机型号:STM32F407VGT6 在STM32开发笔记60: 在STM32CubeMX中配置LwIP文章的基础上进行分层设计,将与用户设计相关的文件挑出来单独建立一个工程,此工程使用CPP11进行生成,在链接的时候提示错误。 挑出的与用户逻辑相关的文件如下图所示: 错误如下图所示: ethernetif_init函数出现在ethernetif.c文件中,代码如下。 err_t ethernetif_init(struct netif *netif) { LWIP_ASSERT( netif != NULL , (netif != NULL)); #if LWIP_NETIF_HOSTNA
[单片机]
<font color='red'>STM32</font>开发笔记61: 解决Undefined symbol ethernetif_init (referred from lwip.
STM32片上外设时钟使能 失能和复位的区别
今天分享的关于时钟知识,可能很多人没有在意过。这也是之前有朋友问过的问题,这里就简单给大家普及一下吧。 1 RCC时钟说明 在STM32参考手册中,都有Reset and Clock Control(RCC)复位和时钟控制的章节。 在这一章节就可以看到有两类寄存器:peripheral reset register(RSTR)外设复位寄存器和peripheral clock enable register(ENR)外设时钟使能寄存器。 我们拿STM32F1参考手册为例,可以看到如下图寄存器: 一种是控制外设时钟的寄存器,一种是复位外设的寄存器。 2 外设时钟使能和失能 我们都知道,配置STM32外设,会先开启对应的时钟
[单片机]
<font color='red'>STM32</font>片上外设时钟使能 失能和复位的区别
STM32 触摸屏触摸功能
要用到触摸屏首先就要对触摸屏的原理有一定的了解,我想这个是前提,也不用太多说的。就是当触笔触到屏上时,对应的位置就会产生相应大小的电压,输入到芯片,AD转换后得到一个数据。而触摸校准就是将接受到的原始模数转换值转换成屏幕像素坐标。 再就是了解触摸芯片,知道他的工作方式,以及跟STM32的连线。触摸实验中,我的实验板是用SPI口来实现数据的传输的,即SPI与xpt2046相连。 触摸屏控制芯片ADS7843中文资料 ADS7843是一个内置12位模数转换、低导通电阻模拟开关的串行接口芯片。供电电压2.7~5 V,参考电压VREF为1 V~+VCC,转换电压的输入范围为0~ VREF,最高转换速率为125 kHz。 ADS
[单片机]
<font color='red'>STM32</font> 触摸屏触摸功能
STM32通过IIC读写EEPROM(24C02)
STM32作为主机I2C,读写24C02 EEPROM 1、 时钟和数据的传输:开始和停止条件,数据在SCL的高电平期间有效,在SCL的低电平期间改变。 2、 开始条件:在SCL高电平期间,SDA产生一个下降沿 3、 停止条件:在SCL高电平期间,SDA产生一个上升沿 4、 应答:成功接收到数据(地址和数据),产生一个应答位(在第9个时钟周期,将SDA拉低) 下面是源程序:原理上说,下面程序再移植时,只要将数据类型变化,可以应用到任何处理器 AT24c02.h #ifndef __24CXX_H #define __24CXX_H #include i2c.h /*********************************
[单片机]
STM32 assert_param
在STM32的固件库和提供的例程中,到处都可以见到assert_param()的使用。如果打开任何一个例程中的stm32f10x_conf.h文件,就可以看到实际上assert_param是一个宏定义;在固件库中,它的作用就是检测传递给函数的参数是否是有效的参数。 所谓有效的参数是指满足规定范围的参数,比如某个参数的取值范围只能是小于3的正整数,如果给出的参数大于3,则这个assert_param()可以在运行的程序调用到这个函数时报告错误,使程序员可以及时发现错误,而不必等到程序运行结果的错误而大费周折。 这是一种常见的软件技术,可以在调试阶段帮助程序员快速地排除那些明显的错误。 它确实在程序的运行上牺牲了效率(但只
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved