本帖最后由 Dylan疾风闪电 于 2018-8-9 15:39 编辑
使用举例:配置72MHZ时钟作为系统时钟#define SystemClockMHz 72//MHZ
HW_SystemClockMux(USE_EXTERNAL_HSE, SystemClockMHz) ;
HW_SystemClockMux(USE_INTERNAL_HSI, SystemClockMHz);
---------------------------------------------------------------------------------------------
代码已验证。发个帖子,便于自己移植使用。
- /* Const to source of high speed clock:internal or external. */
- #define USE_EXTERNAL_HSE 0
- #define USE_INTERNAL_HSI 1
- /**
- * <b>配製系統主時鐘頻率。</b>
- * <p>功能:選擇時鐘源,并進行PLL倍頻。
- * @param osc 高速時鐘源的選擇。
- * @arg USE_EXTERNAL_HSE: 外部高速晶振
- * @arg USE_INTERNAL_HSI: 內部高速晶振
- * @param maxFreq 芯片最大主频?M,查询对应的数据手册
- * @return osc
- * @version 2.0.0.0(20160407)
- * <p-2014>实现CM0与CM3兼容完成!
- * <p-2016>對字符串/單詞進行變更。
- * @author Dylan
- */
- uint8_t HW_SystemClockMux(uint8_t osc, uint8_t maxFreq)
- {
- #if defined (STM32F100) || defined (STM32F101) || defined (STM32F103)
- uint8_t errCode = 0xff;
- uint32_t sTimeCount, sTimeMax = 0xFFF;
- #endif
-
- HW_SystemPowerON();
-
- switch(osc)
- {
- case USE_EXTERNAL_HSE:
- #if defined (STM32F100) || defined (STM32F101) || defined (STM32F103)
- RCC->CR |= 1<<16; //HSEON
-
- sTimeCount = sTimeMax;
- while(((RCC->CR>>17) & 0x1) == 0) //等待HSE就绪
- {
- if (sTimeCount--) return errCode;
- }
-
- RCC->CFGR |= (maxFreq/8-2)<<18; //设置PLL值倍频//HSE 8MHz
-
- RCC->CFGR |= 1<<16; //切换PLL输入时钟源为0->1:HSI/2(4MHz)->HSE(8MHz)
-
- //存在等待状态时,必须先开启预取缓冲区
- if (maxFreq <= 24)
- FLASH->ACR |= 0x30;//000:零等待状态,当 0 < SYSCLK ≤ 24MHz
- else if (maxFreq <= 48)
- FLASH->ACR |= 0x31;//001:一个等待状态,当 24MHz < SYSCLK ≤ 48MHz
- else
- FLASH->ACR |= 0x32;//010:两个等待状态,当 48MHz < SYSCLK ≤ 72MHz
-
- RCC->CR |= 1<<24; //PLLON
-
- sTimeCount = sTimeMax;
- while(((RCC->CR>>25) & 0x1) == 0) //等待PLL就绪
- {
- if (sTimeCount--) return errCode;
- }
-
- RCC->CFGR |= 0x2; //PLL作为sysClk
-
- sTimeCount = sTimeMax;
- while(((RCC->CFGR>>2) & 0x3) != 0x02) //等待sysClk就绪
- {
- if (sTimeCount--) return errCode;
- }
- #elif defined (STM32F051) || defined (STM32F042) //none
- #else
- #warning "Make sure needn't define STM32Fxxx etc. ?"
- #endif
- break;
- default: //case USE_INTERNAL_HSI:
- RCC->CFGR &= 0xFFFEFFFF; //HSI 8MHz/2
- RCC->CFGR |= ((maxFreq>>2)-2)<<18; //设置PLL值倍频
-
- //存在等待状态时,必须先开启预取缓冲区
- if (maxFreq <= 24)
- FLASH->ACR |= 0x30;//000:零等待状态,当 0 < SYSCLK ≤ 24MHz
- else if (maxFreq <= 48)
- FLASH->ACR |= 0x31;//001:一个等待状态,当 24MHz < SYSCLK ≤ 48MHz
- else
- FLASH->ACR |= 0x32;//010:两个等待状态,当 48MHz < SYSCLK ≤ 72MHz
-
- RCC->CR |= 1<<24; //PLLON
- while(((RCC->CR>>25) & 0x1) != 1); //等待PLL就绪
- RCC->CFGR |= 0x2; //PLL作为sysClk
- while(((RCC->CFGR>>2)&0x3) != 0x02); //等待sysClk就绪
- break;
- }
-
- return 0;
- }
- /**
- * <b>芯片上电默认时钟配置。</b>
- * <p>功能:用来恢复时钟系统到上电默认状态。
- * @version 1.1.0.0(20140228)
- * <p-2014>实现CM0与CM3兼容完成!
- * @author Dylan
- */
- void HW_SystemPowerON(void)
- {
- #if defined (STM32F051) || defined (STM32F042)
- RCC->CR |= 0x00000001;//HSION
- RCC->CR &= 0x0202FFFF;/* Reset HSEON, CSSON and PLLON, HSEBYP bit */
- RCC->CFGR &= 0x0000000C;/* Reset SW[1:0], HPRE[3:0], PPRE[2:0], ADCPRE and MCOSEL[2:0],PLLSRC, PLLXTPRE and PLLMUL[3:0] bits */
- RCC->CFGR2 &= 0x00000000;/* Reset PREDIV1[3:0] bits *///与CFGR[17]一起用作HSE-PLL设置
- RCC->CFGR3 &= 0x00000000;/* Reset USARTSW[1:0], I2CSW, CECSW and ADCSW bits */
- RCC->CR2 &= 0xFFFFFFFE;/* Reset HSI14 bit */
- RCC->CIR = 0x00000000;/* Disable all interrupts */
- #elif defined (STM32F100) || defined (STM32F101) || defined (STM32F103)
- RCC->CR &= 0x0000FF83;//把HSI调整到8MHz±1%==》开启HSI==》等待就绪
- RCC->CFGR = 0x00000400;//限制APB1时钟是HCLK_Div2
- RCC->CIR = 0x00BF0000;//清除所有的RCC中断标志
- //配置向量表
- #ifdef VECT_TAB_RAM
- /* Set the Vector Table base location at 0x20000000 */
- NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
- #else /* VECT_TAB_FLASH */
- /* Set the Vector Table base location at 0x08000000 */
- NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
- #endif
- #else
- #warning "Make sure needn't define STM32F051 etc. ?"
- #endif
- }
复制代码
|