完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
去学习除去了解该入门学习灯程序衍生出的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倍,但输出频率最大不得超过72MHz的。 其中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_Handler [WEAK] Reset IMPORT __main IMPORT SystemInit LDR R0, =SystemInit BLX R0 LDR R0, =__main BX R0 ENDP 从上面的程序中可以在main函数调用前,调用了SystemInit函数,该函数的定义可以在system_stm32f10x.c中找到,源码如下: #if 定义 (STM32F10X_LD_VL) || (定义STM32F10X_MD_VL) || (定义STM32F10X_HD_VL)/ *#定义SYSCLK_FREQ_HSE HSE_VALUE * /#定义SYSCLK_FREQ_24MHz 24000000的#else / *#定义SYSCLK_FREQ_HSE HSE_VALUE * / / *#定义SYSCLK_FREQ_24MHz 24000000 * / / *#定义SYSCLK_FREQ_36MHz 36000000 * / / *#定义SYSCLK_FREQ_48MHz 48000000 * / /* #define SYSCLK_FREQ_56MHz 56000000 */ #define SYSCLK_FREQ_72MHz 72000000 #endif /*!《 如果您需要使用安装在 STM3210E-EVAL 板(STM32 高密度和 XL 密度器件)或 STM32100E-EVAL 板(STM32 高密度值线器件)上的外部 SRAM 作为数据存储器,请取消注释以下行 */ #if 定义(STM32F10X_HD) || (定义 STM32F10X_XL) || (定义STM32F10X_HD_VL) /* #define DATA_IN_ExtSRAM */ #endif /**************************************** ******************************************** * 时钟定义 **** ****************************************************** *************************/ #ifdef SYSCLK_FREQ_HSE uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /*!《 System Clock Frequency (Core Clock) */ #elif定义了SYSCLK_FREQ_24MHz uint32_t SystemCoreClock = SYSCLK_FREQ_24MHz; /*!《 System Clock Frequency (Core Clock) */ #elif 定义 SYSCLK_FREQ_36MHz uint32_t SystemCoreClock = SYSCLK_FREQ_36MHz; /*!《 System Clock Frequency (Core Clock) */ #elif 定义 SYSCLK_FREQ_48MHz uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz; /*!《 System Clock Frequency (Core Clock) */ #elif 定义 SYSCLK_FREQ_56MHz uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz; /*!《 System Clock Frequency (Core Clock) */ #elif 定义 SYSCLK_FREQ_72MHz uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz; /*!《 System Clock Frequency (Core Clock) */ #else /*!《 HSI 被选为系统时钟源 */ uint32_t SystemCoreClock = HSI_VALUE; /*!《 系统时钟频率(内核时钟)*/ #endif __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7 , 8, 9}; 静态无效SetSysClock(无效);/** * @brief 设置微控制器系统 * 初始化嵌入式闪存接口、PLL 并更新 * SystemCoreClock 变量。* @note 此功能只能在重置后使用。* @param None * @retval None */ void SystemInit (void) { /* 将 RCC 时钟配置重置为默认重置状态(用于调试目的)*/ /* 设置 HSION 位 */ RCC-》CR |= (uint32_t )0x00000001; /* 复位 SW、HPRE、PPRE1、PPRE2、ADCPRE 和 MCO 位 */ #ifndef STM32F10X_CL RCC-》CFGR &= (uint32_t)0xF8FF0000; #else RCC-》CFGR &= (uint32_t)0xF0FF0000; #endif /* STM32F10X_CL */ /* 重置 HSEON、CSSON 和 PLLON 位 */ RCC-》CR &= (uint32_t)0xFEF6FFFF; /* 重置 HSEBYP 位 */ RCC-》CR &= (uint32_t)0xFFFBFFFF; /* 复位 PLLSRC, PLLXTPRE, PLLMUL 和 USBPRE/OTGFSPRE 位 */ RCC-》CFGR &= (uint32_t)0xFF80FFFF; #ifdef STM32F10X_CL /* 复位 PLL2ON 和 PLL3ON 位 */ RCC-》CR &= (uint32_t)0xEBFFFFFF; /* 禁用所有中断并清除挂起位 */ RCC-》CIR = 0x00FF0000; /* 重置 CFGR2 寄存器 */ RCC-》CFGR2 = 0x00000000; #elif 定义 (STM32F10X_LD_VL) || 定义 (STM32F10X_MD_VL) || (定义STM32F10X_HD_VL) /* 禁止所有中断并清除挂起位*/ RCC-》CIR = 0x009F0000; /* 重置 CFGR2 寄存器 */ RCC-》CFGR2 = 0x00000000; #else /* 禁用所有中断并清除挂起位 */ RCC-》CIR = 0x009F0000; #endif /* STM32F10X_CL */ #if 定义 (STM32F10X_HD) || (定义STM32F10X_XL) || (定义STM32F10X_HD_VL)#ifdef DATA_IN_ExtSRAM SystemInit_ExtMemCtl(); #endif /* DATA_IN_ExtSRAM */ #endif /* 配置系统时钟频率、HCLK、PCLK2 和 PCLK1 预分频器 */ /* 配置闪存延迟周期并启用预取缓冲区 */ SetSysClock(); #ifdef VECT_TAB_SRAM SCB-》VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* 内部 SRAM 中的向量表重定位。*/ #else SCB-》VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* 内部闪存中的向量表重定位。*/ #endif } /** * @brief 配置系统时钟频率、HCLK、PCLK2 和 PCLK1 预分频器。* @param None * @retval None */ static void SetSysClock(void) { #ifdef SYSCLK_FREQ_HSE SetSysClockToHSE(); #elif 定义了 SYSCLK_FREQ_24MHz SetSysClockTo24(); #elif 定义了 SYSCLK_FREQ_36MHz SetSysClockTo36(); #elif 定义了 SYSCLK_FREQ_48MHz SetSysClockTo48(); #elif 定义了 SYSCLK_FREQ_56MHz SetSysClockTo56(); #elif 定义了 SYSCLK_FREQ_72MHz SetSysClockTo72(); #endif /* 如果以上定义都没有启用,HSI 用作系统时钟源(复位后默认)*/ } 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()。。. |
|
|
|
只有小组成员才能发言,加入小组>>
2549 浏览 0 评论
1148浏览 2评论
747浏览 1评论
500浏览 0评论
266浏览 0评论
429浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 21:28 , Processed in 1.106202 second(s), Total 48, Slave 39 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号