Air001 使用内部时钟源,倍频跑48MHz主频例程
Air001 使用内部时钟源,倍频跑48MHz主频例程
- ✨根据该芯片手册描述,Air001最高48MHz工作频率。
- 🍁Air001使用内部时钟源,固定倍频(X2)路线:

🛠频率和CPU访问存储器周期调整
- 🌿系统主频和Flash Delay等级匹配关系表

- 🔖对应代码:
if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) { //=48MHz LATENCY=1
//系统时钟周期Error_Handler();}
🔨系统时钟配置
- 🔧使用内容RC振动器配置为24MHz,通过倍频器(PLL)固定的2倍频,得到48MHz.
/*** @brief 配置系统时钟* @param HSICLKSource_SET:选择HSI时钟频率* @arg @ref RCC_HSICALIBRATION_8MHz:8M时钟* @arg @ref RCC_HSICALIBRATION_16MHz:16M时钟* @arg @ref RCC_HSICALIBRATION_22p12MHz:22.12M时钟* @arg @ref RCC_HSICALIBRATION_24MHz:24M时钟* @retval 无*/static void APP_SystemClockConfig(uint32_t HSICLKSource_SET)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSI ; /* 配置HSE、HSI、LSI、LSE */RCC_OscInitStruct.HSIState = RCC_HSI_ON; /* 开启内部高速时钟HSI */
// RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1; /* HSI不分频 HSIDIV*/RCC_OscInitStruct.HSICalibrationValue = HSICLKSource_SET; /* HSI校准频率8MHz */
// RCC_OscInitStruct.HSEState = RCC_HSE_OFF; /* 关闭HSE */
// RCC_OscInitStruct.HSEFreq = RCC_HSE_16_32MHz; /* HSE频率范围16~32MHz */
// RCC_OscInitStruct.LSIState = RCC_LSI_ON; /*开启内部低速时钟 关闭LSI:RCC_LSI_OFF *//* RCC_OscInitStruct.LSEDriver = RCC_LSEDRIVE_MEDIUM; */ /* 默认LSE驱动能力 */RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; /* 开启PLL 关闭PLL:RCC_PLL_OFF*/
// RCC_OscInitStruct.PLL.PLLSource =RCC_PLLSOURCE_HSI; //RCC_PLLSOURCE_HSI RCC_PLLSOURCE_NONERCC_OscInitStruct.PLL.PLLSource =RCC_PLLSOURCE_HSI;/* PLL内部时钟源 RCC_PLLSOURCE_NONE*/if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/* 配置振荡器 */if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {Error_Handler();}RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1;/* 配置SYSCLK、HCLK、PCLK */RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; /* 配置系统时钟为HSI RCC_SYSCLKSOURCE_PLLCLK RCC_SYSCLKSOURCE_HSI*/RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; /* AHB时钟不分频 */RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; /* APB时钟不分频 *//* 配置时钟源 */if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) { //=48MHz LATENCY=1
//系统时钟周期Error_Handler();}
}
- 🔧使用内容RC振动器配置为8 - 24MHz,不通过倍频器(PLL)固定的2倍频,走分频器路线:

/*** @brief 配置系统时钟* @param HSICLKSource_SET:选择HSI时钟频率* @arg @ref RCC_HSICALIBRATION_8MHz:8M时钟* @arg @ref RCC_HSICALIBRATION_16MHz:16M时钟* @arg @ref RCC_HSICALIBRATION_22p12MHz:22.12M时钟* @arg @ref RCC_HSICALIBRATION_24MHz:24M时钟* @retval 无*/
static void APP_SystemClockConfig(uint32_t HSICLKSource_SET)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI \| RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE; /* 配置HSE、HSI、LSI、LSE */RCC_OscInitStruct.HSIState = RCC_HSI_ON; /* 开启内部高速时钟HSI */RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1; /* HSI不分频 */RCC_OscInitStruct.HSICalibrationValue = HSICLKSource_SET; /* HSI校准频率8MHz */RCC_OscInitStruct.HSEState = RCC_HSE_OFF; /* 关闭HSE */
// RCC_OscInitStruct.HSEFreq = RCC_HSE_16_32MHz; /* HSE频率范围16~32MHz */RCC_OscInitStruct.LSIState = RCC_LSI_ON; /*开启内部低速时钟 关闭LSI:RCC_LSI_OFF */RCC_OscInitStruct.LSEState = RCC_LSE_OFF; /* 关闭LSE *//* RCC_OscInitStruct.LSEDriver = RCC_LSEDRIVE_MEDIUM; */ /* 默认LSE驱动能力 */// RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; /* 开启PLL 关闭PLL:RCC_PLL_OFF*/
// RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; /* PLL内部时钟源 RCC_PLLSOURCE_NONE*/if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {Error_Handler();}/* 配置振荡器 */if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {Error_Handler();}RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1;/* 配置SYSCLK、HCLK、PCLK */RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; /* 配置系统时钟为HSI RC*/RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; /* AHB时钟不分频 */RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; /* APB时钟不分频 *//* 配置时钟源 */if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) {Error_Handler();}
}
📘时钟测试代码:
/********************************************************************************* @file main.c* @author MCU Application Team* @brief Main program body******************************************************************************* @attention** <h2><center>© Copyright (c) AirM2M.* All rights reserved.</center></h2>** <h2><center>© Copyright (c) 2016 STMicroelectronics.* All rights reserved.</center></h2>** This software component is licensed by ST under BSD 3-Clause license,* the "License"; You may not use this file except in compliance with the* License. You may obtain a copy of the License at:* opensource.org/licenses/BSD-3-Clause********************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usart.h"
#include "gpio.h"
#include "stdio.h"
/* Private define ------------------------------------------------------------*/
#define CPU_8MHZ 8000000u
#define CPU_12MHZ 12000000u
#define CPU_16MHZ 16000000u
#define CPU_22P12MHZ 22120000u
#define CPU_24MHZ 24000000u
#define CPU_48MHZ 48000000u/* Private variables ---------------------------------------------------------*/
/* Private user code ---------------------------------------------------------*/
static void APP_SystemClockConfig(uint32_t HSICLKSource_SET);void Hal_delay_us(uint32_t us)
{// 确定每个微秒所需的滴答定时器计数值uint32_t ticks = us * (SystemCoreClock);// 设置滴答定时器的计数值SysTick->LOAD = ticks - 1;SysTick->VAL = 0;// 启用滴答定时器,并等待定时器计数完成SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;while(!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk));// 关闭滴答定时器SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}//void delay_us(uint32_t us)
//{
// uint32_t delay = (HAL_RCC_GetHCLKFreq() / 4000000 * us);
// while (delay--)
// {
// ;
// }
//}
#define DLY_TIM_Handle (&htim16)
TIM_HandleTypeDef htim16;
/* TIM16 init function */
void MX_TIM16_Init(void)
{/* USER CODE BEGIN TIM16_Init 0 *//* USER CODE END TIM16_Init 0 */__HAL_RCC_TIM16_CLK_ENABLE();/* USER CODE BEGIN TIM16_Init 1 *//* USER CODE END TIM16_Init 1 */htim16.Instance = TIM16;htim16.Init.Prescaler = 24000 - 1; //24000000/24000=1000htim16.Init.CounterMode = TIM_COUNTERMODE_UP;htim16.Init.Period = 65535;htim16.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;htim16.Init.RepetitionCounter = 0;htim16.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;if(HAL_TIM_Base_Init(&htim16) != HAL_OK) {Error_Handler();}/* USER CODE BEGIN TIM16_Init 2 *//* USER CODE END TIM16_Init 2 */}void delay_ms(uint16_t nus)
{__HAL_TIM_SET_COUNTER(DLY_TIM_Handle, 0);__HAL_TIM_ENABLE(DLY_TIM_Handle);while(__HAL_TIM_GET_COUNTER(DLY_TIM_Handle) < nus) {}__HAL_TIM_DISABLE(DLY_TIM_Handle);
}/* Private macro -------------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*//*** @brief 应用程序入口函数.* @retval int*/
int main(void)
{/* 初始化所有外设,Flash接口,SysTick */HAL_Init();APP_SystemClockConfig(RCC_HSICALIBRATION_24MHz);/* 初始化GPIO */MX_GPIO_Init();MX_USART_UART_Init();//串口:PA2 PA3// __HAL_RCC_TIM16_CLK_ENABLE();MX_TIM16_Init();uint32_t Sysclock = HAL_RCC_GetSysClockFreq() ;printf("Sysclock:%d \r\n",Sysclock);while(1) {/* LED翻转 */switch(Sysclock){case CPU_8MHZ:HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_1); break;case CPU_16MHZ: HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);break;case CPU_24MHZ:HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3);break;case CPU_48MHZ:HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_3);break;default :break;}printf("Sysclock:%d \r\n",Sysclock);delay_ms(1000);
// HAL_Delay(1000) ;// __NOP();/* 延时250ms */// Hal_delay_us(250);// HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);// Hal_delay_us(250);// HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3);// Hal_delay_us(250);// printf("Hello world2 \n");}
}/*** @brief 配置系统时钟* @param HSICLKSource_SET:选择HSI时钟频率* @arg @ref RCC_HSICALIBRATION_8MHz:8M时钟* @arg @ref RCC_HSICALIBRATION_16MHz:16M时钟* @arg @ref RCC_HSICALIBRATION_22p12MHz:22.12M时钟* @arg @ref RCC_HSICALIBRATION_24MHz:24M时钟* @retval 无*/static void APP_SystemClockConfig(uint32_t HSICLKSource_SET)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSI ; /* 配置HSE、HSI、LSI、LSE */RCC_OscInitStruct.HSIState = RCC_HSI_ON; /* 开启内部高速时钟HSI */
// RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1; /* HSI不分频 HSIDIV*/RCC_OscInitStruct.HSICalibrationValue = HSICLKSource_SET; /* HSI校准频率8MHz */
// RCC_OscInitStruct.HSEState = RCC_HSE_OFF; /* 关闭HSE */
// RCC_OscInitStruct.HSEFreq = RCC_HSE_16_32MHz; /* HSE频率范围16~32MHz */
// RCC_OscInitStruct.LSIState = RCC_LSI_ON; /*开启内部低速时钟 关闭LSI:RCC_LSI_OFF *//* RCC_OscInitStruct.LSEDriver = RCC_LSEDRIVE_MEDIUM; */ /* 默认LSE驱动能力 */RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; /* 开启PLL 关闭PLL:RCC_PLL_OFF*/
// RCC_OscInitStruct.PLL.PLLSource =RCC_PLLSOURCE_HSI; //RCC_PLLSOURCE_HSI RCC_PLLSOURCE_NONERCC_OscInitStruct.PLL.PLLSource =RCC_PLLSOURCE_HSI;/* PLL内部时钟源 RCC_PLLSOURCE_NONE*/if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/* 配置振荡器 */if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {Error_Handler();}RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1;/* 配置SYSCLK、HCLK、PCLK */RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; /* 配置系统时钟为HSI RCC_SYSCLKSOURCE_PLLCLK RCC_SYSCLKSOURCE_HSI*/RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; /* AHB时钟不分频 */RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; /* APB时钟不分频 *//* 配置时钟源 */if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) { //=48MHz LATENCY=1
//系统时钟周期Error_Handler();}
}/*** @brief 错误执行函数* @param 无* @retval 无*/
void Error_Handler(void)
{while(1) {}
}#ifdef USE_FULL_ASSERT
/*** @brief 输出产生断言错误的源文件名及行号* @param file:源文件名指针* @param line:发生断言错误的行号* @retval 无*/
void assert_failed(uint8_t* file, uint32_t line)
{/* 用户可以根据需要添加自己的打印信息,例如: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* 无限循环 */while(1) {}
}
#endif /* USE_FULL_ASSERT *//************************ (C) COPYRIGHT AirM2M *****END OF FILE******************/

📚测试工程
链接:https://pan.baidu.com/s/1ygHz3s5aDP4gZl1r1JgnzA?pwd=zi2g
提取码:zi2g