您的位置 首页 ADAS

STM32F10x芯片时钟操控总结

1、介绍STM32F10x芯片的时钟控制主要包括以下几个方面知识:时钟源的选择(HSE、HIS、PLL)、系统时钟频率的配置、总线(AHB、APB2、APB1)…

1、介绍

STM32F10x芯片的时钟操控首要包含以下几个方面常识:时钟源的挑选(HSE、HIS、PLL)、体系时钟频率的装备、总线(AHB、APB2、APB1)时钟的装备、总线(AHB、APB2、APB1)设备时钟的使能/除能、总线(AHB、APB2、APB1)设备的复位。

2、体系时钟框图

STM32F10x能够用三种不同的时钟源来驱动体系时钟(SYSCLK):HSI振荡器时钟;HSE外部时钟和PLL时钟。他们之间的联系如附件所示(时钟树)。

从时钟树中能够看出一下几点:

l体系时钟的来历能够是HSI振荡器时钟、PLL时钟、或许HSE时钟;且体系总线时钟最大值为72MHz,AHB和APB2总线最大频率也是72MHz,APB1总线最大答应频率是36MHz;而Cortex-M3核的自在运转时钟是FCLK(来历于AHB总线);

lstm32f10x芯片总共有四个时钟源:HSE、LSE(外部时钟信号);HIS、LSI(内部时钟信号),芯片内的其他一切时钟都是经过如上四个时钟源分频得来;

lRTC的时钟来历能够是HSE外部时钟128分频之后的时钟、或许LSE外部时钟(32.768kHz)或许内部LSI振荡器时钟;

lIWDG的时钟来历有必要是内部LSI振荡器时钟;

lMCO引脚的时钟输出源的来历有:PLL时钟的2分频、内部HIS时钟、外部HSE时钟以及体系时钟。

lPLL时钟的来历能够是HIS振荡器时钟或许HSE外部供给的时钟;

lUSB外设是直接运用PLL输出时钟(假如运用USB外设,HSE和PLL时钟都有必要使能,且体系时钟有必要是48MHz或许72MHz);AHB总线的时钟输入源的是体系时钟;APB1和APB2的时钟来历是AHB;

l一直安全体系(CSS)有必要由HSE供给时钟源;若CSS激活且HSE时钟呈现毛病,则引发CSS中止,一起产生NMI(NMI中止是不行屏蔽的),NMI将被不断履行,知道CSS中止挂起位被铲除;

l定时器时钟要么等于总线时钟,要么等于总线时钟频率的两倍,这取决于总线分频系数的值是否为1;

l当HIS被用于作为PLL时钟输入时,体系时钟能得到的最大频率是64MHz;

lCortex-M3内核的自在运转时刻是FCLK。

3、时钟寄存器描绘

l时钟操控寄存器:RCC_CR

l时钟装备寄存器:RCC_CFGR

l时钟中止寄存器:RCC_CIR

lAPB2外设复位寄存器:RCC_APB2RSTR

lAPB1外设复位寄存器:RCC_APB1RSTR

lAHB外设时钟使能寄存器:RCC_AHBENR

lAPB2外设时钟使能寄存器:RCC_APB2ENR

lAPB1外设时钟使能寄存器:RCC_APB1ENR

l备份域操控寄存器:RCC_BDCR

l操控/状况寄存器:RCC_CSR

4、时钟操控首要依照以下五步进行操控

l体系复位后,HSI振荡器被选为体系时钟;

l调用RCC_DeInit()函数将外设RCC寄存器重置为缺省值;

l挑选体系时钟:

?若挑选HSE做体系时钟:先调用RCC_HSEConfig()使能HSE,然后调用RCC_WaitForHSEStartUp()函数等候HSE起震,最终调用RCC_GetFlagStatus()函数获取HSE晶振状况,检查HIE晶振是否安排妥当;;

?若挑选HSI做体系时钟:首要调用RCC_AdjustHSICalibrationValue()函数调整内部高速晶振校准值(也能够不必,运用体系预留值),然后调用RCC_HSICmd()函数使能HSI,最终调用RCC_GetFlagStatus()函数获取HSI晶振状况,检查HIS晶振是否安排妥当;

?若要运用PLL做体系时钟,如前面两步将HSE和HIS设定好之后,调用RCC_PLLConig()挑选PLL时钟源并设定倍频系数,最终调用RCC_PLLCmd()使能PLL,最终调用RCC_GetFlagStatus()函数获取PLL晶振状况,检查PLL是否安排妥当;。

l最终,在以上时钟装备安排妥当之后,调用RCC_SYSCLKConfig()函数挑选体系时钟输入源:HSE/HIS/PLL。

至此,体系时钟设定完结,能够调用RCC_GetSYSCLKSource()函数来获取当时体系时钟是运用的哪个时钟(检测设置是否成功):0x010:HIS;x040:HSE;x08:PLL。

l然后是总线时钟设置:设置AHB总线时钟:调用RCC_HCLKConfig()函数;设置APB1总线时钟:调用RCC_PCLK1Config()函数;设置APB2总线时钟:调用RCC_PCLK2Config()函数。其间AHB总线时钟来历于SYSCLK总线时钟,APB1和APB2总线时钟来历于AHB总线时钟。留意:这三个时钟的设置能够在体系时钟、PLL、HSE、HIS发动之前设置,也能够在他们之后设置,但习气在PLL装备之前。

l最终是依据使用需求装备各总线上的外围设备,发动/停用外围设备的函数有:RCC_AHBPeriphClockCmd();RCC_APB2PeriphClockCmd();RCC_APB1PeriphClockCmd();复位总线上的设备函数:RCC_APB2PeriphResetCmd();RCC_APB1PeriphResetCmd();详细能够检查RCC固件库。

留意:使能外设时钟的函数有必要在调用外设初始化函数XXX_Init()函数之前,不然可能会导致对应外设初始化失利,编译器却不会因而报错。

5、时钟操控比如

void SetSysClockToHSE(void)

{

ErrorStatus HSEStartUpStatus;

RCC_DeInit();

RCC_HSEConfig(RCC_HSE_ON);

HSEStartUpStatus = RCC_WaitForHSEStartUp();

if(SUCCESS == HSEStartUpStatus)

{

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

FLASH_SetLatency(FLASH_Latency_0);

RCC_HCLKConfig(RCC_SYSCLK_Div1);

RCC_PCLK2Config(RCC_HCLK_Div1);

RCC_PCLK1Config(RCC_HCLK_Div1);

RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE);

while(0x04 != RCC_GetSYSCLKSource())

{

}

}

else

{

}

}

void SetSysClockTo20(void)

{

ErrorStatus HSEStartUpStatus;

RCC_DeInit();

RCC_HSEConfig(RCC_HSE_ON);

HSEStartUpStatus = RCC_WaitForHSEStartUp();

if(SUCCESS == HSEStartUpStatus)

{

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

FLASH_SetLatency(FLASH_Latency_0);

RCC_HCLKConfig(RCC_SYSCLK_Div1);

RCC_PCLK2Config(RCC_HCLK_Div1);

RCC_PCLK1Config(RCC_HCLK_Div1);

RCC_PLLConfig(RCC_PLLSource_HSE_Div2,RCC_PLLMul_5);

RCC_PLLCmd(ENABLE);

while(RESET == RCC_GetFlagStatus(RCC_FLAG_PLLRDY))

{

}

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

while(0x08 != RCC_GetSYSCLKSource())

{

}

}

else

{

}

}

void SetSysClockTo36(void)

{

ErrorStatus HSEStartUpStatus;

RCC_DeInit();

RCC_HSEConfig(RCC_HSE_ON);

HSEStartUpStatus = RCC_WaitForHSEStartUp();

if(SUCCESS == HSEStartUpStatus)

{

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

FLASH_SetLatency(FLASH_Latency_1);

RCC_HCLKConfig(RCC_SYSCLK_Div1);

RCC_PCLK2Config(RCC_HCLK_Div1);

RCC_PCLK1Config(RCC_HCLK_Div1);

RCC_PLLConfig(RCC_PLLSource_HSE_Div2,RCC_PLLMul_9);

RCC_PLLCmd(ENABLE);

while(RESET == RCC_GetFlagStatus(RCC_FLAG_PLLRDY))

{

}

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

while(0x08 != RCC_GetSYSCLKSource())

{

}

}

else

{

}

}

void SetSysClockTo48(void)

{

ErrorStatus HSEStartUpStatus;

RCC_DeInit();

RCC_HSEConfig(RCC_HSE_ON);

HSEStartUpStatus = RCC_WaitForHSEStartUp();

if(SUCCESS == HSEStartUpStatus)

{

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

FLASH_SetLatency(FLASH_Latency_1);

RCC_HCLKConfig(RCC_SYSCLK_Div1);

RCC_PCLK2Config(RCC_HCLK_Div1);

RCC_PCLK1Config(RCC_HCLK_Div2);

RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_6);

RCC_PLLCmd(ENABLE);

while(RESET == RCC_GetFlagStatus(RCC_FLAG_PLLRDY))

{

}

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

while(0x08 != RCC_GetSYSCLKSource())

{

}

}

else

{

}

}

void SetSysClockTo72(void)

{

ErrorStatus HSEStartUpStatus;

RCC_DeInit();

RCC_HSEConfig(RCC_HSE_ON);

HSEStartUpStatus = RCC_WaitForHSEStartUp();

if(SUCCESS == HSEStartUpStatus)

{

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

FLASH_SetLatency(FLASH_Latency_2);

RCC_HCLKConfig(RCC_SYSCLK_Div1);

RCC_PCLK2Config(RCC_HCLK_Div1);

RCC_PCLK1Config(RCC_HCLK_Div2);

RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);

RCC_PLLCmd(ENABLE);

while(RESET == RCC_GetFlagStatus(RCC_FLAG_PLLRDY))

{

}

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

while(0x08 != RCC_GetSYSCLKSource())

{

}

}

else

{

}

}

6、体系时钟安全体系CSS

在实践使用中,经常呈现因为晶体振荡器在运转中失掉效果,形成微处理器的时钟源丢掉,然后呈现死机的现象,导致体系犯错。为防止发声这种严重错误,STM32F10X系列芯片供给了一个时钟安全体系CCS机制。如下图:

时钟安全体系被激活后,时钟监控器将实时监控外部高速振荡器;假如HSE时钟产生毛病,外部振荡器主动被封闭,产生时钟安全中止,此中止被连接到Cortex-M3的NVIC中止;与此一起CSS将内部RC振荡器(HSI)切换为STM32的体系时钟源。

留意:一旦CSS被激活,当HSE时钟呈现毛病产生CSS中止,一起主动产生NMI,NMI将不断履行,直到CSS中止挂起位被铲除。因而在NMI的处理程序中,有必要经过设置时钟中止寄存器RCC_CIR中的CSSC位(软件置1铲除)来铲除CSS中止。(其实RCC的其他各时钟源的安排妥当中止标志,也都需求经过软件置1来铲除,仅仅CSS是NMI中止(不行屏蔽中止),其他中止需求设置相应位答应中止,并要在NVIC中翻开RCC的中止通道)

7、体系时钟安全体系CSS使用

发动时钟安全体系CCS:

RCC_ClockSecuritySystemCmd(ENABLE);

编写NMI中止处理函数:

void NMI_Handler(void)

{

if(RESET != RCC_GetITStatus(RCC_IT_CSS))

{/* HSE、PLL现已被制止,但PLL设置未变*/

……/*客户增加相应的体系维护代码处理*/

/*下面增加HSE康复后的预设代码*/

RCC_HSEConfig(RCC_HSE_ON);

RCC_ITConfig(RCC_IT_HSERDY,ENABLE);

RCC_ITConfig(RCC_IT_PLLRDY,ENABLE);

RCC_ClearITPendingBit(RCC_IT_CSS);

/*至此一旦HSE时钟康复,将产生HSERDY中止,在RCC中止处理程序中,能够将体系时钟设置到曾经的状况*/

}

}

编写RCC中止处理函数:

void RCC_IRQHandler(void)

{

if(RESET != RCC_GetITStatus(RCC_IT_HSERDY))

{

/*增加相应处理*/

RCC_ClearITPendingBit(RCC_IT_HSERDY);

}

if(RESET != RCC_GetITStatus(RCC_IT_PLLRDY))

{

/*增加相应处理*/

RCC_ClearITPendingBit(RCC_IT_PLLRDY);

}

}

8、输出芯片内部时钟

STM32F10x芯片支撑将内部时钟经过PA.8输出,可是有必要留意GPIO输出管脚最大呼应频率为50MHz,假如超越这个频率,输出的波形将会失真。使用实例如下:

首要装备端口PA.8

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_Init(GPIOA,&GPIO_InitStructure);

然后调用函数RCC_MCOConfig(RCC_MCO)挑选要输出的内部时钟:RCC_MCO能够是:

RCC_MCO_NoClock——无时钟输出

RCC_MCO_SYSCLK——输出体系时钟

RCC_MCO_HSI——输出内部高速8MHz的RC振荡器时钟

RCC_MCO_HSE——输出外部时钟信号

RCC_MCO_PLLCLK_Div2——输出PLL倍频后的二分频时钟

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qiche/adas/274951.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部