去学习除去了解该入门学习灯程序衍生出的stm32基础中的基础外,我们还需要有心的概念,本篇记录将stm32的五系统。
1、STM32的概念介绍
幅幅图时stm32的
车载设备1)蓝底框表示有机源,即:
①HSI是高速内部控制器,RC,频率为8MHz
②HS是高速外部设备,可接石英陶瓷器,或者接外部时钟源,频率范围为4MHz时〜16MHz的。
③LSI是低速内部时钟,RC振荡器,频率为40kHz的。(WDG看门狗使用该时钟源)
④LSE是低速外部时钟,接频率为32.768kHz的的石英晶体。(RTC实时
显示器使用该电容源)⑤PLL为锁相环倍频输出,其输入源选择为HSI/2、HSE或HSE/2。倍频性能为2~16倍,但输出频率最大不得7MHz。
其中HSE和LSE是通过外部的外部晶振输入的,一共四个脚管HSE的输入管脚是OSC_IN和OSC_OUT(8M),
LSE的管脚对应的通常为OSC32_IN和OSC32_OUT(32.768kHz2)
梯形表示器,例如:
梯形表示SYSCLK系统来源的形式可以使HSIRCCLKPLL、HSSc(即HSI标签、HSE标签、PLL)
3)绿色方框表示预分频器(prescaler)
4)该图片如何,
比如下图:上图深红色的路线来解释:PLL的源源经过前面的选择器按照实际为8MHz,PLL 9倍频后PLLCLK的频率为72MHz,则选择器SYSCLK(系统时钟)频率为72MHz,经过AHB分频器1分频后HCLK输出频率72MHz,APB1分频器2分频后PCLK1频率为36MHz;经过APB2分频器1分频后PCLK2频率为72MHz 。
5)时钟输出MCO脚(PA8),可以选择PLL输出的2分频,HSI,HSE或者系统时钟。
6)任何一个外设在使用之前,必须首先使能其相应的时钟。
7)需要记住几个重要的
时钟- SYSCLK(系统时钟)
- AHB 总线时钟
- APB1,最高
时钟到(低速)速度 速度 36MHz - APB2 总线时钟(高速),速度最高到 72MHz
- PLL
时钟目录贴一张《STM32中文》手册“中的时钟图,该图和上面的图表示的意思是一致的,我们看看官方是如何展示时钟框图的。
2,(时钟控制)RCC寄存器
typedef struct
{
__IO uint32_t CR; //HSI,HSE,CSS,PLL等的使能和就绪标志位
__IO uint32_t CFGR; //PLL等的时钟源选择,分频系数设定
__IO uint32_t CIR; //清除/使能 时钟就绪中断
__IO uint32_t APB2RSTR; //APB2线上外设复位寄存器
__IO uint32_t APB1RSTR; //APB1线上外设复位寄存器
__IO uint32_t AHBENR; //DMA,SDIO等时钟使能
__IO uint32_t APB2ENR; //APB2线上外设时钟使能
__IO uint32_t APB1ENR; //APB1线上外设时钟使能
__IO uint32_t BDCR; //备份域控制寄存器
__IO uint32_t CSR; //控制状态寄存器
} RCC_TypeDef;
上面是RCC芯片的结构体定义,结构体中的每个变量的哪个位代表什么需要我们参考《STM32中文手册》第6章的6.3小节RCC控制器描述来了解,现仅对一个变量CR贴出参考手册的描述,其他的资料了,参考手册目录。
3、系统
初始化对界面控制器的概念性的介绍,在写程序时我们一般不直接操作 RCC_TypeDef结构体,而是调用相应的库函数来编程。
在此我们先看一下库函数中系统默认如何初始化这些寄存器的,我们先看一段汇编程序,我们知道ç中默认的程序入口是主函数,那主函数的如何调用的呢,我们先来看看以下程序(该程序在startup_stm32f10x_hd.s中可以找到):
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT SystemInit
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
从上面的程序中可以实现在main函数调用前,调用了SystemInit函数,该函数的定义可以在system_stm32f10x.c中找到,源码如下:
#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
/* #define SYSCLK_FREQ_HSE HSE_VALUE */
#define SYSCLK_FREQ_24MHz 24000000
#else
/* #define SYSCLK_FREQ_HSE HSE_VALUE */
/* #define SYSCLK_FREQ_24MHz 24000000 */
/* #define SYSCLK_FREQ_36MHz 36000000 */
/* #define SYSCLK_FREQ_48MHz 48000000 */
/* #define SYSCLK_FREQ_56MHz 56000000 */
#define SYSCLK_FREQ_72MHz 72000000
#endif
/*!《 Uncomment the following line if you need to use external SRAM mounted
on STM3210E-EVAL board (STM32 High density and XL-density devices) or on
STM32100E-EVAL board (STM32 High-density value line devices) as data memory */
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
/* #define DATA_IN_ExtSRAM */
#endif
/*******************************************************************************
* Clock Definitions
*******************************************************************************/
#ifdef SYSCLK_FREQ_HSE
uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /*!《 System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_24MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_24MHz; /*!《 System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_36MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_36MHz; /*!《 System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_48MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz; /*!《 System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_56MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz; /*!《 System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_72MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz; /*!《 System Clock Frequency (Core Clock) */
#else /*!《 HSI Selected as System Clock source */
uint32_t SystemCoreClock = HSI_VALUE; /*!《 System Clock Frequency (Core Clock) */
#endif
__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
static void SetSysClock(void);
/**
* @brief Setup the microcontroller system
* Initialize the Embedded Flash Interface, the PLL and update the
* SystemCoreClock variable.
* @note This function should be used only after reset.
* @param None
* @retval None
*/
void SystemInit (void)
{
/* Reset the RCC clock configuration to the default reset state(for debug purpose) */
/* Set HSION bit */
RCC-》CR |= (uint32_t)0x00000001;
/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CL
RCC-》CFGR &= (uint32_t)0xF8FF0000;
#else
RCC-》CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F10X_CL */
/* Reset HSEON, CSSON and PLLON bits */
RCC-》CR &= (uint32_t)0xFEF6FFFF;
/* Reset HSEBYP bit */
RCC-》CR &= (uint32_t)0xFFFBFFFF;
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
RCC-》CFGR &= (uint32_t)0xFF80FFFF;
#ifdef STM32F10X_CL
/* Reset PLL2ON and PLL3ON bits */
RCC-》CR &= (uint32_t)0xEBFFFFFF;
/* Disable all interrupts and clear pending bits */
RCC-》CIR = 0x00FF0000;
/* Reset CFGR2 register */
RCC-》CFGR2 = 0x00000000;
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
/* Disable all interrupts and clear pending bits */
RCC-》CIR = 0x009F0000;
/* Reset CFGR2 register */
RCC-》CFGR2 = 0x00000000;
#else
/* Disable all interrupts and clear pending bits */
RCC-》CIR = 0x009F0000;
#endif /* STM32F10X_CL */
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
#ifdef DATA_IN_ExtSRAM
SystemInit_ExtMemCtl();
#endif /* DATA_IN_ExtSRAM */
#endif
/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
/* Configure the Flash Latency cycles and enable prefetch buffer */
SetSysClock();
#ifdef VECT_TAB_SRAM
SCB-》VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
SCB-》VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif
}
/**
* @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
* @param None
* @retval None
*/
static void SetSysClock(void)
{
#ifdef SYSCLK_FREQ_HSE
SetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHz
SetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHz
SetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHz
SetSysClockTo48();
#elif defined SYSCLK_FREQ_56MHz
SetSysClockTo56();
#elif defined SYSCLK_FREQ_72MHz
SetSysClockTo72();
#endif
/* If none of the define above is enabled, the HSI is used as System clock
source (default after reset) */
}
1)从上面代码逐行往下看,我们知道我们前面的程序 定义的宏定义是 STM32F10X_HD,如下图
2)从而在初始化器确定了系统频率为(72MHz):‘#define SYSCLK_FREQ_72MHz 72000000’初始化智能
的状态为:
系统时钟 72MHz
AHB 72MHz
PCLK1 36MHz
PCLK2 72MHz
锁相环 72MHz
3)SystemInit()函数的第一行代码RCC-》CR|=(uint32_t)0x00000001;我们查手册CR第一位置1,表示开启了8MHz的内部代码,提交的代码阅读如该句,都需要参照手册来理解,在此不再说明。
4)初始化之后可以通过变量SystemCoreClock获取系统变量。如果SYSCLK=72MHz,那么变量SystemCoreClock=72000000。
4、RCC配置库函数
了解了stm32默认给我们配置未来的时钟源,若我们想自定义,则需要借助系统库来进行修改,那么我需要函数库函数stm32f10x_rcc.h里定义的库函数
目录使能配置:
RCC_LSEConfig() 、RCC_HSEConfig()、
RCC_HSICmd() 、 RCC_LSICmd() 、 RCC_PLLCmd() ……
时钟源相关配置:RCC_PLLConfig ()、 RCC_SYSCLKConfig() 、
RCC_RTCCLKConfig() 。..
分频系数选择配置:
RCC_HCLKConfig() 、 RCC_PCLK1Config() 、 RCC_PCLK2Config()。..
外设使能:
RCC_APB1PeriphClockCmd(): //APB1线上外设使能
RCC_APB2PeriphClockCmd(); //APB2线上外设时钟使能
RCC_AHBPeriphClockCmd(); //AHB线上外设使能
其他
外部设备配置:RCC_ADCCLKConfig(); RCC_RTCCLKConfig();
状态参数获取参数:
RCC_GetClocksFreq();
RCC_GetSYSCLKSource();
RCC_GetFlagStatus()
RCC中断相关函数:
RCC_ITConfig() 、 RCC_GetITStatus() 、 RCC_ClearITPendingBit()。..
去学习除去了解该入门学习灯程序衍生出的stm32基础中的基础外,我们还需要有心的概念,本篇记录将stm32的五系统。
1、STM32的概念介绍
幅幅图时stm32的
车载设备1)蓝底框表示有机源,即:
①HSI是高速内部控制器,RC,频率为8MHz
②HS是高速外部设备,可接石英陶瓷器,或者接外部时钟源,频率范围为4MHz时〜16MHz的。
③LSI是低速内部时钟,RC振荡器,频率为40kHz的。(WDG看门狗使用该时钟源)
④LSE是低速外部时钟,接频率为32.768kHz的的石英晶体。(RTC实时
显示器使用该电容源)⑤PLL为锁相环倍频输出,其输入源选择为HSI/2、HSE或HSE/2。倍频性能为2~16倍,但输出频率最大不得7MHz。
其中HSE和LSE是通过外部的外部晶振输入的,一共四个脚管HSE的输入管脚是OSC_IN和OSC_OUT(8M),
LSE的管脚对应的通常为OSC32_IN和OSC32_OUT(32.768kHz2)
梯形表示器,例如:
梯形表示SYSCLK系统来源的形式可以使HSIRCCLKPLL、HSSc(即HSI标签、HSE标签、PLL)
3)绿色方框表示预分频器(prescaler)
4)该图片如何,
比如下图:上图深红色的路线来解释:PLL的源源经过前面的选择器按照实际为8MHz,PLL 9倍频后PLLCLK的频率为72MHz,则选择器SYSCLK(系统时钟)频率为72MHz,经过AHB分频器1分频后HCLK输出频率72MHz,APB1分频器2分频后PCLK1频率为36MHz;经过APB2分频器1分频后PCLK2频率为72MHz 。
5)时钟输出MCO脚(PA8),可以选择PLL输出的2分频,HSI,HSE或者系统时钟。
6)任何一个外设在使用之前,必须首先使能其相应的时钟。
7)需要记住几个重要的
时钟- SYSCLK(系统时钟)
- AHB 总线时钟
- APB1,最高
时钟到(低速)速度 速度 36MHz - APB2 总线时钟(高速),速度最高到 72MHz
- PLL
时钟目录贴一张《STM32中文》手册“中的时钟图,该图和上面的图表示的意思是一致的,我们看看官方是如何展示时钟框图的。
2,(时钟控制)RCC寄存器
typedef struct
{
__IO uint32_t CR; //HSI,HSE,CSS,PLL等的使能和就绪标志位
__IO uint32_t CFGR; //PLL等的时钟源选择,分频系数设定
__IO uint32_t CIR; //清除/使能 时钟就绪中断
__IO uint32_t APB2RSTR; //APB2线上外设复位寄存器
__IO uint32_t APB1RSTR; //APB1线上外设复位寄存器
__IO uint32_t AHBENR; //DMA,SDIO等时钟使能
__IO uint32_t APB2ENR; //APB2线上外设时钟使能
__IO uint32_t APB1ENR; //APB1线上外设时钟使能
__IO uint32_t BDCR; //备份域控制寄存器
__IO uint32_t CSR; //控制状态寄存器
} RCC_TypeDef;
上面是RCC芯片的结构体定义,结构体中的每个变量的哪个位代表什么需要我们参考《STM32中文手册》第6章的6.3小节RCC控制器描述来了解,现仅对一个变量CR贴出参考手册的描述,其他的资料了,参考手册目录。
3、系统
初始化对界面控制器的概念性的介绍,在写程序时我们一般不直接操作 RCC_TypeDef结构体,而是调用相应的库函数来编程。
在此我们先看一下库函数中系统默认如何初始化这些寄存器的,我们先看一段汇编程序,我们知道ç中默认的程序入口是主函数,那主函数的如何调用的呢,我们先来看看以下程序(该程序在startup_stm32f10x_hd.s中可以找到):
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT SystemInit
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
从上面的程序中可以实现在main函数调用前,调用了SystemInit函数,该函数的定义可以在system_stm32f10x.c中找到,源码如下:
#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
/* #define SYSCLK_FREQ_HSE HSE_VALUE */
#define SYSCLK_FREQ_24MHz 24000000
#else
/* #define SYSCLK_FREQ_HSE HSE_VALUE */
/* #define SYSCLK_FREQ_24MHz 24000000 */
/* #define SYSCLK_FREQ_36MHz 36000000 */
/* #define SYSCLK_FREQ_48MHz 48000000 */
/* #define SYSCLK_FREQ_56MHz 56000000 */
#define SYSCLK_FREQ_72MHz 72000000
#endif
/*!《 Uncomment the following line if you need to use external SRAM mounted
on STM3210E-EVAL board (STM32 High density and XL-density devices) or on
STM32100E-EVAL board (STM32 High-density value line devices) as data memory */
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
/* #define DATA_IN_ExtSRAM */
#endif
/*******************************************************************************
* Clock Definitions
*******************************************************************************/
#ifdef SYSCLK_FREQ_HSE
uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /*!《 System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_24MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_24MHz; /*!《 System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_36MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_36MHz; /*!《 System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_48MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz; /*!《 System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_56MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz; /*!《 System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_72MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz; /*!《 System Clock Frequency (Core Clock) */
#else /*!《 HSI Selected as System Clock source */
uint32_t SystemCoreClock = HSI_VALUE; /*!《 System Clock Frequency (Core Clock) */
#endif
__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
static void SetSysClock(void);
/**
* @brief Setup the microcontroller system
* Initialize the Embedded Flash Interface, the PLL and update the
* SystemCoreClock variable.
* @note This function should be used only after reset.
* @param None
* @retval None
*/
void SystemInit (void)
{
/* Reset the RCC clock configuration to the default reset state(for debug purpose) */
/* Set HSION bit */
RCC-》CR |= (uint32_t)0x00000001;
/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CL
RCC-》CFGR &= (uint32_t)0xF8FF0000;
#else
RCC-》CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F10X_CL */
/* Reset HSEON, CSSON and PLLON bits */
RCC-》CR &= (uint32_t)0xFEF6FFFF;
/* Reset HSEBYP bit */
RCC-》CR &= (uint32_t)0xFFFBFFFF;
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
RCC-》CFGR &= (uint32_t)0xFF80FFFF;
#ifdef STM32F10X_CL
/* Reset PLL2ON and PLL3ON bits */
RCC-》CR &= (uint32_t)0xEBFFFFFF;
/* Disable all interrupts and clear pending bits */
RCC-》CIR = 0x00FF0000;
/* Reset CFGR2 register */
RCC-》CFGR2 = 0x00000000;
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
/* Disable all interrupts and clear pending bits */
RCC-》CIR = 0x009F0000;
/* Reset CFGR2 register */
RCC-》CFGR2 = 0x00000000;
#else
/* Disable all interrupts and clear pending bits */
RCC-》CIR = 0x009F0000;
#endif /* STM32F10X_CL */
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
#ifdef DATA_IN_ExtSRAM
SystemInit_ExtMemCtl();
#endif /* DATA_IN_ExtSRAM */
#endif
/* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
/* Configure the Flash Latency cycles and enable prefetch buffer */
SetSysClock();
#ifdef VECT_TAB_SRAM
SCB-》VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
SCB-》VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif
}
/**
* @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
* @param None
* @retval None
*/
static void SetSysClock(void)
{
#ifdef SYSCLK_FREQ_HSE
SetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHz
SetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHz
SetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHz
SetSysClockTo48();
#elif defined SYSCLK_FREQ_56MHz
SetSysClockTo56();
#elif defined SYSCLK_FREQ_72MHz
SetSysClockTo72();
#endif
/* If none of the define above is enabled, the HSI is used as System clock
source (default after reset) */
}
1)从上面代码逐行往下看,我们知道我们前面的程序 定义的宏定义是 STM32F10X_HD,如下图
2)从而在初始化器确定了系统频率为(72MHz):‘#define SYSCLK_FREQ_72MHz 72000000’初始化智能
的状态为:
系统时钟 72MHz
AHB 72MHz
PCLK1 36MHz
PCLK2 72MHz
锁相环 72MHz
3)SystemInit()函数的第一行代码RCC-》CR|=(uint32_t)0x00000001;我们查手册CR第一位置1,表示开启了8MHz的内部代码,提交的代码阅读如该句,都需要参照手册来理解,在此不再说明。
4)初始化之后可以通过变量SystemCoreClock获取系统变量。如果SYSCLK=72MHz,那么变量SystemCoreClock=72000000。
4、RCC配置库函数
了解了stm32默认给我们配置未来的时钟源,若我们想自定义,则需要借助系统库来进行修改,那么我需要函数库函数stm32f10x_rcc.h里定义的库函数
目录使能配置:
RCC_LSEConfig() 、RCC_HSEConfig()、
RCC_HSICmd() 、 RCC_LSICmd() 、 RCC_PLLCmd() ……
时钟源相关配置:RCC_PLLConfig ()、 RCC_SYSCLKConfig() 、
RCC_RTCCLKConfig() 。..
分频系数选择配置:
RCC_HCLKConfig() 、 RCC_PCLK1Config() 、 RCC_PCLK2Config()。..
外设使能:
RCC_APB1PeriphClockCmd(): //APB1线上外设使能
RCC_APB2PeriphClockCmd(); //APB2线上外设时钟使能
RCC_AHBPeriphClockCmd(); //AHB线上外设使能
其他
外部设备配置:RCC_ADCCLKConfig(); RCC_RTCCLKConfig();
状态参数获取参数:
RCC_GetClocksFreq();
RCC_GetSYSCLKSource();
RCC_GetFlagStatus()
RCC中断相关函数:
RCC_ITConfig() 、 RCC_GetITStatus() 、 RCC_ClearITPendingBit()。..
举报