本帖最后由 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小跑堂 |