STM32學習筆記-系統時鍾初始化函數詳解


STM32學習筆記-系統時鍾初始化函數詳解

1. STM32F10xx時鍾系統框圖及說明

image

1. STM32有5個時鍾源:HSI、HSE、LSI、LSE、PLL。

  • HSI是高速內部時鍾,RC振盪器,頻率為8MHz,精度不高
  • HSE是高速外部時鍾,可接石英/陶瓷諧振器,或者接外部時鍾源,頻率范圍為4MHz~16MHz
  • LSI是低速內部時鍾,RC振盪器,頻率為40kHz,提供低功耗時鍾,WDG
  • LSE是低速外部時鍾,接頻率為32.768kHz的石英晶體,RTC
  • PLL為鎖相環倍頻輸出,其時鍾輸入源可以選為HSI/2,HSE或HSE/2。倍頻可選擇2~16倍,但是其輸出頻率最大不能超過72MHz

2. 系統時鍾SYSCLK可源於三個時鍾源

  • HSI振盪器時鍾
  • HSE振盪器時鍾
  • PLL時鍾

2. 系統初始化函數

//系統時鍾初始化函數
//pll:選擇的倍頻數,從2開始,最大值為16		 
void Stm32_Clock_Init(u8 PLL)
{
	unsigned char temp=0;   
	MYRCC_DeInit();		  //復位並配置向量表
 	RCC->CR|=0x00010000;  //外部高速時鍾使能HSEON
	while(!(RCC->CR>>17));//等待外部時鍾就緒
	RCC->CFGR=0X00000400; //APB1=DIV2;APB2=DIV1;AHB=DIV1;
	PLL-=2;				  //抵消2個單位(因為是從2開始的,設置0就是2)
	RCC->CFGR|=PLL<<18;   //設置PLL值 2~16
    
    //PLLSRC:PLL輸入時鍾源
	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;
	}    
}		    

//不能在這里執行所有外設復位!否則至少引起串口不工作.		    
//把所有時鍾寄存器復位		  
void MYRCC_DeInit(void)
{	
    
    //APB1RSTR和APB2RSTR是APB1和APB2外設復位寄存器,對應掛在兩條總線上的各種外設,全部置為無作用
 	RCC->APB1RSTR = 0x00000000;//復位結束			 
	RCC->APB2RSTR = 0x00000000; 
    
	//AHBENR、AHB2ENR、AHB1ENR是外設時鍾使能寄存器,使能哪個外設需要將對應的位進行操作
    //睡眠模式閃存和SRAM不使能就不能使用flash和SRAM
  	RCC->AHBENR = 0x00000014;  //睡眠模式閃存和SRAM時鍾使能.其他關閉.	  
  	RCC->APB2ENR = 0x00000000; //外設時鍾關閉.			   
  	RCC->APB1ENR = 0x00000000; 
    //CR為時鍾控制寄存器
    //將HSI使能作為系統時鍾
	RCC->CR |= 0x00000001;     //使能內部高速時鍾HSI ON	 														//CFGR為時鍾控制寄存器
    //SW:系統時鍾切換  此處設為00: HSI作為系統時鍾;
    //HPRE:AHB預分頻   此處設為0000:表示不分頻
    //PPRE1:低速APB預分頻(APB1)  此處設為000表示HCLK不分頻
    //PPRE2:高速APB預分頻(APB2)  此處設為000表示HCLK不分頻
    //ADCPRE:ADC預分頻 		 此處設為00: PCLK2 2分頻后作為ADC時鍾
    //MCO:微控制器時鍾輸出		  此處設為000表示沒有時鍾輸出
	RCC->CFGR &= 0xF8FF0000;   //復位SW[1:0],HPRE[3:0],PPRE1[2:0],PPRE2[2:0],ADCPRE[1:0],MCO[2:0]				//HSEON:外部高速時鍾使能	HSE振盪器關閉
    //CSSON:時鍾安全系統使能	時鍾監測器關閉;
    //PLLON:PLL使能			PLL關閉
	RCC->CR &= 0xFEF6FFFF;     //復位HSEON,CSSON,PLLON
    //HSEBYP:外部高速時鍾旁路	外部4-16MHz振盪器沒有旁路
	RCC->CR &= 0xFFFBFFFF;     //復位HSEBYP	   	  
    //PLLSRC:PLL輸入時鍾源 		0: HSI振盪器時鍾經2分頻后作為PLL輸入時鍾
    //PLLXTPRE:HSE分頻器作為PLL輸入	0: HSE不分頻
    //PLLMUL:PLL倍頻系數			0000: PLL 2倍頻輸出
    //USBPRE:USB預分頻				0: PLL時鍾1.5倍分頻作為USB時鍾
	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
}

3. SysTick 定時器與延時函數

1. SysTick定時器

4個寄存器控制SysTick定時器:

2. 延時函數

void delay_init()
{
#if SYSTEM_SUPPORT_OS  							//如果需要支持OS.
	u32 reload;
#endif
    
 	//系統時鍾為72M,1/8為9M,既每秒鍾震動9000000次,1s=1000ms=1000000us =》 1us震動9次
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);	//選擇外部時鍾  HCLK/8
	fac_us=SystemCoreClock/8000000;				//為系統時鍾的1/8  
#if SYSTEM_SUPPORT_OS  							//如果需要支持OS.
	reload=SystemCoreClock/8000000;				//每秒鍾的計數次數 單位為M  
	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    

#else
	fac_ms=(u16)fac_us*1000;					//非OS下,代表每個ms需要的systick時鍾數   
#endif
}								    


//延時nus
//nus為要延時的us數.		    								   
void delay_us(u32 nus)
{		
	u32 temp;	    	 
	SysTick->LOAD=nus*fac_us; 					//時間加載	  		 
	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 
void delay_ms(u16 nms)
{	 		  	  
	u32 temp;		   
	SysTick->LOAD=(u32)nms*fac_ms;				//時間加載(SysTick->LOAD為24bit)
	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;       					//清空計數器	  	    
} 
#endif 



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM