×
单片机 > 单片机程序设计 > 详情

STM32学习笔记——RCC系统时钟配置

发布时间:2020-05-21 发布时间:
|
//学习RCC的配置方法,以后可以直接用

 

#include "stm32f10x_lib.h"

 

 

 

//#define SYSCLK_HSE

//#define SYSCLK_FREQ_20MHz

//#define SYSCLK_FREQ_36MHz   //36MH工作

//#define SYSCLK_FREQ_48MHz   //48MH工作 通过宏定义改变系统时钟频率

#define SYSCLK_FREQ_72MHz   //工作72MH 

 

#define DELAY_COUNT    0xFFFFF

 

 

GPIO_InitTypeDef  GPIO_InitStructure;  //定义GPIO配置的结构体变量,用于初始化设置GPIO

RCC_ClocksTypeDef  RCC_ClockFreq; //定义RCC时钟频率配置的结构体变量,用于配置RCC。包括SYSCLK,HCLK,PCLK1,PCLK2,ADCCLK频率的设置

ErrorStatus  HSEStartUpStatus;   //定义枚举类型的错误变量

 

 

//设置系统时钟SYSCLK的函数

void SetSysClock(void);

void SetSysClockToHSE(void);

void SetSysClockTo20(void);

void SetSysClockTo36(void);

void SetSysClockTo48(void);

void SetSysClockTo72(void);

 

void NVIC_Configuration(void);  //配置嵌套向量中断控制器函数

void Delay(vu32 nCount);    //延迟

 

 

 

int main(void)

{

#ifdef DEBUG

  debug();

#endif

 

 

  SetSysClock();   //设置系统时钟  HCLK PCLK2 PCLK1 

 

  

  RCC_GetClocksFreq(&RCC_ClockFreq);   //获得不同片上时钟的频率,RCC_ClockFreq为前面定义的时钟频率结构体变量,该函数把当前

  //不同片上时钟的频率存放在结构体RCC_ClockFreq中

 

  

  RCC_ClockSecuritySystemCmd(ENABLE);  //该函数使能或失能时钟安全系统  在这里是使能

     

  

  NVIC_Configuration();

 

  //开启GPIOA 和 GPIOB 模块时钟  使能APB2时钟

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB RCC_APB2Periph_GPIOA, ENABLE);

    

  GPIO_InitStructure.GPIO_Pin GPIO_Pin_6 GPIO_Pin_7 GPIO_Pin_8 GPIO_Pin_9;  //选择6,7,8,9引脚

  GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; //GPIO速度为50MHz

  GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP;    //设置为推挽输出模式

  GPIO_Init(GPIOB, &GPIO_InitStructure); //用刚刚配置好的结构体变量初始化PB口

 

  GPIO_Write(GPIOB, GPIO_Pin_7 GPIO_Pin_9);    //向GPIOB口写入数据

 

   //MCO:微控制器时钟输出  时钟能够输出到外部的MCO管脚,相关的GPIO管脚必须被配置成备用功能模式 即AF模式

     //在STM32F103C8中PA8为MCO管脚

  GPIO_InitStructure.GPIO_Pin GPIO_Pin_8;    //选择第8脚

  GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP;  //复用推挽输出模式

  GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PA口

 

 //在STM32F103C8中PA8为MCO管脚

  RCC_MCOConfig(RCC_MCO_HSE);   //选择在MCO管脚上输出的时钟源 参数设置指定输出的时钟源,可取值如下:

  //RCC_MCO_NoClock:无时钟被选中,RCC_MCO_SYSCLK:选中系统时钟,RCC_MCO_HSI:选中HSI,RCC_MCO_HSE:选中HSE,RCC_MCO_PLLCLK_Div2:

  //选中PLL时钟除以2

  //警告:当选中系统时钟作为MCO管脚的输出时,注意它的时钟频率不超过50MHz(最大I/O速率)。

 

 

       

  while (1)

  {

    GPIO_Write(GPIOB, (u16)~GPIO_ReadOutputData(GPIOB));   //PB口的状态取反

 

    

    Delay(DELAY_COUNT);

  }

}

 

 

void SetSysClock(void)  //设定系统时钟频率函数

   

#if defined SYSCLK_HSE

  SetSysClockToHSE();   //系统时钟频率设为HSE

#elif defined SYSCLK_FREQ_20MHz

  SetSysClockTo20(); //系统时钟频率设为20MHz 

#elif defined SYSCLK_FREQ_36MHz

  SetSysClockTo36(); //系统时钟频率设为36MHz

#elif defined SYSCLK_FREQ_48MHz

  SetSysClockTo48(); //系统时钟频率设为48MHz

#elif defined SYSCLK_FREQ_72MHz

  SetSysClockTo72(); //系统时钟频率设为72MHz

#endif

 

  

}

 

 

void SetSysClockToHSE(void)   //设置系统时钟频率为HSE的函数

{

     

  

 //复位RCC外部设备寄存器到默认值

  RCC_DeInit();  //将外设RCC寄存器重设为缺省值

 

  

  RCC_HSEConfig(RCC_HSE_ON);//打开外部高速晶振HSE

 

  

  HSEStartUpStatus RCC_WaitForHSEStartUp();   //等待外部高速时钟准备好

 

  if (HSEStartUpStatus == SUCCESS)

  {

    

    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //使能flash的预取功能

 

    

    FLASH_SetLatency(FLASH_Latency_0);  //设置flash代码延时时钟周期数为0

 

    

    RCC_HCLKConfig(RCC_SYSCLK_Div1);  //设置AHB时钟等于系统时钟

  

    

    RCC_PCLK2Config(RCC_HCLK_Div1);  //设置APB2时钟频率等于AHB时钟

 

    

    RCC_PCLK1Config(RCC_HCLK_Div1);   //设置APB1时钟频率等于AHB时钟

 

    

    RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE);//设置系统时钟为HSE

 

    

    while (RCC_GetSYSCLKSource() != 0x04)   //检查系统时钟是否为HSE  0x04:HSE作为系统时钟

    {

    }

  }

  else

      

 

    

    while (1)

    {

    }

   

}

 

 

void SetSysClockTo20(void)    //设置系统时钟频率为20MHz

{

     

  

  RCC_DeInit();

 

  

  RCC_HSEConfig(RCC_HSE_ON);

 

  

  HSEStartUpStatus RCC_WaitForHSEStartUp();

 

  if (HSEStartUpStatus == SUCCESS)

  {

    

    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);   // HSE为8MHz  设置PLL输出频率为20MHz

 

     

    RCC_PLLCmd(ENABLE);    //使能PLL

 

    

    while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)//等待PLL就绪

    {

    }

 

    [page]

    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);     //配置系统时钟为PLL

 

    

    while (RCC_GetSYSCLKSource() != 0x08)  //检查系统时钟是否为PLL

    {

    }

  }

  else

      

 

    

    while (1)

    {

    }

  }

}

 

 

void SetSysClockTo36(void)    //设置系统时钟为36MHz函数

{

     

  

  RCC_DeInit();

 

  

  RCC_HSEConfig(RCC_HSE_ON);

 

  

  HSEStartUpStatus RCC_WaitForHSEStartUp();

 

  if (HSEStartUpStatus == SUCCESS)

  {

    

    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);   //8/2 *9=36  设置PLL为36MHz

 

     

    RCC_PLLCmd(ENABLE);

 

    

    while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)

    {

    }

 

    

    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

 

    

    while (RCC_GetSYSCLKSource() != 0x08)

    {

    }

  }

  else

      

 

    

    while (1)

    {

    }

  }

}

 

 

void SetSysClockTo48(void)   //设置系统时钟为48MHz函数

{

     

  

  RCC_DeInit();

 

  

  RCC_HSEConfig(RCC_HSE_ON);

 

  

  HSEStartUpStatus RCC_WaitForHSEStartUp();

 

  if (HSEStartUpStatus == SUCCESS)

  {

    

    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);   //设置PLL为48MHz

 

     

    RCC_PLLCmd(ENABLE);

 

    

    while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)

    {

    }

 

    

    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

 

    

    while (RCC_GetSYSCLKSource() != 0x08)

    {

    }

  }

  else

      

 

    

    while (1)

    {

    }

  }

}

 

 

void SetSysClockTo72(void)    //设置系统时钟为72MHz

{

     

  

  RCC_DeInit();

 

  

  RCC_HSEConfig(RCC_HSE_ON);

 

  

  HSEStartUpStatus RCC_WaitForHSEStartUp();

 

  if (HSEStartUpStatus == SUCCESS)

  {

    

    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);  //设置PLL为72MHz

 

     

    RCC_PLLCmd(ENABLE);

 

    

    while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)

    {

    }

 

    

    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

 

    

    while(RCC_GetSYSCLKSource() != 0x08)

    {

    }

  }

  else

      

 

    

    while (1)

    {

    }

  }

}

 

 

void NVIC_Configuration(void)    //设置中断向量表基址

{

  NVIC_InitTypeDef NVIC_InitStructure;    //NVIC初始化结构体,定义初始化NVIC的结构体变量

 

#ifdef  VECT_TAB_RAM  

   

  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); 

#else  

   

  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   

#endif

 

    //NVIC_InitStructure 是前面定义的NVIC初始化结构体 包括以下几项

  NVIC_InitStructure.NVIC_IRQChannel RCC_IRQChannel;    //指定IRQ通道    这里指定为RCC全局中断

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 0; //该参数设置成员NVIC_IRQChannel中的先占优先级

  NVIC_InitStructure.NVIC_IRQChannelSubPriority 0;    //该参数设置成员NVIC_IRQChannel中的从优先级   详见函数说明P167

  NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE;  //该参数指定在成员NVIC_IRQChannel中定义的IRQ通道被使能还是失能

  //取值可以为ENABLE或DISABLE

  NVIC_Init(&NVIC_InitStructure);  //根据结构体NVIC_InitStructure中指定的参数初始化外设NVIC 

}

 

 

void Delay(vu32 nCount)

{

  for(; nCount!= 0;nCount--);

}

 

#ifdef  DEBUG

 

//assert_failed编写于文件main.c或其他用户C文件中

 

void assert_failed(u8* file, u32 line)

  

 

  

  while (1)

  {

  }

}

#endif

关键字:STM32  RCC系统  时钟配置 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
ARM 汇编的必知必会