GD32设置时钟108M方法

[复制链接]
6070|6
手机看帖
扫描二维码
随时随地手机跟帖
listentoenglish|  楼主 | 2013-7-15 07:55 | 显示全部楼层 |阅读模式
本帖最后由 listentoenglish 于 2013-7-15 08:01 编辑

将system_stm32f10x.c替换为system_gd32f10x.c。
#define SYSCLK_FREQ  108000000UL修改时钟主频。
#include "stm32f10x.h"

//==============================================================================
//设置主频
#define SYSCLK_FREQ  108000000UL

//以下不用更改
//==============================================================================
#define RCC_CFGR_PLLMULL17 (0x08000000UL|RCC_CFGR_PLLMULL2)
#define RCC_CFGR_PLLMULL18 (0x08000000UL|RCC_CFGR_PLLMULL3)
#define RCC_CFGR_PLLMULL19 (0x08000000UL|RCC_CFGR_PLLMULL4)
#define RCC_CFGR_PLLMULL20 (0x08000000UL|RCC_CFGR_PLLMULL5)
#define RCC_CFGR_PLLMULL21 (0x08000000UL|RCC_CFGR_PLLMULL6)
#define RCC_CFGR_PLLMULL22 (0x08000000UL|RCC_CFGR_PLLMULL7)
#define RCC_CFGR_PLLMULL23 (0x08000000UL|RCC_CFGR_PLLMULL8)
#define RCC_CFGR_PLLMULL24 (0x08000000UL|RCC_CFGR_PLLMULL9)
#define RCC_CFGR_PLLMULL25 (0x08000000UL|RCC_CFGR_PLLMULL10)
#define RCC_CFGR_PLLMULL26 (0x08000000UL|RCC_CFGR_PLLMULL11)
#define RCC_CFGR_PLLMULL27 (0x08000000UL|RCC_CFGR_PLLMULL12)
#define RCC_CFGR_PLLMULL28 (0x08000000UL|RCC_CFGR_PLLMULL13)
#define RCC_CFGR_PLLMULL29 (0x08000000UL|RCC_CFGR_PLLMULL14)
#define RCC_CFGR_PLLMULL30 (0x08000000UL|RCC_CFGR_PLLMULL15)
#define RCC_CFGR_PLLMULL31 (0x08000000UL|RCC_CFGR_PLLMULL16)
#define RCC_CFGR_PLLMULL32 (0x08040000UL|RCC_CFGR_PLLMULL16)

#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
/* #define DATA_IN_ExtSRAM */
#endif

/*!< Uncomment the following line if you need to relocate your vector Table in
Internal SRAM. */
/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET  0x0 /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */


/*******************************************************************************
*  Clock Definitions
*******************************************************************************/
uint32_t SystemCoreClock         = SYSCLK_FREQ;

__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};

static void SetSysClock(void);

void SystemInit (void)
{
  /* Reset the RCC clock configuration to the default reset state(for debug purpose) */
  /* Set HSION bit */
  RCC->CR |= (uint32_t)0x00000001;
  
  /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CL
  RCC->CFGR &= (uint32_t)0xF8FF0000;
#else
  RCC->CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F10X_CL */   
  
  /* Reset HSEON, CSSON and PLLON bits */
  RCC->CR &= (uint32_t)0xFEF6FFFF;
  
  /* Reset HSEBYP bit */
  RCC->CR &= (uint32_t)0xFFFBFFFF;
  
  /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
  RCC->CFGR &= (uint32_t)0xFF80FFFF;
  
#ifdef STM32F10X_CL
  /* Reset PLL2ON and PLL3ON bits */
  RCC->CR &= (uint32_t)0xEBFFFFFF;
  
  /* Disable all interrupts and clear pending bits  */
  RCC->CIR = 0x00FF0000;
  
  /* Reset CFGR2 register */
  RCC->CFGR2 = 0x00000000;
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
  /* Disable all interrupts and clear pending bits  */
  RCC->CIR = 0x009F0000;
  
  /* Reset CFGR2 register */
  RCC->CFGR2 = 0x00000000;      
#else
  /* Disable all interrupts and clear pending bits  */
  RCC->CIR = 0x009F0000;
#endif /* STM32F10X_CL */
  
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
#ifdef DATA_IN_ExtSRAM
  SystemInit_ExtMemCtl();
#endif /* DATA_IN_ExtSRAM */
#endif
  
  /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
  /* Configure the Flash Latency cycles and enable prefetch buffer */
  SetSysClock();
  
#ifdef VECT_TAB_SRAM
  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif
}

/**
* [url=home.php?mod=space&uid=247401]@brief[/url]  Update SystemCoreClock variable according to Clock Register Values.
*         The SystemCoreClock variable contains the core clock (HCLK), it can
*         be used by the user application to setup the SysTick timer or configure
*         other parameters.
*           
* [url=home.php?mod=space&uid=536309]@NOTE[/url]   Each time the core clock (HCLK) changes, this function must be called
*         to update SystemCoreClock variable value. Otherwise, any configuration
*         based on this variable will be incorrect.         
*     
* [url=home.php?mod=space&uid=536309]@NOTE[/url]   - The system frequency computed by this function is not the real
*           frequency in the chip. It is calculated based on the predefined
*           constant and the selected clock source:
*            
*           - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
*                                             
*           - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
*                          
*           - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
*             or HSI_VALUE(*) multiplied by the PLL factors.
*         
*         (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value
*             8 MHz) but the real value may vary depending on the variations
*             in voltage and temperature.   
*   
*         (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value
*              8 MHz or 25 MHz, depedning on the product used), user has to ensure
*              that HSE_VALUE is same as the real frequency of the crystal used.
*              Otherwise, this function may have wrong result.
*               
*         - The result of this function could be not correct when using fractional
*           value for HSE crystal.
* @param  None
* @retval None
*/
void SystemCoreClockUpdate (void)
{
  uint32_t tmp = 0, pllmull = 0, pllsource = 0;
  
#ifdef  STM32F10X_CL
  uint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0;
#endif /* STM32F10X_CL */
  
#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
  uint32_t prediv1factor = 0;
#endif /* STM32F10X_LD_VL or STM32F10X_MD_VL or STM32F10X_HD_VL */
  
  /* Get SYSCLK source -------------------------------------------------------*/
  tmp = RCC->CFGR & RCC_CFGR_SWS;
  
  switch (tmp)
  {
  case 0x00:  /* HSI used as system clock */
    SystemCoreClock = HSI_VALUE;
    break;
  case 0x04:  /* HSE used as system clock */
    SystemCoreClock = HSE_VALUE;
    break;
  case 0x08:  /* PLL used as system clock */
   
    /* Get PLL clock source and multiplication factor ----------------------*/
    pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
    pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
   
#ifndef STM32F10X_CL      
    pllmull = ( pllmull >> 18) + 2;
   
    if (pllsource == 0x00)
    {
      /* HSI oscillator clock divided by 2 selected as PLL clock entry */
      SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
    }
    else
    {
#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
      prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
      /* HSE oscillator clock selected as PREDIV1 clock entry */
      SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
#else
      /* HSE selected as PLL clock entry */
      if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET)
      {/* HSE oscillator clock divided by 2 */
        SystemCoreClock = (HSE_VALUE >> 1) * pllmull;
      }
      else
      {
        SystemCoreClock = HSE_VALUE * pllmull;
      }
#endif
    }
#else
    pllmull = pllmull >> 18;
   
    if (pllmull != 0x0D)
    {
      pllmull += 2;
    }
    else
    { /* PLL multiplication factor = PLL input clock * 6.5 */
      pllmull = 13 / 2;
    }
   
    if (pllsource == 0x00)
    {
      /* HSI oscillator clock divided by 2 selected as PLL clock entry */
      SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
    }
    else
    {/* PREDIV1 selected as PLL clock entry */
      
      /* Get PREDIV1 clock source and division factor */
      prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC;
      prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
      
      if (prediv1source == 0)
      {
        /* HSE oscillator clock selected as PREDIV1 clock entry */
        SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;         
      }
      else
      {/* PLL2 clock selected as PREDIV1 clock entry */
        
        /* Get PREDIV2 division factor and PLL2 multiplication factor */
        prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4) + 1;
        pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8 ) + 2;
        SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;                        
      }
    }
#endif /* STM32F10X_CL */
    break;
   
  default:
    SystemCoreClock = HSI_VALUE;
    break;
  }
  
  /* Compute HCLK clock frequency ----------------*/
  /* Get HCLK prescaler */
  tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
  /* HCLK clock frequency */
  SystemCoreClock >>= tmp;  
}

/**
* [url=home.php?mod=space&uid=247401]@brief[/url]  Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
* @param  None
* @retval None
*/


const uint32_t RCC_CFGR_PLL_TAB[]=
{
  0,
  0,
  RCC_CFGR_PLLMULL2,
  RCC_CFGR_PLLMULL3,  
  RCC_CFGR_PLLMULL4,
  
  RCC_CFGR_PLLMULL5,
  RCC_CFGR_PLLMULL6,
  RCC_CFGR_PLLMULL7,
  RCC_CFGR_PLLMULL8,  
  RCC_CFGR_PLLMULL9,
  
  RCC_CFGR_PLLMULL10,
  RCC_CFGR_PLLMULL11,
  RCC_CFGR_PLLMULL12,
  RCC_CFGR_PLLMULL13,  
  RCC_CFGR_PLLMULL14,
  
  RCC_CFGR_PLLMULL15,
  RCC_CFGR_PLLMULL16,
  RCC_CFGR_PLLMULL17,
  RCC_CFGR_PLLMULL18,  
  RCC_CFGR_PLLMULL19,
  
  RCC_CFGR_PLLMULL20,
  RCC_CFGR_PLLMULL21,
  RCC_CFGR_PLLMULL22,
  RCC_CFGR_PLLMULL23,  
  RCC_CFGR_PLLMULL24,
  
  RCC_CFGR_PLLMULL25,
  RCC_CFGR_PLLMULL26,
  RCC_CFGR_PLLMULL27,
  RCC_CFGR_PLLMULL28,  
  RCC_CFGR_PLLMULL29,
  
  RCC_CFGR_PLLMULL30,
  RCC_CFGR_PLLMULL31,  
  RCC_CFGR_PLLMULL32  
};

static void SetSysClockToPll(uint8_t __pre,uint8_t __pllmul)
{
  __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);
   
#if SYSCLK_FREQ>48000000ul
    FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;   
#elif SYSCLK_FREQ>24000000ul
    FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1;
#endif
   
    /* 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;
   
    //8/2*(15+12)=108MHz
   
    uint32_t __cfgr=RCC_CFGR_PLLSRC_HSE;
    if(__pre)
    {
      __cfgr |=RCC_CFGR_PLLXTPRE_HSE_Div2;
    }
   
    if(__pllmul<=32)
    {
      __cfgr |= RCC_CFGR_PLL_TAB[__pllmul];
    }
   
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
                                        RCC_CFGR_PLLMULL));
   
    RCC->CFGR |= __cfgr;
   
    /* 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 */
  }
}

static void SetSysClock(void)
{
  uint8_t __pre=1;
  uint8_t __pllmul=(SYSCLK_FREQ) / ((HSE_VALUE)/2);
  
  SetSysClockToPll(__pre,__pllmul);
}

system_gd32f10x.rar

3.16 KB

周立功GD32| | 2013-7-15 08:54 | 显示全部楼层
楼主辛苦啊!
但还是采用修改源代码里的配置参数的思路来更改主频,不如我的sysClockSet()函数灵活啊,可在应用当中随时调用更改主频!
详见“【原创】《wdxLib_for_GD32F103》驱动开发(提供高质量源代码)”贴子

使用特权

评论回复
tonydong| | 2013-7-15 13:36 | 显示全部楼层
周立功GD32 发表于 2013-7-15 08:54
楼主辛苦啊!
但还是采用修改源代码里的配置参数的思路来更改主频,不如我的sysClockSet()函数灵活啊,可在 ...

是滴是滴,sysClockSet()函数更灵活,一旦定义,可随时调用

使用特权

评论回复
shenpingbing| | 2013-8-29 20:37 | 显示全部楼层
下载学习一下

使用特权

评论回复
筱禾1988| | 2013-8-30 20:53 | 显示全部楼层
向楼主学习一下

使用特权

评论回复
fengshuo123| | 2013-9-28 11:11 | 显示全部楼层
时钟频率这么高   工业中不会有问题吧?

使用特权

评论回复
爱情转移| | 2015-3-7 12:15 | 显示全部楼层
借鉴一下楼主的成果

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

16

帖子

0

粉丝