打印
[资料干货]

AT32F403A的内部时钟 HSI 倍频作主频的使用

[复制链接]
189|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
一汀烟雨|  楼主 | 2022-10-7 23:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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的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的

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

65

主题

65

帖子

0

粉丝