stm32------系统时钟配置
Posted xugdawn666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了stm32------系统时钟配置相关的知识,希望对你有一定的参考价值。
一、概述
系统时钟,是整个芯片的心脏,如果没有了它,就等于人没有了心跳;在实际工程应用中,每当使用一个外设时,首先需要做的就是打开该外设对应的时钟;这样的好处就是,如果不使用一个外设的时候,就把它的时钟关掉,从而可以降低系统的功耗,达到节能,实现低功耗的效果(低功耗);
寄存器是由D触发器组成的,只有送来了时钟,触发器才能被改写值。任何MCU的任何外设都需要有时钟,8051也是如此;STM32为了让用户更好地掌握功耗,对每个外设的时钟都设置了开关,让用户可以精确地控制,
关闭不需要的设备,达到节省供电的目的。51单片机不用配置IO时钟,只是因为默认使用同一个时钟,这样是方便,但是这样的话功耗就降低不了。51中某个功能不需要,
但是它还是一直运行。stm32中当你想关闭某个IO的时候,关闭它相对应的时钟使能就是了;ARM的芯片都是这样,外设通常都是给了时钟后,才能设置它的寄存器(即才能使用这个外设),
这么做的目的是为了省电,使用了所谓时钟门控的技术。
二、关于时钟
1.时钟分类(stm32所有型号的时钟分为4类)
①、HSI 是高速内部时钟(High Speed Internal Clock Signal)
②、HSE是高速外部时钟(High Speed External Clock Signal)
③、LSI 是低速内部时钟(Low Speed Internal Clock Signal)
④、LSE是低速外部时钟(Low Speed External Clock Signal)
2.时钟源(stm32)
①、HSI内部高速时钟,RC振荡器,频率为8MHz,当HSE故障时,系统时钟会自动切换到HSI,直到HSE启动成功,相对HSE精度小,受温度影响较大,会有温漂。
②、HSE外部高速时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz,多使用8MHz/12MHz。
③、PLL锁相环倍频时钟,其时钟输入源可选择为HSI/2、HSE或者HSE/2。倍频可选择为2~16倍,但是其输出频率最大不得超过72MHz。
STM32具有以下两个次级时钟源:
①、LSI内部低速时钟,RC振荡器,频率为30~60kHz不等,一般取40kHz,该 RC 用于驱动独立看门狗,也可选择提供给 RTC 用于停机/待机模式下的自动唤醒。②、LSE外部低速时钟,接频率为32.768kHz的石英晶体,主要做RTC时钟源;
(使用32.768kHz是因为2的15次方为32768,32.768kHz的晶振产生的时钟信号经过15次分频后,便会产生频率为1Hz的信号,即为秒脉冲信号)
3.时钟树(stm32)
注:
1)对于不同系列的芯片,时钟树之间会存在或大或小的差异,具体需要查看手册中RCC的章节;
2)MCO接口的两个作用:其一,可以观察波形是否正常;其二,可以作为其他部件的时钟;
三、实验分析
keil软件版本:V5.35.00st官网:STM32 固件 - 意法半导体STMicroelectronics
单片机型号:STM32F103VET6
1、标准库中配置系统时钟分析
1)系统时钟配置的相关代码在这里哦
2)配置详情及描述(stm32)
/** * @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); //使能HSE,等待HSE稳定 /* Wait till HSE is ready and if Time out is reached exit */ do //等待HSE启动稳定,并做超时处理 HSEStatus = RCC->CR & RCC_CR_HSERDY; StartUpCounter++; while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); if ((RCC->CR & RCC_CR_HSERDY) != RESET) //判断HSE启动是否成功,置位标志位 HSEStatus = (uint32_t)0x01; else HSEStatus = (uint32_t)0x00; if (HSEStatus == (uint32_t)0x01) //如果HSE启动成功 /* Enable Prefetch Buffer */ FLASH->ACR |= FLASH_ACR_PRFTBE; //使能FLASH预存取缓冲区 /* Flash 2 wait state */ //SYSCLK 周期与闪存访问时间的比例设置,这里统一设置成 2 FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); //设置成 2 的时候, SYSCLK 低于 48M 也可以工作,如果设置成 0 或者 1 的时候, FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; //如果配置的 SYSCLK 超出了范围的话,则会进入硬件错误,程序就死了 //0: 0 < SYSCLK <= 24M //1: 24< SYSCLK <= 48M //2: 48< SYSCLK <= 72M //设置AHB、APB2、APB1预分频因子 /* HCLK = SYSCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; /* PCLK1 = HCLK/2 */ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; #ifdef STM32F10X_CL /* 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); #else /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC //设置PLL时钟来源,设置PLL倍频因子,PLLCLK = HSE * 9 = 72MHz | RCC_CFGR_PLLXTPRE |RCC_CFGR_PLLMULL)); RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); #endif /* STM32F10X_CL */ /* Enable PLL */ RCC->CR |= RCC_CR_PLLON; //使能PLL /* Wait till PLL is ready */ while((RCC->CR & RCC_CR_PLLRDY) == 0) //等待PLL稳定 /* Select PLL as system clock source */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); //选择PLL作为系统时钟来源 RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; /* Wait till PLL is used as system clock source */ //读取时钟切换状态位,确保PLLCLK被选为系统时钟 while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) else //如果HSE启动失败,可以在这里添加错误代码 /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */
3)另外补充一个例子(gd32)
/*! \\brief configure the system clock to 72M by PLL which selects HXTAL as its clock source \\param[in] none \\param[out] none \\retval none */ static void system_clock_72m_hxtal(void) uint32_t timeout = 0U; uint32_t stab_flag = 0U; /* enable HXTAL */ /*开启外部高速时钟*/ RCU_CTL0 |= RCU_CTL0_HXTALEN; /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */ /*等待外部高速时钟稳定,(当外部晶振稳定后,芯片将自动设置相关标志位,软件只需要不断读取这个标志位就可以知道时钟是否稳定)*/ do timeout++; stab_flag = (RCU_CTL0 & RCU_CTL0_HXTALSTB); while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); /* if fail 若外部高速时钟异常,上面等待超时,进入这里*/ if(0U == (RCU_CTL0 & RCU_CTL0_HXTALSTB)) return; /*运行到这里,说明外部高速时钟正常启动,下面按照时钟树,来配置系统和各个模块的时钟*/ /* HXTAL is stable */ /* AHB = SYSCLK */ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; //系统时钟到AHB总线时钟不进行分频 /* APB2 = AHB/2 */ RCU_CFG0 |= RCU_APB2_CKAHB_DIV2; //APB2是AHB的2分频 /* APB1 = AHB/2 */ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; //APB1是AHB的2分频 /* PLL = HXTAL * 6 = 72 MHz */ /*现在外部晶振是12M,通过PLL倍频为72M*/ RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PLLMF | RCU_CFG0_PLLMF4 | RCU_CFG0_PLLPREDV); RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PLLMF5 | RCU_CFG1_PREDV); RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | (RCU_PLL_MUL6 & (~RCU_CFG1_PLLMF5))); //PLLSEL设置为1,PLL设置为6 // RCU_CFG0 |= (RCU_CFG0_PLLPREDV); //HXTAL或CK_IRC48M时钟二分频 (CFG0第17位,与CFG1中的PREDV[0]位是一样的) RCU_CFG1 |= (RCU_PLLPRESEL_HXTAL); //HXTAL选为PLL时钟源 PREDV 选择1分频 RCU_CFG1 |= (RCU_PLL_MUL6 & RCU_CFG1_PLLMF5); //PLLMF的第五位设置为0 /* enable PLL */ /*上面的配置完成,使能PLL*/ RCU_CTL0 |= RCU_CTL0_PLLEN; /* wait until PLL is stable */ while(0U == (RCU_CTL0 & RCU_CTL0_PLLSTB)) /* select PLL as system clock */ /*设置SCS[1:0],将时钟切换到刚配置好的PLL这条系统时钟线路*/ RCU_CFG0 &= ~RCU_CFG0_SCS; RCU_CFG0 |= RCU_CKSYSSRC_PLL; /* wait until PLL is selected as system clock */ /*等待PLL这条系统时钟配置能稳定给系统提供时钟*/ while(0U == (RCU_CFG0 & RCU_SCSS_PLL)) /*到此处,系统完成了从8M到200M的切换*/
2、重新定义并初始化函数
由上文代码可知,程序运行起来会首先执行启动文件,调用systeminit()函数,最终初始化系统时钟;如需改变时钟配置,可以在系统时钟配置文件中修改;但是为了不破坏库函数的完整性,可重新定义并调用初始化函数;
一般情况下,使用HSE经分频倍频后来配置系统时钟;
1)以HSE配置系统时钟为例,按照时钟树流程来完成函数:
/** * @brief HSE_SetSysClk program. * @param RCC_PLLMul_x: specifies the PLL multiplication factor[2~16] * @retval None */ void HSE_SetSysClk(uint32_t RCC_PLLMul_x) ErrorStatus HSEStatus; RCC_DeInit(); //把RCC寄存器复位 RCC_HSEConfig(RCC_HSE_ON); //使能HSE HSEStatus = RCC_WaitForHSEStartUp(); //等待HSE稳定,返回HSE状态 if(HSEStatus == SUCCESS) /*预取缓冲器包含两个数据块,每个数据块有8个字节; 预取指令(数据)块直接映像到闪存中, 因为数据块的大小与闪存的宽度相同, 所以读取预取指令块可以在一个读周期完成; 设置预取缓冲器可以使CPU更快地执行, CPU读取一个字的同时下一个字已经在预取缓冲器中等候, 即当代码跳转的边界为8字节的倍数时, 闪存的加速比例为2; flash等待周期数要系统时钟频率对应, 《stm32f10xxx闪存编程手册》中可以进行了解 */ FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //使能预取指 FLASH_SetLatency(FLASH_Latency_2); //2个等待周期 RCC_HCLKConfig(RCC_SYSCLK_Div1); //配置AHB总线时钟HCLK RCC_PCLK1Config(RCC_HCLK_Div2); //配置APB1总线时钟PCLK1,PCLK1 = HCLK/2 RCC_PCLK2Config(RCC_HCLK_Div1); //配置APB2总线时钟PCLK2,PCLK2 = HCLK RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_x); //配置锁相环时钟(PLLCLK = HSE * RCC_PLLMul_x = 72MHz),RCC_PLLMul_x为倍频因子,PLL需要先配置再使能 RCC_PLLCmd(ENABLE); //使能PLL while(RESET == RCC_GetFlagStatus(RCC_FLAG_PLLRDY)); //等待PLL稳定 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //选择PLLCLK为系统时钟 while(0x08 != RCC_GetSYSCLKSource()); //等待PLLCLK置位系统时钟完成 else /*如果HSE启动失败,可以在这里添加处理错误的代码*/ /*在main中调用即可*/ /** * @brief Main program. * @param None * @retval None */ int main(void) LED_GPIO_Config(); HSE_SetSysClk(RCC_PLLMul_9); // HSI_SetSysClk(RCC_PLLMul_16); MCO_GPIO_Config(); RCC_MCOConfig(RCC_MCO_SYSCLK); for(;;) LED1_TOGGLE; Delay(0xFFFFF); LED1_TOGGLE; Delay(0xFFFFF);
/** * @brief MCO_GPIO_Config program. * @param void * @retval enable mco for see clock */ void MCO_GPIO_Config() GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); RCC_MCOConfig(RCC_MCO_SYSCLK);
2)以HSI作为系统时钟
/** * @brief HSI_SetSysClk program. * @param RCC_PLLMul_x: specifies the PLL multiplication factor[2~16] * @retval None */ void HSI_SetSysClk(uint32_t RCC_PLLMul_x) __IO uint32_t HSIStatus = 0; //加 __IO 防止编译器优化 RCC_DeInit(); //把RCC寄存器复位 // RCC_HSICmd(ENABLE); //使能HSI,复位时候已经使能了HSI,这里可以不再使能 HSIStatus = RCC->CR & RCC_CR_HSIRDY; //等待HSI稳定,读取hsirdy寄存器 if(HSIStatus == RCC_CR_HSIRDY) /*预取缓冲器包含两个数据块,每个数据块有8个字节; 预取指令(数据)块直接映像到闪存中, 因为数据块的大小与闪存的宽度相同, 所以读取预取指令块可以在一个读周期完成; 设置预取缓冲器可以使CPU更快地执行, CPU读取一个字的同时下一个字已经在预取缓冲器中等候, 即当代码跳转的边界为8字节的倍数时, 闪存的加速比例为2; flash等待周期数要系统时钟频率对应, 《stm32f10xxx闪存编程手册》中可以进行了解 */ FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //使能预取指 FLASH_SetLatency(FLASH_Latency_2); //2个等待周期 RCC_HCLKConfig(RCC_SYSCLK_Div1); //配置AHB总线时钟HCLK RCC_PCLK1Config(RCC_HCLK_Div2); //配置APB1总线时钟PCLK1,PCLK1 = HCLK/2 RCC_PCLK2Config(RCC_HCLK_Div1); //配置APB2总线时钟PCLK2,PCLK2 = HCLK RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_x); //配置锁相环时钟(PLLCLK = HSI * RCC_PLLMul_x = 64MHz),RCC_PLLMul_x为倍频因子,PLL需要先配置再使能 RCC_PLLCmd(ENABLE); //使能PLL while(RESET == RCC_GetFlagStatus(RCC_FLAG_PLLRDY)); //等待PLL稳定 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //选择PLLCLK为系统时钟 while(0x08 != RCC_GetSYSCLKSource()); //等待PLLCLK置位系统时钟完成 else /*如果HSI启动失败,可以在这里添加处理错误的代码*/
四、总结
系统时钟配置需要根据具体的时钟框图,先设置好时钟源,AHB、APB1、APB2的分频系数;再设置好PLL倍频和分频;最后使用SW切换选择系统时钟来源即可。
参考:
1、《STM32F10X-中文参考手册》2、[野火EmbedFire]《STM32库开发实战指南——基于野火指南者开发板》;
3、野火F103-指南者bilibili教程视频【150集-野火F103霸道/指南者视频教程】-中级篇_哔哩哔哩_bilibili;
4、32系统时钟配置 - Darren_pty - 博客园 (cnblogs.com)
5、STM32F4_RCC系统时钟配置及描述 - strongerHuang - 博客园 (cnblogs.com)
6、STM32F2系列系统时钟默认配置 - MyBooks - 博客园 (cnblogs.com)
7、STM32入门系列-STM32时钟系统,时钟使能配置函数 - STM32嵌入式开发 - 博客园 (cnblogs.com)
小弟才疏学浅,如有错误或不足之处,还请大佬批评指正,深表感谢!
STM32F4_RCC系统时钟配置及描述
Ⅰ、概述
对于系统时钟应该都知道它的作用,就是驱动整个芯片工作的心脏,如果没有了它,就等于人没有了心跳。
对于使用开发板学习的朋友来说,RCC系统时钟这一块知识估计没怎么去配置过,原因在于开发板提供的晶振基本上都是官方标准的时钟频率,使用官方的标准库,这样系统时钟就是默认的配置,也就是默认的频率。但对于自己设计开发板,或者想要改变系统时钟频率(如:降低功耗就需要降频)的朋友来说,配置系统时钟就有必要了。
关于时钟这一块对定时器(TIM、RTC、WDG等)相关的外设也比较重要,因为要求精准,就需要时钟频率精准。
该文将描述关于系统时钟配置及注意的相关事项,更多详情内容,请往下看。
本着免费分享的原则,方便大家手机学习知识,定期在微信平台分享技术知识。如果你觉得分享的内容对你有用,又想了解更多相关的文章,请用微信搜索“EmbeddDeveloper” 或者扫描下面二维码、关注,将有更多精彩内容等着你。
Ⅱ、关于时钟
1.时钟分类
STM32芯片(所有型号)的时钟包含4类:
HSE(High Speed External)高速外部时钟
HSI(High Speed Internal)高速内部时钟
LSE(Low Speed External)低速外部时钟
LSI(Low Speed Internal)低速内部时钟
2.时钟源
STM32芯片(所有型号)驱动系统时钟的时钟源:
HSI 内部高速时钟
HSE 外部高速时钟
PLLCLK倍频时钟
STM32具有以下两个次级时钟源:
32 kHz 低速内部 RC (LSI RC),该 RC 用于驱动独立看门狗,也可选择提供给 RTC 用于停机/待机模式下的自动唤醒。
32.768 kHz 低速外部晶振( LSE 晶振),用于驱动 RTC 时钟 (RTCCLK)。对于每个时钟源来说,在未使用时都可单独打开或者关闭,以降低功耗。
3.时钟树(框图)
关于STM32的时钟树针对不同系列芯片可能存在差异。F0、F1和F3系列芯片(主流芯片,频率相对较低)有很多相似的地方,F2和F4(高性能芯片)系列芯片有很多相似的地方。但是,F3芯片和F4芯片的时钟树之间却存在很大差异,具体请看参考手册RCC相关章节。
STM32时钟控制器为应用带来了高度的灵活性,用户在运行内核和外设时可选择使用外部晶振或者使用振荡器,既可采用最高的频率,也可为以太网、 USB OTG FS 以及 HS、 I2S 和 SDIO等需要特定时钟的外设保证合适的频率。
以F417芯片为例:可通过多个预分频器配置 AHB 频率、高速 APB (APB2) 和低速 APB (APB1)。 AHB 域的最大频率为 168 MHz。高速 APB2 域的最大允许频率为 84 MHz。低速 APB1 域的最大允许频率为 42 MHz。实际上输出的最大时钟可以适当提高一点,但为了保证在多种环境下,最好还是不要超过标准的最大值。
STM32F4xx 器件具有两个 PLL:
主 PLL (PLL) 由 HSE 或 HSI 振荡器提供时钟信号,并具有两个不同的输出时钟:
第一个输出用于生成高速系统时钟(最高达 168 MHz)
第二个输出用于生成 USB OTG FS 的时钟 (48 MHz)、随机数发生器的时钟
专用 PLL (PLLI2S) 用于生成精确时钟,从而在 I2S 接口实现高品质音频性能。
由于在 PLL 使能后主 PLL 配置参数便不可更改,所以建议先对 PLL 进行配置,然后再使能(选择 HSI 或 HSE 振荡器作为 PLL 时钟源,并配置分频系数 M、 N、 P 和 Q)。
PLLI2S 使用与 PLL 相同的输入时钟( PLLM[5:0] 和 PLLSRC 位为两个 PLL 所共用)。但是, PLLI2S 具有专门的使能/禁止和分频系数( N 和 R)配置位。在 PLLI2S 使能后,配置参数便不能更改。
Ⅲ、代码分析
以STM32F4x5、x7系列芯片为例来分析一下系统时钟的配置。
参考软件工程:
https://yunpan.cn/cRepWDShSK4yc 访问密码 65b1
1.倍频参数
结合上面时钟树和源代码可以看得出来,系统时钟PLLCLK的计算主要是配置PLL_M、PLL_N、PLL_P这三个参数,最后168M是通过分频、倍频得出来的。
2.验证时钟频率
对于STM32芯片来说,验证系统时钟最终运行多大的速度,最准确的验证方法的用示波器测试它的系统时钟。
这里描述一下怎样用示波器来测试系统时钟。其实很简单,就是在软件代码里面配置时钟输出(这里可以输出多种类型的时钟HSE、HSI、PLLCLK等),根据代码配置不同,相应输出的时钟就不同。请看源代码:
我提供的代码里面就有这一选项,将定义配置为1,就打开了这个功能。时钟输出的参数有两个,时钟源,分频值。注意:这里的最大输出时钟是100M,所以PLLCLK时钟分频之后才能输出,不然你用示波器检测不到波形(我测试过了)。
最后输出的波形如图:
Ⅳ、说明
关于STM32的开发,软件兼容性是很好的,不要觉得你的芯片和我总结的实例有差异就不看了,其实是错误的认识,特别是同一个系列的芯片基本上程序都兼容,也就是可以互相使用。
以上总结仅供参考,若有不对之处,敬请谅解。
Ⅴ、最后
关注微信,回复“更多内容”,将获得更多内容(如:UCOS实例等,不断更新中......)。
如果你喜欢我分享的内容,你又想了解更多相关内容,请关注文章开头的微信公众号,新内容持续更新中,后期将会有更多精彩内容出现。
以上是关于stm32------系统时钟配置的主要内容,如果未能解决你的问题,请参考以下文章
STM32F103想用内部时钟HSI做为系统时钟,怎么配置成36M