STM32芯片内部系统架构详细讲解:1.芯片内部混乱电信号解决方案: 芯片内部的电路组成结构大多数是逻辑电路(与门、或门、非门、异或门、同或门等),然而在多个逻辑电路连接运算时,由于逻辑门内部运算涉及了充放电过程,因此在电路的运算过程中,寄存器会出现一段由于门电路运算延时产生的错误状态,但是短暂的错误状态会导致依赖此寄存器状态的程序与其他逻辑电路出现更加严重的错误。 那么,设计电路时遇到这个问题该怎么办呢?——解决方法就是,在寄存器前面放一个边缘触发器,并且接入一个一定频率的方波信号——可以为寄存器规避门电路运算的混乱状态 原理:方波的一个周期内,门电路执行运算产生的任何副作用都不会影响到寄存器的值,等待门电路运算稳定后,方波的上升沿到达,最终运算产生的结果才会通过边沿触发器进入寄存器中——方波信号即为时钟信号 ![]() ![]()
(图片来自bilibili up主keysking) 图中的方波信号为时钟信号,时钟信号在单片机中由时钟源(单片机的心脏)产生,通过时钟树传播到整个芯片当中 2.时钟树:AHB(Advanced High Performance Bus)先进高性能总线 (可以理解为STM32芯片内部电路的主干道,芯片上的各种外设都连接到这一总线上,通过这一总线进行数据通信) HCLK——AHB总线中的时钟线 ![]()
STM32时钟树 ![]()
![]()
SysTick为时钟提供一个时钟基准 分频器:为频率作除法 APB先进外设总线:专门用来连接外设,然后通过桥接器连接到AHB总线上,与其他一同连接到AHB总线上的部分进行通信 FCLK自由运行时钟:当我们为了节省电量,需要STM32进入低功耗模式之一的停止模式时,AHB会停止运行,HCLK会停止传输时钟脉冲 Enable CSS:时钟安全系统——他可以在HSE发生故障时,立即切换会HSI,并且产生中断,让我们可以进行紧急制动处理 独立小时钟树 ![]()
STM32 的时钟系统比较复杂, 但又十分重要,理解STM32的时钟树对理解STM32 十分重要。 下面分五个部分择要对其进行阐述: 1.内部RC振荡器与外部晶振的选择STM32可以选择内部时钟(内部RC振荡器),也可以选择外部时钟(外部晶振)。但如果使用内部RC振荡器而不使用外部晶振,必须清楚以下几点:
(1)对于100脚或144脚的产品,OSC_IN应接地,OSC_OUT应悬空。 (2)对于少于100脚的产品,有两种接法:
方法1: OSC_IN和OSC _OUT分别通过10KΩ电阻接地。此方法可提高EMC性能。方法2:分别重映射OSC_IN和OSC _OUT至PD0和PD1,再配置PD0和PD1为推挽输出并输出0。此方法相对于方法1,可以减小功耗并节省两个外部电阻。 (3) 内部8MHz的RC振荡器的误差在1%左右,内部RC振荡器的精度通常比用HSE(外部晶振)要低十倍以上。STM32 的ISP就是利用了HSI (内部RC振荡器)。 2. STM32 时钟源在STM32中,有5个时钟源,分别为HSI、HSE、LSI、 LSE、PLL
(1) HSI 是高速内部时钟,RC振荡器,频率为8MHz(是STM32主要的时钟) (2) HSE是高速外部时钟,可接石英谐振器、陶瓷谐振器,或者接外部时钟源,它的频率范围为4MHz~ 16MHz。 (3) LSI是低速内部时钟,RC振荡器,频率为40kHz。 (4) LSE是低速外部时钟,接频率为32.768kHz的石英晶体。 (5)PLL为锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE/2。倍频可选择2~16倍,但是其输出频率最大不得超过72MHz。 3.STM32中几个与时钟相关的概念SYSCLK:系统时钟,STM32大部分器件的时钟来源。它由AHB预分频器分配到各个部件。 HCLK:由AHB预分频器直接输出得到,它是高速总线AHB的时钟信号,提供给存储器、DMA及Cortex内核,是Cortex内核运行的时钟,CPU主频就是这个信号,它的大小与STM32运算速度、数据存取速度密切相关。 FCLK:同样由AHB预分频器输出得到,是内核的“自由运行时钟”(free running clock).“自由”表现在它不来自时钟HCLK,因此在HCLK时钟停止时FCLK也会继续运行。它的存在,可以保证在处理器休眠时,也能够采样中断和跟踪休眠事件,它与HCLK互相同步。 PCLKI:外设时钟,由APB1预分频器输出得到,最大频率为36MHz,提供给挂载在APBI总线上的外设(低速外设)。 PCLK2:外设时钟,由APB2预分频器输出得到,最大频率可为72MHz,提供给挂载在APB2总线上的外设(高速外设)。
4.时钟输出的使能及其流程时钟输出中有很多是带使能控制的,如AHB总线时钟、内核时钟、各种APB1外设时钟、APB2外设时钟等。
当需要使用某模块时,必须先使能对应的时钟,需要注意的是定时器的倍频器,当APB的分频为1时,它的倍频值为1,否则它的倍频值就为2.
连接在APB1上的设备(低速外设)有电源接口备份接口、CAN、USB、IIC1、IIC2、UART2、UART3、SPI2、窗口看门物、Timer2、Timer3、Timer4. 注意:USB模块虽然需要一个单独的48MHz时钟信号,但它不是供USB模块工作的时钟,而只是提供给串行接口引擎(SIE)使用的时钟,USB模块工作的时钟应该是由APB1提供的
连接在APB2上的设备(高速外设)有:GPIO_A-E、USART1、ADC1、ADC2、ADC3(ADC需要采集一段时间的数据才能更准确地获取电压值)、TM1、TIM8、SPI1、AFIO.
5.时钟设置的基本流程假设使用HSE时钟,并且使用ST的固件库函数,那么在程序中设置时钟参数的流程如下: 第1步:
将RCC寄存器重新设置为默认值,即调用函数RCC_DeInit;
第2步:
打开外部高速时钟晶振HSE,调用函数RCC_HSEConfig(RCC_HSE_ON);
第3步:
等待外部高速时钟晶振工作,调用HSEStartUpStatus = RCC_WaitForHSEStartUp(); 第4步:
设置AHB时钟,即调用函数RCC_HCLKConfig;
第5步:
设置高速AHB时钟,即调用函数RCC_PCLK2Config;
第6步:
设置低速AHB时钟,即调用函数RCC_PCLK1Config;
第7步:
设置PLL,即调用函数RCC_PLLConfig;
第8步:
打开PLL,即调用函数RCC_PLLCmd(ENABLE);
第9步:
等待PLL工作,while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET); 第10步:
设置系统时钟,即调用函数RCC_SYSCLKConfig;
第11步;
判断PLL是否是系统时钟,while(RCC_GetSYSCLKSource()!=0x08);
第12步:
打开要使用的外设时钟,即调用函数RCC_APB2PeriphClockCmd();或者 RCC_APB1PeriphClockCmd();
|