搜索

[AT32F403/403A] AT32F403A的内部时钟HSI倍频作主频的使用

[复制链接]
474|3
 楼主 | 2021-4-8 14:09 | 显示全部楼层 |阅读模式
本帖最后由 hejun96 于 2021-4-10 15:15 编辑

#申请原创#

AT32F403A的内部时钟HSI使用





     最近使用了AT32F403ARCT7,用来pin to pin STM32F103RCT6,内部时钟HSI使用稳定。下面介绍下用HSI PLL锁相环时钟倍频后作主频的初始化:
     
  1. AT32F403A默认使用的是HSE = 8MHz,倍频的方式到240MHz主频


  2. 我这里把它改成内部64MHz为例子,这里的寄存器我使用的是AT32的底层库:

  3. static void setSysClockHSI(uint32_t pllmult)
  4. {
  5.         __IO uint32_t HSIStartUpStatus = 0, StartUpCounter = 0;//StartUpCounter 是AT32底层库需要

  6.         // 把 RCC 外设初始化成复位状态
  7.         ///RCC_Reset();///RCC_DeInit();

  8.         //使能 HSI
  9.         RCC_HSICmd(ENABLE);

  10.         // 等待 HSI 就绪
  11.         do
  12.         {
  13.                 HSIStartUpStatus = RCC->CTRL & RCC_CTRL_HSISTBL;
  14.                
  15. /***此处和STM32F103有点不一样,因为AT32F403A主频高于STM32F103***/
  16.                 StartUpCounter++;//
  17.         }
  18.         while((HSIStartUpStatus == 0) && (StartUpCounter != 0xFFFF));
  19.         
  20.         if ((RCC->CTRL & RCC_CTRL_HSISTBL) != RESET)
  21.         {
  22.                 HSIStartUpStatus = (uint32_t)0x01;
  23.         }
  24.         else
  25.         {
  26.                 HSIStartUpStatus = (uint32_t)0x00;
  27.         }
  28.         
  29.         // 只有 HSI 就绪之后则继续往下执行
  30.         if (HSIStartUpStatus == RCC_CTRL_HSIEN) ///if (HSIStartUpStatus == RCC_CTRL_HSISTBL)
  31.         {
  32. /*****************************************************************/
  33.                 //-------------------------------------------------------------//
  34.                 // 这两句是操作 FLASH 闪存用到的,如果不操作 FLASH,这两个注释掉也没影响
  35.                 // 使能 FLASH 预存取缓冲区
  36.                 ///FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

  37.                 // SYSCLK 周期与闪存访问时间的比例设置,这里统一设置成 2
  38.                 // 设置成 2 的时候, SYSCLK 低于 48M 也可以工作,如果设置成 0 或者 1 的时候,
  39.                 // 如果配置的 SYSCLK 超出了范围的话,则会进入硬件错误,程序就死了
  40.                 // 0: 0 < SYSCLK <= 24M
  41.                 // 1: 24< SYSCLK <= 48M
  42.                 // 2: 48< SYSCLK <= 72M

  43.                 ///FLASH_SetLatency(FLASH_Latency_2);
  44.                 //------------------------------------------------------------//

  45.                 // AHB 预分频因子设置为 1 分频, HCLK = SYSCLK
  46.                 RCC_AHBCLKConfig(RCC_SYSCLK_Div1);

  47.                 // APB2 预分频因子设置为 1 分频, PCLK2 = HCLK
  48.                 RCC_APB2CLKConfig(RCC_AHBCLK_Div1);

  49.                 // APB1 预分频因子设置为 2 分频, PCLK1 = HCLK/2
  50.                 RCC_APB1CLKConfig(RCC_AHBCLK_Div2);

  51.                 //-----------设置各种频率主要就是在这里设置-------------------//
  52.                 // 设置 PLL 时钟来源为 HSI,设置 PLL 倍频因子
  53.                 // PLLCLK = 4MHz * pllmul
  54.                 RCC_PLLConfig(RCC_PLLRefClk_HSE_Div2, pllmult,RCC_Range_LessEqual_72Mhz);//HSI是内部晶体频率/2 * pllnum = 8/2 * pllnum STM32F103是内部8HMz
  55.                 //-- -----------------------------------------------------//

  56.                 // 开启 PLL
  57.                 RCC_PLLCmd(ENABLE);

  58.                 // 等待 PLL 稳定
  59.                 while (RCC_GetFlagStatus(RCC_FLAG_PLLSTBL) == RESET) {}

  60.                 // 当 PLL 稳定之后,把 PLL 时钟切换为系统时钟 SYSCLK
  61.                 RCC_SYSCLKConfig(RCC_SYSCLKSelction_PLL);

  62.                 // 读取时钟切换状态位,确保 PLLCLK 被选为系统时钟
  63.                 while (RCC_GetSYSCLKSelction() != 0x08) {}
  64.         }
  65.         else
  66.         {
  67.                 // 如果 HSI 开启失败,那么程序就会来到这里,用户可在这里添加出错的代码处理
  68.                 // 当 HSE 开启失败或者故障的时候,单片机会自动把 HSI 设置为系统时钟,
  69.                 // HSI 是内部的高速时钟, 8MHZ
  70.                 while (1) {}
  71.         }
  72. }

  73. 调用这个函数,内部默认是HSI = (48/6) MHz,也就是8MHz,这里16倍频

  74. setSysClockHSI(RCC_PLLMult_16);//没有外部晶体,用AT32F403A内部晶体,内部时钟使用64MHz,8/2 *16 = 64MHz



  75. ==============================================================================


  76. 如果是SXX32的底层库,那么改成以下写法:
  77. static void setSysClockHSI(uint32_t pllmul)
  78. {
  79.         __IO uint32_t HSIStartUpStatus = 0;

  80.         // 把 RCC 外设初始化成复位状态
  81.         RCC_DeInit();

  82.         //使能 HSI
  83.         RCC_HSICmd(ENABLE);

  84.         // 等待 HSI 就绪
  85.         HSIStartUpStatus = RCC->CR & RCC_CR_HSIRDY;

  86.         // 只有 HSI 就绪之后则继续往下执行
  87.         if (HSIStartUpStatus == RCC_CR_HSIRDY)
  88.         {
  89.                 //-------------------------------------------------------------//
  90.                 // 这两句是操作 FLASH 闪存用到的,如果不操作 FLASH,这两个注释掉也没影响
  91.                 // 使能 FLASH 预存取缓冲区
  92.                 FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

  93.                 // SYSCLK 周期与闪存访问时间的比例设置,这里统一设置成 2
  94.                 // 设置成 2 的时候, SYSCLK 低于 48M 也可以工作,如果设置成 0 或者 1 的时候,
  95.                 // 如果配置的 SYSCLK 超出了范围的话,则会进入硬件错误,程序就死了
  96.                 // 0: 0 < SYSCLK <= 24M
  97.                 // 1: 24< SYSCLK <= 48M
  98.                 // 2: 48< SYSCLK <= 72M

  99.                 FLASH_SetLatency(FLASH_Latency_2);
  100.                 //------------------------------------------------------------//

  101.                 // AHB 预分频因子设置为 1 分频, HCLK = SYSCLK
  102.                 RCC_HCLKConfig(RCC_SYSCLK_Div1);

  103.                 // APB2 预分频因子设置为 1 分频, PCLK2 = HCLK
  104.                 RCC_PCLK2Config(RCC_HCLK_Div1);

  105.                 // APB1 预分频因子设置为 2 分频, PCLK1 = HCLK/2
  106.                 RCC_PCLK1Config(RCC_HCLK_Div2);

  107.                 //-----------设置各种频率主要就是在这里设置-------------------//
  108.                 // 设置 PLL 时钟来源为 HSI,设置 PLL 倍频因子
  109.                 // PLLCLK = 4MHz * pllmul
  110.                 RCC_PLLConfig(RCC_PLLSource_HSI_Div2, pllmul);//HSI是内部晶体频率/2 * pllnum = 8/2 * pllnum STM32F103是内部8HMz
  111.                 //-- -----------------------------------------------------//

  112.                 // 开启 PLL
  113.                 RCC_PLLCmd(ENABLE);

  114.                 // 等待 PLL 稳定
  115.                 while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {}

  116.                 // 当 PLL 稳定之后,把 PLL 时钟切换为系统时钟 SYSCLK
  117.                 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

  118.                 // 读取时钟切换状态位,确保 PLLCLK 被选为系统时钟
  119.                 while (RCC_GetSYSCLKSource() != 0x08) {}
  120.         }
  121.         else
  122.         {
  123.                 // 如果 HSI 开启失败,那么程序就会来到这里,用户可在这里添加出错的代码处理
  124.                 // 当 HSE 开启失败或者故障的时候,单片机会自动把 HSI 设置为系统时钟,
  125.                 // HSI 是内部的高速时钟, 8MHZ
  126.                 while (1) {}
  127.         }
  128. }

  129. setSysClockHSI(RCC_PLLMul_16);//使用内部晶体,8/2 *16 = 64MHz
复制代码
       经测试,用AT32F403A pin to pin SXX32F103,内部时钟可以运行72MHz都是ok的

使用特权

评论回复
| 2021-4-8 15:34 | 显示全部楼层
很不错的,感谢楼主分享

使用特权

评论回复
| 2021-4-8 19:03 | 显示全部楼层
内部HSI精度咋样?测试过没?

使用特权

评论回复
 楼主 | 2021-4-8 19:15 | 显示全部楼层
chenjun89 发表于 2021-4-8 19:03
内部HSI精度咋样?测试过没?

很稳定,比较准

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 我要提问 投诉建议 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表