本帖最后由 hejun96 于 2021-6-11 09:38 编辑
#申请原创# 最近使用了AT32F403ARCT7,用来pin to pin STM32F103RCT6,内部时钟HSI使用稳定。下面介绍下用HSI PLL锁相环时钟倍频后作主频的初始化:
- AT32F403A默认使用的是HSE = 8MHz,倍频的方式到240MHz主频
- 我这里把它改成内部64MHz为例子,这里的寄存器我使用的是AT32的底层库:
- static void setSysClockHSI(uint32_t pllmult)
- {
- __IO uint32_t HSIStartUpStatus = 0, StartUpCounter = 0;//StartUpCounter 是AT32底层库需要
- // 把 RCC 外设初始化成复位状态
- ///RCC_Reset();///RCC_DeInit();
- //使能 HSI
- RCC_HSICmd(ENABLE);
- // 等待 HSI 就绪
- do
- {
- HSIStartUpStatus = RCC->CTRL & RCC_CTRL_HSISTBL;
-
- /***此处和STM32F103有点不一样,因为AT32F403A主频高于STM32F103***/
- StartUpCounter++;//
- }
- while((HSIStartUpStatus == 0) && (StartUpCounter != 0xFFFF));
-
- if ((RCC->CTRL & RCC_CTRL_HSISTBL) != RESET)
- {
- HSIStartUpStatus = (uint32_t)0x01;
- }
- else
- {
- HSIStartUpStatus = (uint32_t)0x00;
- }
-
- // 只有 HSI 就绪之后则继续往下执行
- if (HSIStartUpStatus == RCC_CTRL_HSIEN) ///if (HSIStartUpStatus == RCC_CTRL_HSISTBL)
- {
- /*****************************************************************/
- //-------------------------------------------------------------//
- // 这两句是操作 FLASH 闪存用到的,如果不操作 FLASH,这两个注释掉也没影响
- // 使能 FLASH 预存取缓冲区
- ///FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
- // SYSCLK 周期与闪存访问时间的比例设置,这里统一设置成 2
- // 设置成 2 的时候, SYSCLK 低于 48M 也可以工作,如果设置成 0 或者 1 的时候,
- // 如果配置的 SYSCLK 超出了范围的话,则会进入硬件错误,程序就死了
- // 0: 0 < SYSCLK <= 24M
- // 1: 24< SYSCLK <= 48M
- // 2: 48< SYSCLK <= 72M
- ///FLASH_SetLatency(FLASH_Latency_2);
- //------------------------------------------------------------//
- // AHB 预分频因子设置为 1 分频, HCLK = SYSCLK
- RCC_AHBCLKConfig(RCC_SYSCLK_Div1);
- // APB2 预分频因子设置为 1 分频, PCLK2 = HCLK
- RCC_APB2CLKConfig(RCC_AHBCLK_Div1);
- // APB1 预分频因子设置为 2 分频, PCLK1 = HCLK/2
- RCC_APB1CLKConfig(RCC_AHBCLK_Div2);
- //-----------设置各种频率主要就是在这里设置-------------------//
- // 设置 PLL 时钟来源为 HSI,设置 PLL 倍频因子
- // PLLCLK = 4MHz * pllmul
- RCC_PLLConfig(RCC_PLLRefClk_HSE_Div2, pllmult,RCC_Range_LessEqual_72Mhz);//HSI是内部晶体频率/2 * pllnum = 8/2 * pllnum STM32F103是内部8HMz
- //-- -----------------------------------------------------//
- // 开启 PLL
- RCC_PLLCmd(ENABLE);
- // 等待 PLL 稳定
- while (RCC_GetFlagStatus(RCC_FLAG_PLLSTBL) == RESET) {}
- // 当 PLL 稳定之后,把 PLL 时钟切换为系统时钟 SYSCLK
- RCC_SYSCLKConfig(RCC_SYSCLKSelction_PLL);
- // 读取时钟切换状态位,确保 PLLCLK 被选为系统时钟
- while (RCC_GetSYSCLKSelction() != 0x08) {}
- }
- else
- {
- // 如果 HSI 开启失败,那么程序就会来到这里,用户可在这里添加出错的代码处理
- // 当 HSE 开启失败或者故障的时候,单片机会自动把 HSI 设置为系统时钟,
- // HSI 是内部的高速时钟, 8MHZ
- while (1) {}
- }
- }
- 调用这个函数,内部默认是HSI = (48/6) MHz,也就是8MHz,这里16倍频
- setSysClockHSI(RCC_PLLMult_16);//没有外部晶体,用AT32F403A内部晶体,内部时钟使用64MHz,8/2 *16 = 64MHz
- ==============================================================================
- 如果是SXX32的底层库,那么改成以下写法:
- static void setSysClockHSI(uint32_t pllmul)
- {
- __IO uint32_t HSIStartUpStatus = 0;
- // 把 RCC 外设初始化成复位状态
- RCC_DeInit();
- //使能 HSI
- RCC_HSICmd(ENABLE);
- // 等待 HSI 就绪
- HSIStartUpStatus = RCC->CR & RCC_CR_HSIRDY;
- // 只有 HSI 就绪之后则继续往下执行
- if (HSIStartUpStatus == RCC_CR_HSIRDY)
- {
- //-------------------------------------------------------------//
- // 这两句是操作 FLASH 闪存用到的,如果不操作 FLASH,这两个注释掉也没影响
- // 使能 FLASH 预存取缓冲区
- FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
- // SYSCLK 周期与闪存访问时间的比例设置,这里统一设置成 2
- // 设置成 2 的时候, SYSCLK 低于 48M 也可以工作,如果设置成 0 或者 1 的时候,
- // 如果配置的 SYSCLK 超出了范围的话,则会进入硬件错误,程序就死了
- // 0: 0 < SYSCLK <= 24M
- // 1: 24< SYSCLK <= 48M
- // 2: 48< SYSCLK <= 72M
- FLASH_SetLatency(FLASH_Latency_2);
- //------------------------------------------------------------//
- // AHB 预分频因子设置为 1 分频, HCLK = SYSCLK
- RCC_HCLKConfig(RCC_SYSCLK_Div1);
- // APB2 预分频因子设置为 1 分频, PCLK2 = HCLK
- RCC_PCLK2Config(RCC_HCLK_Div1);
- // APB1 预分频因子设置为 2 分频, PCLK1 = HCLK/2
- RCC_PCLK1Config(RCC_HCLK_Div2);
- //-----------设置各种频率主要就是在这里设置-------------------//
- // 设置 PLL 时钟来源为 HSI,设置 PLL 倍频因子
- // PLLCLK = 4MHz * pllmul
- RCC_PLLConfig(RCC_PLLSource_HSI_Div2, pllmul);//HSI是内部晶体频率/2 * pllnum = 8/2 * pllnum STM32F103是内部8HMz
- //-- -----------------------------------------------------//
- // 开启 PLL
- RCC_PLLCmd(ENABLE);
- // 等待 PLL 稳定
- while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {}
- // 当 PLL 稳定之后,把 PLL 时钟切换为系统时钟 SYSCLK
- RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
- // 读取时钟切换状态位,确保 PLLCLK 被选为系统时钟
- while (RCC_GetSYSCLKSource() != 0x08) {}
- }
- else
- {
- // 如果 HSI 开启失败,那么程序就会来到这里,用户可在这里添加出错的代码处理
- // 当 HSE 开启失败或者故障的时候,单片机会自动把 HSI 设置为系统时钟,
- // HSI 是内部的高速时钟, 8MHZ
- while (1) {}
- }
- }
- setSysClockHSI(RCC_PLLMul_16);//使用内部晶体,8/2 *16 = 64MHz
经测试,用AT32F403A pin to pin SXX32F103,内部时钟可以运行72MHz都是ok的 @21小跑堂
|