完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
1 时钟系统结构图
2 STM32时钟系统(一) 2.1 各个时钟源 ① STM32有5个时钟源:HSI、HSE、 LSI、 LSE、 PLL HSI是高速内部时钟,RC振荡器,频率为8MHz,精度不高 HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz ~ 16MHz LSI是低速内部时钟,RC振荡器,频率为40kHz,提供低功耗时钟 LSE是低速外部时钟,接频率为32.768kHz的石英晶体 PLL为锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE/2,倍频可选择为2~16倍,但是其输出频率最大不得超过72MHz ② 系统时钟SYSCLK可来源于三个时钟源: HSI振荡器时钟 HSE振荡器时钟 PLL时钟 ④ 举例: Keil编写程序是默认的时钟为72Mhz: 外部晶振(HSE)提供的8MHz,通过PLLXTPRE分频器 进入PLLSRC选择开关,通过PLLMUL锁相环进行倍频(x9),为系统提供72MHz的系统时钟(SYSCLK) AHB预分频器对时钟信号进行分频,为低速外设提供时钟 ③ 注意: 独立时钟源为4个,因为PLL本身不能提供时钟 LSI一般作为IWDGCLK(独立看门狗)时钟源和RTC时钟源 系统时钟最大频率为72MHz 2.2 时钟信号输出到外部 STM32可以选择一个时钟信号输出到MCO脚(PA8)上,可以选择为PLL输出的2分频、HSI、HSE、或者系统时钟。可以把时钟信号输出供外部使用 2.3 AHB分频器 系统时钟通过AHB分频器给外设提供时钟,系统时钟 -》 AHB分频器 -》 各个外设分频倍频器 -》 外设时钟的设置 AHB分频器可选择1、2、4、8、16、64、128、256、512分频,输出的时钟输送给5大模块使用: 内核总线:输送给AHB总线、内核、内存和DMA使用的HCLK时钟 Tick定时器:通过8分频后送给Cortex的系统定时器时钟 I2S总线:直接送给Cortex的空闲运行时钟FCLK APB1外设:送给APB1分频器。APB1分频器可选择1、2、4、8、16分频,其输出一路供APB1外设使用(PCLK1,最大频率36MHz),另一路送给通用定时器使用。该倍频器可选择1或者2倍频,时钟输出供定时器2-7使用 APB2外设:送给APB2分频器。APB2分频器可选择1、2、4、8、16分频,其输出一路供APB2外设使用(PCLK2,最大频率72MHz),另一路送给高级定时器。该倍频器可选择1或者2倍频,时钟输出供定时器1和定时器8使用 2.4 APB1和APB2的对应外设 APB1上面连接的是低速外设,包括电源接口、备份接口、CAN、USB、I2C1、I2C2、USART2、USART3、UART4、UART5、SPI2、SP3等 而APB2上面连接的是高速外设,包括UART1、SPI1、Timer1、ADC1、ADC2、ADC3、所有的普通I/O口(PA-PE)、第二功能I/O(AFIO)口等 3 STM32时钟系统(二) 3.1 时钟安全系统(CSS) 如果HSE时钟发生故障,HSE振荡器被自动关闭,时钟失效事件将被送到高级定时器(TIM1和TIM8)的刹车输入端,并产生时钟安全中断CSSI,允许软件完成营救操作。此CSSI中断连接到Cortex™-M3的NMI中断(不可屏蔽中断) 一旦CSS被激活,并且HSE时钟出现故障,CSS中断就产生,并且NMI也自动产生。NMI将被不断执行,直到CSS 中断挂起位被清除。因此,在NMI的处 理程序中必须通过设置时钟中断寄存器(RCC_ CIR) 里的CSSC位来清除CSS中断 如果HSE振荡器被直接或间接地作为系统时钟,(间接的意思是:它被作为PLL输入时钟或通过PLL2,并且PLL时钟被作为系统时钟),时钟故障将导致系统时钟自动切换到HSI振荡器,同时外部HSE振荡器被关闭。在时钟失效时,如果HSE振荡器时钟(直接的或通过PLL2)是作为PLL的输入时钟,PLL也将被关闭 3.2 RTC时钟 通过设置 备份域控制寄存器(RCC_BDCR)里的RTCSEL[1:0]位,RTCCLK时钟源可以由HSE/128、LSE或LSI时钟提供 3.3 看门狗时钟 如果独立看门狗已经由硬件选项或软件启动,LSI振荡器将被强制在打开状态,并且不能被关闭。在LSI振荡器稳定后,时钟供应给IWDG 3.4 USB时钟 STM32中有一个全速功能的USB模块,其串行接口引擎需要一个频率为48MHz的时钟源。该时钟源只能从PLL输出端获取(唯一的),可以选择为1.5分频或者1分频,也就是,当需要使用USB模块时,PLL必须使能,并且时钟频率配置为48MHz或72MHz 4 RCC寄存器 4.1 时钟控制寄存器(RCC_CR) 4.2 时钟配置寄存器(RCC_CFGR) 4.3 时钟中断寄存器(RCC_CIR) 4.4 APB2外设复位寄存器(RCC_APB2RSTR) 4.5 APB1外设复位寄存器(RCC_APB1RSTR) 4.6 AHB外设时钟使能寄存器(RCC_AHBENR) 4.7 APB2外设时钟使能寄存器(RCC_APB2ENR) 4.8 APB1外设时钟使能寄存器(RCC_APB1ENR) 4.9 备份域控制寄存器(RCC_BDCR) 4.10 控制/状态寄存器(RCC_CSR) 4.11 AHB外设时钟复位寄存器(RCC_AHBRSTR) 4.12 时钟配置寄存器2(RCC_CFGR2) 4.13 RCC寄存器地址映像 5 时钟系统初始化C语言代码实现 步骤: 定义一个RCC结构体指针,按照RCC_TypeDef类型指向RCC的基地址;STM32访问寄存器的方式是通过基地址加偏移地址来实现的 /* C语言书籍这样定义volatile关键字:volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或 读取这个变量的时候,告诉编译器对该变量不做优化,都会直接从变量内存地址中读取数据,从而可以提供对特殊地址的稳定访 问。。如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的 话,将出现不一致的现象。(简洁的说就是:volatile关键词影响编译器编译的结果,用volatile声明的变量表示该变量随时可能发 生变化,与该变量有关的运算,不要进行编译优化,以免出错) */ #define __IO volatile /*!《 defines ‘read / write’ permissions */ typedef unsigned int uint32_t; //所有外设基地址 #define PERIPH_BASE ((uint32_t)0x40000000) /*!《 Peripheral base address in the alias region */ //AHB总线基地址 #define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) //RCC寄存器基地址 #define RCC_BASE (AHBPERIPH_BASE + 0x1000) //使用这个结构体,不用再给每一个寄存器初始化其物理地址 //只需要知道RCC寄存器地址即可,利用了结构体对齐的优点 //即指针只要指过来,就可以访问到该寄存器实际地址了 //参考本文的 4.13 -》 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; #define RCC ((RCC_TypeDef *) RCC_BASE) 定义一个函数来复位初始化所有时钟寄存器、配置向量表 //不能在这里执行所有外设复位!否则至少引起串口不工作。 //把所有时钟寄存器复位 void MYRCC_DeInit(void) { RCC-》APB1RSTR = 0x00000000;//复位 RCC-》APB2RSTR = 0x00000000;//复位 RCC-》AHBENR = 0x00000014; //睡眠模式闪存和SRAM时钟使能。其他关闭。 RCC-》APB2ENR = 0x00000000; //外设时钟关闭。 RCC-》APB1ENR = 0x00000000; RCC-》CR |= 0x00000001; //使能内部高速时钟HSION,系统默认 RCC-》CFGR &= 0xF8FF0000; //复位SW[1:0],HPRE[3:0],PPRE1[2:0],PPRE2[2:0],ADCPRE[1:0],MCO[2:0] RCC-》CR &= 0xFEF6FFFF; //复位HSEON,CSSON,PLLON RCC-》CR &= 0xFFFBFFFF; //复位HSEBYP RCC-》CFGR &= 0xFF80FFFF; //复位PLLSRC, PLLXTPRE, PLLMUL[3:0] and USBPRE RCC-》CIR = 0x00000000; //关闭所有中断 //配置向量表 #ifdef VECT_TAB_RAM MY_NVIC_SetVectorTable(0x20000000, 0x0); #else MY_NVIC_SetVectorTable(0x08000000,0x0); #endif } 定义一个可供调用的系统时钟初始化函数 //系统时钟初始化函数 //pll:选择的倍频数,从2开始,最大值为16 void Stm32_Clock_Init(u8 PLL) { unsigned char temp=0; MYRCC_DeInit(); //复位并配置向量表 RCC-》CR|=0x00010000; //外部高速时钟使能HSEON while(!(RCC-》CR》》17));//等待外部时钟就绪(位17 值1:外部4-16MHz振荡器就绪) RCC-》CFGR=0X00000400; //APB1=DIV2;APB2=DIV1;AHB=DIV1; PLL-=2; //抵消2个单位(因为是从2开始的,设置0就是2) RCC-》CFGR|=PLL《《18; //设置PLL值 2~16 RCC-》CFGR|=1《《16; //PLLSRC ON FLASH-》ACR|=0x32; //FLASH 2个延时周期 RCC-》CR|=0x01000000; //PLLON while(!(RCC-》CR》》25));//等待PLL锁定 RCC-》CFGR|=0x00000002;//PLL作为系统时钟 while(temp!=0x02) //等待PLL作为系统时钟设置成功 { temp=RCC-》CFGR》》2; temp&=0x03; } } 在main函数调用,设置系统时钟为72MHz #include “sys.h” #include “usart.h” #include “delay.h” #include “led.h” int main(void) { Stm32_Clock_Init(9); //系统时钟设置 delay_init(72); //延时初始化 LED_Init(); //初始化与LED连接的硬件接口 while(1) { LED0=0; LED1=1; delay_ms(300); LED0=1; LED1=0; delay_ms(300); } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1907 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1678 浏览 1 评论
1171 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
770 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1730 浏览 2 评论
1970浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
805浏览 4评论
stm32f4下spi+dma读取数据不对是什么原因导致的?
253浏览 3评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
623浏览 3评论
634浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-22 23:03 , Processed in 0.838326 second(s), Total 77, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号