STM32F4时钟配置

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/louyangyang91/article/details/51542943

看了下时钟树按照http://blog.csdn.net/louyangyang91/article/details/51374924这个博文配置了,结果发现UART波特率不对,但是MOC1\2都是正常输出(168M/5分频输出),蒙了很久才发现 USART_Init(USART1, &USART_InitStructure); 这个函数内部会调用RCC_GetClocksFreq(&RCC_ClocksStatus);这个函数来得到PCLK1\PCLK2等系统时钟,进入这个函数看其内部发现它调用了一个

HSE_VALUE的宏定义,继续定位发现居然是
#if !defined  (HSE_VALUE) 
  #define HSE_VALUE    ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
8M的频率。果断改成我使用的外部晶振12M,然后配置PLL系统时钟168M,再看UART波特率对了。问题解决、、、、
的void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)
{
  uint32_t tmp = 0, presc = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2;

  /* Get SYSCLK source -------------------------------------------------------*/
  tmp = RCC->CFGR & RCC_CFGR_SWS;

  switch (tmp)
  {
    case 0x00:  /* HSI used as system clock source */
      RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
      break;
    case 0x04:  /* HSE used as system clock  source */
      RCC_Clocks->SYSCLK_Frequency = HSE_VALUE;
      break;
    case 0x08:  /* PLL used as system clock  source */

      /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN
         SYSCLK = PLL_VCO / PLLP
         */    
      pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22;
      pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
      
      if (pllsource != 0)
      {
        /* HSE used as PLL clock source */
        pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
      }
      else
      {
        /* HSI used as PLL clock source */
        pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);      
      }

      pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2;
      RCC_Clocks->SYSCLK_Frequency = pllvco/pllp;
      break;
    default:
      RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
      break;
  }
  /* Compute HCLK, PCLK1 and PCLK2 clocks frequencies ------------------------*/

  /* Get HCLK prescaler */
  tmp = RCC->CFGR & RCC_CFGR_HPRE;
  tmp = tmp >> 4;
  presc = APBAHBPrescTable[tmp];
  /* HCLK clock frequency */
  RCC_Clocks->HCLK_Frequency = RCC_Clocks->SYSCLK_Frequency >> presc;

  /* Get PCLK1 prescaler */
  tmp = RCC->CFGR & RCC_CFGR_PPRE1;
  tmp = tmp >> 10;
  presc = APBAHBPrescTable[tmp];
  /* PCLK1 clock frequency */
  RCC_Clocks->PCLK1_Frequency = RCC_Clocks->HCLK_Frequency >> presc;

  /* Get PCLK2 prescaler */
  tmp = RCC->CFGR & RCC_CFGR_PPRE2;
  tmp = tmp >> 13;
  presc = APBAHBPrescTable[tmp];
  /* PCLK2 clock frequency */
  RCC_Clocks->PCLK2_Frequency = RCC_Clocks->HCLK_Frequency >> presc;
}

下面贴出时钟配置代码:

void SetSysClockProc(void)
{
	ErrorStatus HSEStartUpStatus;
					 
	RCC_DeInit();                                
					
	RCC_HSEConfig(RCC_HSE_ON);        
						 
	HSEStartUpStatus = RCC_WaitForHSEStartUp();        
					 
	if(HSEStartUpStatus==SUCCESS)                        
	{    
			RCC_HCLKConfig(RCC_SYSCLK_Div1);        

			RCC_PCLK1Config(RCC_HCLK_Div4);                

			RCC_PCLK2Config(RCC_HCLK_Div2);                
									
			FLASH_SetLatency(FLASH_Latency_5);        

			FLASH_PrefetchBufferCmd(ENABLE); 

			//RCC_ADCCLKConfig(RCC_PCLK2_Div2);
									
			RCC_PLLConfig(RCC_PLLSource_HSE,12,336,2,7);//168M

			RCC_PLLCmd(ENABLE);

			while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
			{
			}    

		 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); 

	//  while(RCC_GetSYSCLKSource()!=0x08)
	//    {
	//    }
	}   

}


猜你喜欢

转载自blog.csdn.net/louyangyang91/article/details/51542943