STM32寄存器学习日记1-RCC
一、目标实现STM32系统时钟初始化二、方案硬件正点原子STM32F103ZET6精英开发版软件RCC配置步骤// 第1阶段复位和默认状态 可选1、复位APB1、APB2、AHB总线上的外设RCC-APB1RSTR等2、关闭所有外设时钟RCC-APB1ENR等 0// 第2阶段确保基础时钟 可选3、使能内部高速时钟HSIRCC-CR | HSI_ON // HSI默认已使能但显式配置更安全// 第3阶段复位所有时钟配置 可选4、复位系统时钟选择SW 0选择HSI5、复位HSE、PLL相关配置清除HSEON、PLLON、PLLSRC、PLLMUL等6、关闭HSE、HSI、LSE、LSI的使能可选根据需求7、清除所有RCC中断标志配置SYSCLK// 第4阶段配置HSE 8、使能外部高速时钟HSERCC-CR | HSE_ON9、等待HSE就绪while(!(RCC-CR HSE_RDY)) 关键// 如果不等待后续配置可能失败// 第5阶段配置Flash重要10、配置Flash等待周期FLASH-ACR // 必须在提高频率前配置否则会崩溃// 第6阶段配置PLL 11、确保PLL已关闭RCC-CR ~PLL_ON12、配置PLL倍频系数PLLMUL13、选择HSE作为PLL输入源PLLSRC HSE此时HSE已经稳定可以安全选择配置AHB、APB1、APB2// 第7阶段使能PLL并等待 14、使能PLLRCC-CR | PLL_ON15、等待PLL就绪while(!(RCC-CR PLL_RDY))// 第8阶段配置总线时钟 16、配置AHB预分频HPRE→ HCLK17、配置APB1预分频PPRE1→ PCLK118、配置APB2预分频PPRE2→ PCLK219、选择PLL作为系统时钟SW 220、等待切换完成SWS 2三、实现/** * brief 时钟设置函数 * param plln: PLL倍频系数(PLL倍频), 取值范围: 2~16 * note * * PLLCLK: PLL输出时钟 * PLLSRC: PLL输入时钟频率, 可以是 HSI/2, HSE/2, HSE等, 一般选择HSE. * SYSCLK: 系统时钟, 可选来自 HSI/PLLCLK/HSE, 一般选择来自PLLCLK * FCLK : Cortex M3内核时钟, 等于HCLK * HCLK : AHB总线时钟, 来自 SYSCLK 的分频, 可以是1...512分频, 一般不分频 * PCLK2 : APB2总线时钟, 来自 HCLK 的分频(最大72Mhz), 可以是1/2/4/8/16分频, 一般不分频 * PCLK1 : APB1总线时钟, 来自 HCLK 的分频(最大36Mhz), 可以是1/2/4/8/16分频, 一般二分频 * * PLLCLK PLLSRC * plln; * FCLK HCLK SYSCLK; * PCLK2 HCLK; * PCLK1 HCLK / 2; * * 我们一般选择PLLSRC来自HSE, 即来自外部晶振. * 当外部晶振为 8M的时候, 推荐: plln 9, AHB不分频, 得到: * PLLCLK 8 * 9 72Mhz * FCLK HCLK SYSCLK PLLCLK / 1 72Mhz * PCLK2 HCLK 72Mhz * PCLK1 HCLK / 2 36Mhz * * 关于STM32F103的PLL说明详见: STM32中文参考手册 V10第六章相关内容 * * retval 错误代码: 0, 成功; 1, HSE错误; */ uint8_t sys_clock_set(uint32_t plln) { uint32_t retry 0; uint8_t retval 0; RCC-CR | 0x00010000; /* 外部高速时钟使能HSEON */ while (retry 0XFFF0) { __nop(); /* 注意, MDK5.29或以后版本, 在使能HSEON以后, 如果不加一定的延时 * 再开始其他配置, 会导致仿真器下载完代码, 延时函数运行不正常的 bug * 需要按复位按键, 延时才会正常, 在这里加一定的延时, 可以解决这个 bug * 这里, 我们设置的延时时间, 至少是 0X8000 个 nop时间 */ if (RCC-CR (1 17) retry 0X8000) { break; } retry; /* 等待HSE RDY */ } if (retry 0XFFF0) { retval 1; /* HSE无法就绪 */ } else { RCC-CFGR 0X00000400; /* PCLK1 HCLK / 2; PCLK2 HCLK; HCLK SYSCLK; */ plln - 2; /* 抵消2个单位(因为是从2开始的, 设置0就是2) */ RCC-CFGR | plln 18; /* 设置PLL值 2~16 */ RCC-CFGR | 1 16; /* PLLSRC 1, 选择 HSE 作为 PLL 输入时钟 */ /* FLASH_ACR寄存器的描述详见: STM32F10xx闪存编程手册 */ FLASH-ACR 1 4; /* PRFTBE 1 开启预取缓冲区 */ FLASH-ACR | 2 0; /* LATENCY[2:0] 2 FLASH两个等待周期 */ RCC-CR | 1 24; /* PLLON 1, 使能PLL */ while (!(RCC-CR 25)); /* 等待PLL锁定 */ RCC-CFGR | 2 0; /* SW[1:0] 2, 选择PLL输出作为系统时钟 */ while (((RCC-CFGR 2) 0X03) ! 2); /* 等待PLL作为系统时钟设置成功 */ } return retval; }参考资料1、正点原子标准例程-寄存器版本