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_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>&copy; Copyright (c) AirM2M.
  * All rights reserved.</center></h2>
  *
  * <h2><center>&copy; 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值