正点原子STM32F103学习笔记(六)——时钟系统
生活随笔
收集整理的這篇文章主要介紹了
正点原子STM32F103学习笔记(六)——时钟系统
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
時鐘系統
RCC: reset clock control 復位和時鐘控制器。
注意: 任何一個外設在使用之前,必須首先使能其相應的時鐘
時鐘系統框圖
圖形含義
- 梯形灰色方塊:選擇器
- 藍色框:時鐘源
時鐘源(5個)
HSI: 高速的內部時鐘。
- 產生:內置RC振蕩器
- 頻率:8MHz左右(內置RC振蕩器不穩定)精度不高
- 可作為系統時鐘時鐘源
HSE: 高速的外部時鐘。
- 產生:外部晶振(石英/陶瓷諧振器或者外部時鐘)
- 頻率:4-16MHz
- 可以直接或二分頻后做相鄰選擇器(選擇器1)輸入,再經過選擇器2后輸入PLL
- 可作為系統時鐘時鐘源
PLL: 鎖相環倍頻輸出
- 來源:HSI的兩分頻,HSE,HSE的兩分頻
- 作用:倍頻器(可選擇關閉或倍頻×2,?,×16\times 2, \cdots ,\times 16×2,?,×16共16種選擇,可以通過相關寄存器配置)
- 倍頻后產生PLLCLK時鐘
- 常將PLLCLK作為系統時鐘的來源
LSE: 低速外部時鐘
- 產生:外部石英晶振
- 頻率:32.768HZ
- 給RTCCLK供電
LSI: 低速內部時鐘
- 產生:內置RC振蕩器
- 頻率:大約40kHz
- 提供低功耗時鐘,可以給IWDGCLK(獨立看門狗)提供時鐘
時鐘(前五個重要)
1. SYSCLK 系統時鐘:
- 來源:HSI,HSE,PLLCLK
- 經過AHB預分頻器(1,2,4,8,16,64,128,256,512 九種)可得到HCLK(最高72MHz,通常通過SYSCLK設為72MHz,AHB設為1得到)
- 其余預分頻線路見圖
2. AHB總線時鐘
3. APB1總線時鐘(低速): 速度最高36MHz
4. APB2總線時鐘(高速): 速度最高72MHz
5. PLL時鐘
6. RTCCLK 實時時鐘
- 來源:HSE的128分頻,LSE,LSI
7. USBCLK USB時鐘
- 來源:PLLCLK經過USB分頻器(預分頻分頻因子有÷1,÷1.5\div 1,\div 1.5÷1,÷1.5兩種選擇)
其他
MCO 輸出時鐘引腳PA8
來源:YSYCLK,HSI,HSE,PLLCLK二分頻
CSS: 時鐘監控系統
- HSE失敗后自動將系統時鐘源切換到HSI
代碼
配置函數在stm32f10x_rcc.h頭文件中
寄存器描述在stm32f10x.h頭文件中
寄存器
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;庫函數
SystemInit時鐘系統初始化函數剖析
函數位置:system_stm32f10x.c中 system_stm32f10x.h
//Reset 即為設置為0 void SystemInit (void) {RCC->CR |= (uint32_t)0x00000001; //Set HSION bit 打開HSION(第一位)/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */ #ifndef STM32F10X_CL //大容量芯片不執行RCC->CFGR &= (uint32_t)0xF8FF0000; #elseRCC->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_ExtSRAMSystemInit_ExtMemCtl(); #endif /* DATA_IN_ExtSRAM */ #endif SetSysClock();#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 }SysTick定時器(滴答定時器/系統定時器)
什么是SysTick
- Systick定時器,是一個簡單的定時器,對于CM3,CM4內核芯片,都有Systick定時器。
- Systick定時器常用來做延時,或者實時系統的心跳時鐘。這樣可以節省MCU資源,不用浪費一個定時器。比如UCOS中,分時復用,需要一個最小的時間戳,一般在STM32+UCOS系統中,都采用Systick做UCOS心跳時鐘。
- Systick定時器就是系統滴答定時器,一個24 位的倒計數定時器,計到0 時,將從RELOAD 寄存器中自動重裝載定時初值。只要不把它在SysTick 控制及狀態寄存器中的使能位清除(不關閉),就永不停息,即使在睡眠模式下也能工作。
- SysTick定時器被捆綁在NVIC中,用于產生SYSTICK異常(異常號:15)。(即可以產生中斷)
- Systick中斷的優先級也可以設置。
Systick相關寄存器
CTRL:SysTick 控制和狀態寄存器
TICKINT:是否產生中斷
COUNTFLAG:避免誤讀
對于STM32,外部時鐘源是 HCLK(AHB總線時鐘)的1/8;內核時鐘是 HCLK時鐘
LOAD:SysTick 自動重裝載除值寄存器
VAL :SysTick 當前值寄存器
CALIB:SysTick 校準值寄存器
配置函數:
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource) //Systick時鐘源選擇 misc.c文件中 //配置CTRL寄存器 //入口參數 //SysTick_CLKSource_HCLK_Div8(外部時鐘源) SysTick的定時器為72/8=9MHZ //或SysTick_CLKSource_HCLK(內部時鐘) SysTick的定時器為72MHZ static __INLINE uint32_t SysTick_Config(uint32_t ticks) //初始化systick,時鐘為HCLK,并開啟中斷 //core_cm3.h/core_cm4.h文件中 //作用:開啟SysTick中斷,并配置ticks(兩個中斷中間有多少個周期) void SysTick_Handler(void); //Systick中斷服務函數:用中斷的方式實現delay延時
思路
static __IO uint32_t TimingDelay; void Delay(__IO uint32_t nTime) { TimingDelay = nTime;while(TimingDelay != 0); //TimingDelay自動減,減到0退出while }void SysTick_Handler(void) //每到1ms中斷時運行此函數 {if (TimingDelay != 0x00) //不等于0減一{ TimingDelay--;} }int main(void){ //…if (SysTick_Config(SystemCoreClock / 1000)) //systick時鐘為HCLK,中斷時間間隔1ms 72000000Hz/1000=72000//即每兩次中斷中有72000次間隔,運行72000次1/72000000秒=1ms{while (1); //SysTick_Config()有返回值,配置成功返回0跳過死循環}while(1){ Delay(200);//2ms// … } }void delay_init()
void delay_init() { #if SYSTEM_SUPPORT_OS //如果需要支持OS.u32 reload; #endifSysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //選擇外部時鐘 HCLK/8 9MHzfac_us=SystemCoreClock/8000000; //微秒因子 //為系統時鐘的1/8,一微秒為9個時鐘周期 #if SYSTEM_SUPPORT_OS //如果需要支持OS.reload=SystemCoreClock/8000000; //每秒鐘的計數次數 單位為K reload*=1000000/delay_ostickspersec; //根據delay_ostickspersec設定溢出時間//reload為24位寄存器,最大值:16777216,在72M下,約合1.86s左右 fac_ms=1000/delay_ostickspersec; //代表OS可以延時的最少單位 SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; //開啟SYSTICK中斷SysTick->LOAD=reload; //每1/delay_ostickspersec秒中斷一次 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //開啟SYSTICK #elsefac_ms=(u16)fac_us*1000; //非OS下,代表每個ms需要的systick時鐘數 #endif }void delay_us(u32 nus)
#else //不用OS時 //延時nus //nus為要延時的us數. void delay_us(u32 nus) { u32 temp; SysTick->LOAD=nus*fac_us; //時間加載,將兩次中斷中的周期數給LOAD重裝載值 SysTick->VAL=0x00; //清空計數器,清零后使能定時器會重新加載 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //開始倒數,即使能 do{temp=SysTick->CTRL;}while((temp&0x01)&&!(temp&(1<<16))); //等待時間到達 SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //關閉計數器SysTick->VAL =0X00; //清空計數器 } //延時nms //注意nms的范圍 //SysTick->LOAD為24位寄存器,所以,最大延時為: //nms<=0xffffff*8*1000/SYSCLK //SYSCLK單位為Hz,nms單位為ms //對72M條件下,nms<=1864總結
以上是生活随笔為你收集整理的正点原子STM32F103学习笔记(六)——时钟系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 抽象类的意义_python
- 下一篇: 重构业务系统,我是这样做的