STM32F407 学习笔记一(时钟)

来源:互联网 发布:mobiscroll.js官网 编辑:程序博客网 时间:2024/05/17 04:33

时钟是所有微控制器的心脏,是所有模块的驱动信号,因此首先对STM32F407时钟进行了解。

STM32F4x系列时钟树如下:


系统时钟源(SYSCLK)有三个:

(1) HSI振荡器时钟

(2) HSE振荡器时钟

(3) PLL主时钟


可通过多个预分频器配置 AHB频率、高速APB (APB2) 和低速 APB (APB1)AHB域的最大频率为 168 MHz。高速APB2域的最大允许频率为 84 MHz。低速APB1域的最大允许频
率为
42 MHz


对于时钟设置

Fvco=Fs*(plln/pllm);
Fsys=Fvco/pllp=Fs*(plln/(pllm*pllp));
Fusb=Fvco/pllq=Fs*(plln/(pllm*pllq));


Fvco:VCO频率
Fsys:系统时钟频率

Fusb:USB,SDIO,RNG时钟频率

当Fs为8Mhz时,

取plln=336,pllm=8,pllp=2,pllq=7.
Fvco=8*(336/8)=336Mhz

Fsys=336/2=168Mhz

Fusb=336/7=48Mhz

在启动文件startup_stm32f40_41xxx.s中

                 LDR     R0, =SystemInit                 BLX     R0                 LDR     R0, =__main                 BX      R0                 ENDP


首先对系统进行了初始化, 然后进入main函数。


对于SystemInit:


void SystemInit(void){  /* FPU settings ------------------------------------------------------------*/  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */  #endif  /* Reset the RCC clock configuration to the default reset state ------------*/  /* Set HSION bit */  RCC->CR |= (uint32_t)0x00000001;  /* Reset CFGR register */  RCC->CFGR = 0x00000000;  /* Reset HSEON, CSSON and PLLON bits */  RCC->CR &= (uint32_t)0xFEF6FFFF;  /* Reset PLLCFGR register */  RCC->PLLCFGR = 0x24003010;  /* Reset HSEBYP bit */  RCC->CR &= (uint32_t)0xFFFBFFFF;  /* Disable all interrupts */  RCC->CIR = 0x00000000;#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)  SystemInit_ExtMemCtl(); #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */           /* Configure the System clock source, PLL Multiplier and Divider factors,      AHB/APBx prescalers and Flash settings ----------------------------------*/  SetSysClock();  /* Configure the Vector Table location add offset address ------------------*/#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}

在最后调用了SetSysClock()函数:

static void SetSysClock(void){#if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx) || defined (STM32F401xx)/******************************************************************************//*            PLL (clocked by HSE) used as System clock source                *//******************************************************************************/  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;    /* 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)  {    /* Select regulator voltage output Scale 1 mode */    RCC->APB1ENR |= RCC_APB1ENR_PWREN;    PWR->CR |= PWR_CR_VOS;    /* HCLK = SYSCLK / 1*/    RCC->CFGR |= RCC_CFGR_HPRE_DIV1;#if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx)          /* PCLK2 = HCLK / 2*/    RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;        /* PCLK1 = HCLK / 4*/    RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;#endif /* STM32F40_41xxx || STM32F427_437x || STM32F429_439xx */       /* Configure the main PLL */    RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |                   (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);    /* Enable the main PLL */    RCC->CR |= RCC_CR_PLLON;    /* Wait till the main PLL is ready */    while((RCC->CR & RCC_CR_PLLRDY) == 0)    {    } #if defined (STM32F40_41xxx)         /* Configure Flash prefetch, Instruction cache, Data cache and wait state */    FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;#endif /* STM32F40_41xxx  */    /* Select the main PLL as system clock source */    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));    RCC->CFGR |= RCC_CFGR_SW_PLL;    /* Wait till the main PLL is used as system clock source */    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);    {    }  }  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 */  }#elif defined (STM32F411xE)#if defined (USE_HSE_BYPASS) /******************************************************************************//*            PLL (clocked by HSE) used as System clock source                *//******************************************************************************/  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;    /* Enable HSE and HSE BYPASS */  RCC->CR |= ((uint32_t)RCC_CR_HSEON | RCC_CR_HSEBYP);   /* 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)  {    /* Select regulator voltage output Scale 1 mode */    RCC->APB1ENR |= RCC_APB1ENR_PWREN;    PWR->CR |= PWR_CR_VOS;    /* HCLK = SYSCLK / 1*/    RCC->CFGR |= RCC_CFGR_HPRE_DIV1;    /* PCLK2 = HCLK / 2*/    RCC->CFGR |= RCC_CFGR_PPRE2_DIV1;        /* PCLK1 = HCLK / 4*/    RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;    /* Configure the main PLL */    RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |                   (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);        /* Enable the main PLL */    RCC->CR |= RCC_CR_PLLON;    /* Wait till the main PLL is ready */    while((RCC->CR & RCC_CR_PLLRDY) == 0)    {    }    /* Configure Flash prefetch, Instruction cache, Data cache and wait state */    FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_2WS;    /* Select the main PLL as system clock source */    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));    RCC->CFGR |= RCC_CFGR_SW_PLL;    /* Wait till the main PLL is used as system clock source */    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);    {    }  }  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 */  }#else /* HSI will be used as PLL clock source */  /* Select regulator voltage output Scale 1 mode */  RCC->APB1ENR |= RCC_APB1ENR_PWREN;  PWR->CR |= PWR_CR_VOS;    /* HCLK = SYSCLK / 1*/  RCC->CFGR |= RCC_CFGR_HPRE_DIV1;    /* PCLK2 = HCLK / 2*/  RCC->CFGR |= RCC_CFGR_PPRE2_DIV1;    /* PCLK1 = HCLK / 4*/  RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;    /* Configure the main PLL */  RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | (PLL_Q << 24);     /* Enable the main PLL */  RCC->CR |= RCC_CR_PLLON;    /* Wait till the main PLL is ready */  while((RCC->CR & RCC_CR_PLLRDY) == 0)  {  }    /* Configure Flash prefetch, Instruction cache, Data cache and wait state */  FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_2WS;    /* Select the main PLL as system clock source */  RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));  RCC->CFGR |= RCC_CFGR_SW_PLL;    /* Wait till the main PLL is used as system clock source */  while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);  {  }#endif /* USE_HSE_BYPASS */  #endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F401xx */  }



经此配置,

plln=336,pllm=8,pllp=2,pllq=7.
Fvco=8*(336/8)=336Mhz

Fsys=336/2=168Mhz

Fusb=336/7=48Mhz