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_NONE
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_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=1000
htim16.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_NONE
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_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