简易时钟树
main.c
#include "sys.h"
...
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
...
}
sys.h
#ifndef __SYS_H_
#define __SYS_H_
#include "stm32f1xx.h"
void stm32_clock_init(uint32_t plln); // plln:PLL倍频数
#endif
要实现void stm32_clock_init(uint32_t plln),需要实现两个函数:
HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct);
HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency);
函数返回类型
typedef enum
{
HAL_OK = 0x00U,
HAL_ERROR = 0x01U,
HAL_BUSY = 0x02U,
HAL_TIMEOUT = 0x03U
} HAL_StatusTypeDef;
RCC_OscInitTypeDef参数是一个结构体
typedef struct
{
uint32_t OscillatorType; // 振荡器类型
/*
#define RCC_OSCILLATORTYPE_NONE 0x00000000U
#define RCC_OSCILLATORTYPE_HSE 0x00000001U
#define RCC_OSCILLATORTYPE_HSI 0x00000002U
#define RCC_OSCILLATORTYPE_LSE 0x00000004U
#define RCC_OSCILLATORTYPE_LSI 0x00000008U
*/
uint32_t HSEState; // 外部高速时钟状态
/*
#define RCC_HSE_OFF 0x00000000U
#define RCC_HSE_ON RCC_CR_HSEON
#define RCC_HSE_BYPASS ((uint32_t)(RCC_CR_HSEBYP | RCC_CR_HSEON))
*/
uint32_t HSEPredivValue; // HSE预分频值
/*
#define RCC_HSE_PREDIV_DIV1 0x00000000U
#define RCC_HSE_PREDIV_DIV2 RCC_CFGR_PLLXTPRE
*/
uint32_t LSEState; // 外部低速时钟(LSE)状态
uint32_t HSIState; // 内部高速时钟(HSI)状态
uint32_t HSICalibrationValue; // HSI校准值
uint32_t LSIState; // 内部低速时钟(LSI)状态
RCC_PLLInitTypeDef PLL; // PLL配置结构体
/*
typedef struct
{
uint32_t PLLState; // PLLState: The new state of the PLL.
uint32_t PLLSource; // PLLSource: PLL entry clock source.
uint32_t PLLMUL; // PLLMUL: Multiplication factor for PLL VCO input clock
} RCC_PLLInitTypeDef;
*/
} RCC_OscInitTypeDef;
RCC_ClkInitTypeDef也是一个结构体
typedef struct
{
uint32_t ClockType; /* The clock to be configured.*/
uint32_t SYSCLKSource; /* The clock source (SYSCLKS) used as system clock.*/
uint32_t AHBCLKDivider; /* The AHB clock (HCLK) divider. This clock is derived from the system clock (SYSCLK).*/
uint32_t APB1CLKDivider; /* The APB1 clock (PCLK1) divider. This clock is derived from the AHB clock (HCLK).*/
uint32_t APB2CLKDivider; /* The APB2 clock (PCLK2) divider. This clock is derived from the AHB clock (HCLK).*/
} RCC_ClkInitTypeDef;
对应上原理图,写出如下代码
sys.c
#include "sys.h"
void stm32_clock_init(uint32_t plln)
{
HAL_StatusTypeDef ret = HAL_ERROR;
RCC_OscInitTypeDef rcc_osc_init = {0};
RCC_ClkInitTypeDef rcc_clk_init = {0};
rcc_osc_init.OscillatorType = RCC_OSCILLATORTYPE_HSE;
rcc_osc_init.HSEState = RCC_HSE_ON;
rcc_osc_init.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
rcc_osc_init.PLL.PLLState = RCC_PLL_ON;
rcc_osc_init.PLL.PLLSource = RCC_PLLSOURCE_HSE;
rcc_osc_init.PLL.PLLMUL = plln;
ret = HAL_RCC_OscConfig(&rcc_osc_init);
if(ret != HAL_OK)
{
while(1);
}
rcc_clk_init.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
rcc_clk_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
rcc_clk_init.AHBCLKDivider = RCC_SYSCLK_DIV1;
rcc_clk_init.APB1CLKDivider = RCC_HCLK_DIV2;
rcc_clk_init.APB2CLKDivider = RCC_HCLK_DIV1;
ret = HAL_RCC_ClockConfig(&rcc_clk_init, FLASH_LATENCY_2); // FLASH等待周期
if(ret != HAL_OK)
{
while(1);
}
}
结果对不对?
第一编译没问题
第二调试仿真看结果
执行前
执行后
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_41729472/article/details/146991911
|