一:前言
我们使用的是STM32F103CT86的型号
1:介绍
时钟在在我们的单片机中非常重要,相当于我们的人类的心脏;简单来说,时钟是具有周期性的脉冲信号,最常用的是占空比50%的方波;
2:默认时钟
#include "stm32f1xx_hal.h"int main(void){//这个函数用于初始化HAL库;它必须是主程序中执行的第一条指令HAL_Init();//PA8引脚输出系统时钟HAL_RCC_MCOConfig(RCC_MCO1,RCC_MCO1SOURCE_SYSCLK,RCC_MCODIV_1);
}
每个文件都是从汇编文件开始的,
对于我们的单片机而言不管我们上电复位,按键复位,NVIC system ,程序都会进入复位向量;
可以看到复位向量里面首先调用了SystemInit;然后去__main(多了__,首先做了一些准备的工作,其次才开始调用我们c语言中的mian函数)
二:SystemInit
我们研究源码看看在复位向量第一个调用的SystemInit,SystemInit里面到底做了什么
A:时钟控制寄存器(RCC_CR)
/* Reset the RCC clock configuration to the default reset state(for debug purpose) *//* Set HSION bit */RCC->CR |= 0x00000001U; //时钟控制寄存器(RCC_CR)
B:时钟配置寄存器(RCC_CFGR)
/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#if !defined(STM32F105xC) && !defined(STM32F107xC)RCC->CFGR &= 0xF8FF0000U;
#elseRCC->CFGR &= 0xF0FF0000U;
#endif /* STM32F105xC */ /* Reset HSEON, CSSON and PLLON bits */RCC->CR &= 0xFEF6FFFFU;/* Reset HSEBYP bit */RCC->CR &= 0xFFFBFFFFU;/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */RCC->CFGR &= 0xFF80FFFFU;
0xF8FF0000U=1111 1000 1111 1111 0000 0000 0000 0000;
与操作--清零;用于清除需要的 BIT位(0),不影响其他位(1)
C:时钟控制寄存器(RCC_CR)
对时钟控制寄存器(RCC_CR)操作的2次
/* Reset HSEON, CSSON and PLLON bits */RCC->CR &= 0xFEF6FFFFU;/* Reset HSEBYP bit */RCC->CR &= 0xFFFBFFFFU;
0xFEF6FFFFU=1111 1110 1111 0110 1111 1111 1111 1111
第二次操作:RCC->CR &= 0xFFFBFFFFU;-----18位清零
我们可以看到只要失能HSEBYP的前提是关闭振荡器;所以操作RCC->CR寄存器才会分2次写,第一次:关闭振荡器;第二次:失能HSEBYP
D:时钟配置寄存器(RCC_CFGR)
RCC->CFGR &= 0xFF80FFFFU;
在上面配置过了CFGP寄存器为什么还要在配置一遍;因为和上面的CR寄存器一样,关闭某个东西是有前提的
E:实验
#include "stm32f1xx_hal.h"uint32_t GetPCLK1Freq;
uint32_t GetPCLK2Freq;
uint32_t GetHCLKFreq;
int main(void){//这个函数用于初始化HAL库;它必须是主程序中执行的第一条指令HAL_Init();//PA8引脚输出系统时钟HAL_RCC_MCOConfig(RCC_MCO1,RCC_MCO1SOURCE_SYSCLK,RCC_MCODIV_1);SystemCoreClockUpdate();GetHCLKFreq=HAL_RCC_GetHCLKFreq();GetPCLK1Freq=HAL_RCC_GetPCLK1Freq();GetPCLK2Freq=HAL_RCC_GetPCLK2Freq();
}
开启仿真
可以看到HSL系统默认的时钟为----0x007A1200=8000000=8MHZ;可以验证我们的实验正确。
void SystemInit (void)
{/* Reset the RCC clock configuration to the default reset state(for debug purpose) *//* Set HSION bit */RCC->CR |= 0x00000001U;/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#if !defined(STM32F105xC) && !defined(STM32F107xC)RCC->CFGR &= 0xF8FF0000U;
#elseRCC->CFGR &= 0xF0FF0000U;
#endif /* STM32F105xC */ /* Reset HSEON, CSSON and PLLON bits */RCC->CR &= 0xFEF6FFFFU;/* Reset HSEBYP bit */RCC->CR &= 0xFFFBFFFFU;/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */RCC->CFGR &= 0xFF80FFFFU;#if defined(STM32F105xC) || defined(STM32F107xC)/* Reset PLL2ON and PLL3ON bits */RCC->CR &= 0xEBFFFFFFU;/* Disable all interrupts and clear pending bits */RCC->CIR = 0x00FF0000U;/* Reset CFGR2 register */RCC->CFGR2 = 0x00000000U;
#elif defined(STM32F100xB) || defined(STM32F100xE)/* Disable all interrupts and clear pending bits */RCC->CIR = 0x009F0000U;/* Reset CFGR2 register */RCC->CFGR2 = 0x00000000U;
#else/* Disable all interrupts and clear pending bits */RCC->CIR = 0x009F0000U;
#endif /* STM32F105xC */#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)#ifdef DATA_IN_ExtSRAMSystemInit_ExtMemCtl(); #endif /* DATA_IN_ExtSRAM */
#endif #ifdef VECT_TAB_SRAMSCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#elseSCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif
}
三:HSL
目的:得到64M的系统时钟-------选择内部高速时钟(HSL)做为时钟源,通过PLL的倍率调节为64MHZ;同时PLL锁相环做为系统时钟源
#include "stm32f1xx_hal.h"void RCC_Clock_HSLInit(void)
{RCC_OscInitTypeDef RCC_OscInitType;RCC_ClkInitTypeDef RCC_ClkInitType;//选择HSL做为时钟源RCC_OscInitType.OscillatorType=RCC_OSCILLATORTYPE_HSI;RCC_OscInitType.HSIState=RCC_HSI_ON;RCC_OscInitType.HSICalibrationValue=RCC_HSICALIBRATION_DEFAULT;RCC_OscInitType.PLL.PLLState=RCC_PLL_ON; RCC_OscInitType.PLL.PLLSource=RCC_PLLSOURCE_HSI_DIV2;RCC_OscInitType.PLL.PLLMUL=RCC_PLL_MUL16;HAL_RCC_OscConfig(&RCC_OscInitType);//PLL做为系统时钟源RCC_ClkInitType.ClockType=(RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2);RCC_ClkInitType.SYSCLKSource=RCC_SYSCLKSOURCE_STATUS_PLLCLK;RCC_ClkInitType.AHBCLKDivider=RCC_SYSCLK_DIV1;RCC_ClkInitType.APB1CLKDivider=RCC_HCLK_DIV2;RCC_ClkInitType.APB2CLKDivider= RCC_HCLK_DIV1;HAL_RCC_ClockConfig(&RCC_ClkInitType,FLASH_LATENCY_2);}
频率越高,系统会越来越稳定;所以一般情况下我们选择使用内部的HSE,通过PLL可以转变为72HZ; 除非在外部晶振坏了或者考虑成本的情况下才会不会使用内部的晶振。
四:HSE
外部高速时钟
*HSE外部高速时钟做为系统时钟*/
void sys_stm32_clock_init(uint32_t plln)
{HAL_StatusTypeDef ret = HAL_ERROR;RCC_OscInitTypeDef RCC_OscInit = {0};RCC_ClkInitTypeDef RCC_ClkInit={0};//HSE外部时钟做为PLL时钟源RCC_OscInit.OscillatorType=RCC_OSCILLATORTYPE_HSE;/*选择振荡器类型*/RCC_OscInit.HSEState=RCC_HSE_ON; /*选择HSL状态*/RCC_OscInit.HSEPredivValue=RCC_HSE_PREDIV_DIV1; /*HSE的分频系数*/RCC_OscInit.PLL.PLLState=RCC_PLL_ON;RCC_OscInit.PLL.PLLSource=RCC_PLLSOURCE_HSE;RCC_OscInit.PLL.PLLMUL=plln; //RCC_PLL_MUL9ret=HAL_RCC_OscConfig(&RCC_OscInit);if (ret !=HAL_OK){while (1);}//PLL做为系统时钟RCC_ClkInit.ClockType=RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInit.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInit.AHBCLKDivider=RCC_HCLK_DIV1;RCC_ClkInit.APB1CLKDivider=RCC_HCLK_DIV2;RCC_ClkInit.APB2CLKDivider=RCC_HCLK_DIV1;ret=HAL_RCC_ClockConfig(&RCC_ClkInit,FLASH_LATENCY_2);if (ret !=HAL_OK){while (1);} }
HAL_StatusTypeDef
是一个在STM32 HAL (硬件抽象层) 库中定义的类型,用于表示函数调用的状态。这个类型通常用于返回函数执行的结果,以指示操作是否成功或出现了错误。
HAL_StatusTypeDef
通常定义为一个枚举,其中包含几个可能的值,如HAL_OK
、HAL_ERROR
、HAL_TIMEOUT
等。这些值用于表示函数调用的不同结果。例如,如果函数成功执行,它可能会返回HAL_OK
;如果发生错误,它可能会返回HAL_ERROR
。在STM32 HAL库中,许多函数都使用
HAL_StatusTypeDef
作为其返回类型。这使得调用者可以轻松地检查函数调用是否成功,并根据需要采取适当的操作。关于您提到的具体函数(如
HAL_CAN_ActivateNotification
、HAL_CAN_Start
、HAL_CAN_ConfigFilter
和HAL_UART_Receive_IT
),它们都是STM32 HAL库中的函数,用于配置和管理CAN和UART(通用异步收发传输器)外设。这些函数使用HAL_StatusTypeDef
作为返回类型,以指示操作是否成功。如果您在移植标准库的GPIO功能到HAL库工程时遇到
HAL_StatusTypeDef
未定义的问题,这通常意味着您可能没有正确包含必要的头文件或库文件。确保您已经包含了定义HAL_StatusTypeDef
的头文件(通常是stm32fxxx_hal.h
),并且您的项目配置正确,以便包含和链接STM32 HAL库。此外,请注意,当您在HAL库环境中工作时,您需要遵循HAL库的规范和约定。例如,使用HAL库提供的函数和数据结构来初始化和配置外设,而不是尝试直接使用标准库中的函数或数据结构。这有助于确保您的代码与HAL库兼容,并能够充分利用HAL库提供的功能和优势。
本文参考:STM32F10xxx参考手册书写详细文章,请转至参考手册
链接:https://pan.baidu.com/s/1HrL5dzuFoZGTopzMTuQMxQ?pwd=5j2p
提取码:5j2p
--来自百度网盘超级会员V2的分享