STM32学习笔记
时钟配置
-
时钟树
-
系统时钟倍频到168MHz
void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
/* Enable Power Control clock */
__HAL_RCC_PWR_CLK_ENABLE();
/* The voltage scaling allows optimizing the power consumption when the device is
clocked below the maximum system frequency, to update the voltage scaling value
regarding system frequency refer to product datasheet. */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/* Enable HSE Oscillator and activate PLL with HSE as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
/* STM32F405x/407x/415x/417x Revision Z devices: prefetch is supported */
if (HAL_GetREVID() == 0x1001)
{
/* Enable the Flash prefetch */
__HAL_FLASH_PREFETCH_BUFFER_ENABLE();
}
}
-
注意:HSE默认频率为25MHz,在 stm32f4xx_hal_conf.h 中按照实际情况修改外部高速晶振频率值 HSE_VALUE
-
验证时钟频率
- 输出系统频率到MCO脚
- 调用函数获取时钟频率值
// Debug 仿真 wathch 只能查看全局变量
uint32_t SySCLKFreq = 0;
uint32_t HCLKFreq = 0;
uint32_t PCLK1Freq = 0;
uint32_t PCLK2Freq = 0;
int main(void){
HAL_Init();
SystemClock_Config();
HAL_RCC_MCOConfig(RCC_MCO2,RCC_MCO2SOURCE_SYSCLK,RCC_MCODIV_1);
SystemCoreClockUpdate();
SySCLKFreq = HAL_RCC_GetSysClockFreq();
HCLKFreq = HAL_RCC_GetHCLKFreq();
PCLK1Freq = HAL_RCC_GetPCLK1Freq();
PCLK2Freq = HAL_RCC_GetPCLK2Freq();
}
- 注意:修改系统时钟频率后,也要把systick配置好
HAL_SetTickFreq(SySCLKFreq/1000);
报错和异常处理:
使用 HAL_Delay() 函数后,程序卡在 while 循环中,HAL_GetTick()也一直为零
原因:uwTick 值是 HAL_IncTick() 函数中以 uwTickFreq 累加,而 HAL_IncTick() 应当在 SysTick_Handler() 中断中处理
解决:检查是有 HAL_IncTick() 是否有在 SysTick_Handler() 执行,或者查看 SysTick_Handler() 是否有重写
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App