STM32时钟配置函数
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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); FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; /* HCLK = SYSCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
STM32F103 单片机
SystemInit() 函数介绍
备注:此文档为个人实际操作经验,鄙人非大神,如有错误还请指教,谢谢
1 原库函数
注:黑色字体为函数代码,紫色的为注释,红色的是我的理解。 cl:互联型产品,stm32f105/107 系列 vl:超值型产品,stm32f100 系列 xl:超高密度产品,stm32f101/103 系列 ld:低密度产品,FLASH 小于 64K md:中等密度产品,FLASH=64 or 128 hd:高密度产品,FLASH 大于 128
#ifdef DATA_IN_ExtSRAM SystemInit_ExtMemCtl();
#endif #endif 我用的是 STM32F103ZET6,属于 STM32F10X_HD 型,但是不会定 义 DATA_IN_ExtSRAM,所以不去执行 SystemInit_ExtMemCtl(),这 个函数我们后续再看,下面的代码是:SetSysClock();完事向下执行, #ifdef VECT_TAB_SRAM
/* Reset CFGR2 register */ RCC->CFGR2 = 0x00000000; #else /* Disable all interrupts and clear pending bits */ RCC->CIR = 0x009F0000; #endif /* STM32F10X_CL */
/* 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 */
我们用的普通型,则 CFGR 的配置结果为: xxxx x000 xxxx xxxx 0000 0000 0000 0000 CFGR 寄存器功能分配图如下:
由上图一一分析: MCO = 000 没有时钟输出
ADCPRE = 00 PCLK2 2 分频后作为 ADC 时钟
PPRE2 = 000 HCLK 不分频给 APB2
/* 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;
#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 }
定义 SYSCLK_FREQ_72MHz 的地方在:system_stm32f10x.c 的
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); /* Wait till HSE is ready and if Time out is reached exit */ do {
#ifdef STM32F10X_CL /* Reset PLL2ON and PLL3ON bits */ RCC->CR &= (uint32_t)0xEBFFFFFF;
/* Disable all interrupts and clear pending bits */ RCC->CIR = 0x00FF0000;
#else
上面这些代码不用看,应为我用的是 103 系列,不属于 CL 或者 VL
型,所以暂且不用管。用的那你就去看看咯。。。。。。。 接着向下执行: #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
RCC->CFGR &= (uint32_t)0xF8FF0000; #else
RCC->CFGR &= (uint32_t)0xF0FF0000; #endif 首先我们看看这个 STM32F10X_CL 是什么东东?原来它代表的是使 用了 STM32 互联型系列处理器(也就是 105 和 107 系列处理器)。 那么上面的代码就是说我们用的普通型和 105/107 型在配置 RCC 时 钟配置寄存器 CFGR 是存在差异的。
#endif
/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */ /* Configure the Flash Latency cycles and enable prefetch buffer */ SetSysClock();
/* 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;
2 我对代码的理解
SystemInit ()函数的第一条命令是: RCC->CR |= (uint32_t)0x00000001; 这条语句是将 RCC 的时钟控制寄存器 CR 的 bit0 置 1,bit0 的作用是:
所以上一条指令的意思就是要开启内部 8MHz 时钟 HSI。 接着向下执行: #ifndef STM32F10X_CL
#elif defined SYSCLK_FREQ_56MHz SetSysClockTo56();
#elif defined SYSCLK_FREQ_72MHz SetSysClockTo72();
#endif /* If none of the define above is enabled, the HSI is used as System clock source (default after reset) */ } 首先声明:SYSCLK_FREQ_HSE 没有定义,故 SetSysClockToHSE() 不会执行的,而是执行由于定义了 SYSCLK_FREQ_72MHz 而执行 的 SetSysClockTo72() 。
void SystemInit (void) {
/* Reset the RCC clock configuration to the default reset state(for debug purpose) */ /* Set HSION bit */ RCC->CR |= (uint32_t)0x00000001;
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL) #ifdef DATA_IN_ExtSRAM SystemInit_ExtMemCtl(); #endif /* DATA_IN_ExtSRAM */
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; #else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; #endif 这个就是用来指引程序的,日后再聊。
SetSysClock()函数代码: static void SetSysClock(void) {
#ifdef SYSCLK_FREQ_HSE SetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHz SetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHz SetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHz SetSysClockTo48();
CR 寄存器的 CSSON = 0
CR 寄存器的 HSEON = 0
接着向下执行: RCC->CR &= (uint32_t)0xFFFBFFFF; HREBYP = 0 外部高速时钟没有旁路
接着向下执行: RCC->CFGR &= (uint32_t)0xFF80FFFF; USBPRE = 0 保持系统复位状态
RCC->CFGR2 = 0x00000000;
#elif
defined
(STM32F10X_LD_VL)
||
defined
(STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
RCC->CIR = 0x009F0000;
RCC->CFGR2 = 0x00000000;
PLLMULC = 0000 保持系统复位状态
PLLXTPRE = 0 HSI 时钟作为 PLL 输入时钟的状态
wenku.baidu.comPLLSRC = 0 HSI 时钟 2 分频后作为 PLL 输入时钟
接着向下执行:
#ifdef STM32F10X_CL
RCC->CR &= (uint32_t)0xEBFFFFFF;
RCC->CIR = 0x00FF0000;
PPRE1 = 000 HCLK 不分频给 APB1
HPRE = 0000 AHB 预分频器不分频(sysclk 不分频)
SWS = 00 (系统时钟状态)
SW = 00 系统时钟选择
接着向下执行: RCC->CR &= (uint32_t)0xFEF6FFFF; CR 寄存器的 PLLON = 0
STM32F103 单片机
SystemInit() 函数介绍
备注:此文档为个人实际操作经验,鄙人非大神,如有错误还请指教,谢谢
1 原库函数
注:黑色字体为函数代码,紫色的为注释,红色的是我的理解。 cl:互联型产品,stm32f105/107 系列 vl:超值型产品,stm32f100 系列 xl:超高密度产品,stm32f101/103 系列 ld:低密度产品,FLASH 小于 64K md:中等密度产品,FLASH=64 or 128 hd:高密度产品,FLASH 大于 128
#ifdef DATA_IN_ExtSRAM SystemInit_ExtMemCtl();
#endif #endif 我用的是 STM32F103ZET6,属于 STM32F10X_HD 型,但是不会定 义 DATA_IN_ExtSRAM,所以不去执行 SystemInit_ExtMemCtl(),这 个函数我们后续再看,下面的代码是:SetSysClock();完事向下执行, #ifdef VECT_TAB_SRAM
/* Reset CFGR2 register */ RCC->CFGR2 = 0x00000000; #else /* Disable all interrupts and clear pending bits */ RCC->CIR = 0x009F0000; #endif /* STM32F10X_CL */
/* 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 */
我们用的普通型,则 CFGR 的配置结果为: xxxx x000 xxxx xxxx 0000 0000 0000 0000 CFGR 寄存器功能分配图如下:
由上图一一分析: MCO = 000 没有时钟输出
ADCPRE = 00 PCLK2 2 分频后作为 ADC 时钟
PPRE2 = 000 HCLK 不分频给 APB2
/* 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;
#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 }
定义 SYSCLK_FREQ_72MHz 的地方在:system_stm32f10x.c 的
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); /* Wait till HSE is ready and if Time out is reached exit */ do {
#ifdef STM32F10X_CL /* Reset PLL2ON and PLL3ON bits */ RCC->CR &= (uint32_t)0xEBFFFFFF;
/* Disable all interrupts and clear pending bits */ RCC->CIR = 0x00FF0000;
#else
上面这些代码不用看,应为我用的是 103 系列,不属于 CL 或者 VL
型,所以暂且不用管。用的那你就去看看咯。。。。。。。 接着向下执行: #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
RCC->CFGR &= (uint32_t)0xF8FF0000; #else
RCC->CFGR &= (uint32_t)0xF0FF0000; #endif 首先我们看看这个 STM32F10X_CL 是什么东东?原来它代表的是使 用了 STM32 互联型系列处理器(也就是 105 和 107 系列处理器)。 那么上面的代码就是说我们用的普通型和 105/107 型在配置 RCC 时 钟配置寄存器 CFGR 是存在差异的。
#endif
/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */ /* Configure the Flash Latency cycles and enable prefetch buffer */ SetSysClock();
/* 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;
2 我对代码的理解
SystemInit ()函数的第一条命令是: RCC->CR |= (uint32_t)0x00000001; 这条语句是将 RCC 的时钟控制寄存器 CR 的 bit0 置 1,bit0 的作用是:
所以上一条指令的意思就是要开启内部 8MHz 时钟 HSI。 接着向下执行: #ifndef STM32F10X_CL
#elif defined SYSCLK_FREQ_56MHz SetSysClockTo56();
#elif defined SYSCLK_FREQ_72MHz SetSysClockTo72();
#endif /* If none of the define above is enabled, the HSI is used as System clock source (default after reset) */ } 首先声明:SYSCLK_FREQ_HSE 没有定义,故 SetSysClockToHSE() 不会执行的,而是执行由于定义了 SYSCLK_FREQ_72MHz 而执行 的 SetSysClockTo72() 。
void SystemInit (void) {
/* Reset the RCC clock configuration to the default reset state(for debug purpose) */ /* Set HSION bit */ RCC->CR |= (uint32_t)0x00000001;
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL) #ifdef DATA_IN_ExtSRAM SystemInit_ExtMemCtl(); #endif /* DATA_IN_ExtSRAM */
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; #else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; #endif 这个就是用来指引程序的,日后再聊。
SetSysClock()函数代码: static void SetSysClock(void) {
#ifdef SYSCLK_FREQ_HSE SetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHz SetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHz SetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHz SetSysClockTo48();
CR 寄存器的 CSSON = 0
CR 寄存器的 HSEON = 0
接着向下执行: RCC->CR &= (uint32_t)0xFFFBFFFF; HREBYP = 0 外部高速时钟没有旁路
接着向下执行: RCC->CFGR &= (uint32_t)0xFF80FFFF; USBPRE = 0 保持系统复位状态
RCC->CFGR2 = 0x00000000;
#elif
defined
(STM32F10X_LD_VL)
||
defined
(STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
RCC->CIR = 0x009F0000;
RCC->CFGR2 = 0x00000000;
PLLMULC = 0000 保持系统复位状态
PLLXTPRE = 0 HSI 时钟作为 PLL 输入时钟的状态
wenku.baidu.comPLLSRC = 0 HSI 时钟 2 分频后作为 PLL 输入时钟
接着向下执行:
#ifdef STM32F10X_CL
RCC->CR &= (uint32_t)0xEBFFFFFF;
RCC->CIR = 0x00FF0000;
PPRE1 = 000 HCLK 不分频给 APB1
HPRE = 0000 AHB 预分频器不分频(sysclk 不分频)
SWS = 00 (系统时钟状态)
SW = 00 系统时钟选择
接着向下执行: RCC->CR &= (uint32_t)0xFEF6FFFF; CR 寄存器的 PLLON = 0