【STM32】F103學習筆記:SysTick

SysTick簡介、功能框圖講解、SysTick定時實驗講解  
	SysTick:系統滴答定時器,24位,只能遞減,存在於內核中,嵌套在NVIC中,所有的Cortex-M內核的單片機都具有這個定時器。
			(內核中的外設)
			
	功能框圖:STK_CLK(72M/9M)  -》STK_VAL遞減計數器  
									^
									|
								STK_LOAD重裝載寄存器
	
			 遞減計數器counter在時鐘的驅動下,從reload初值開始往下遞減計數到0,
			產生中斷和置位COUNTFLAG標誌瞭然後又從reload值開始重新遞減,如此循環。

	SysTick中的幾個寄存器:
		SysTick控制及狀態寄存器CTRL:
		位段	名稱			類型	復位值	描述
		16		COUNTFLAG		R/W		0		如果上次讀取本寄存器後,SysTick已經到了0,則該位位1
		2       CLKSOURCE 		R/W		0		時鐘源選擇位,0=AHB/8,1=處理器時鐘AHB72M
		(就是說,SysTick的CTRL寄存器中的第16位,如果爲1,說明上次讀取數值後Systick有到了0了,完成一次tick滴答了)
		
		SysTick重裝載數值寄存器LOAD:
		位段	名稱			類型	復位值	描述
		23:0	RELOAD			R/W		0		當倒數計數至0,將被重新裝載賦值

		SysTick當前數值寄存器VAL:
		位段	名稱			類型	復位值	描述
		23:0	CURRENT			R/W		0		讀取時返回當前倒計數的值,寫它則是指清零

	Systick定時時間計算:
		1-t:一個計數循環時間,跟reload和CLK有關
		2-CLK:72M或者9M,由CTRL寄存器配置
		3-RELOAD:24位,用戶自己配置
			t=reload*(1/clk)
			clk=72M 時,t=72 * (1/72M) = 1us  微妙
			clk=72M 時,t=7200 * (1/72M) = 1ms 毫秒
			
			1s = 10^3ms = 10^6us = 10^9ns

	SysTick屬於內核的外設,它的中斷優先級和片上的外設的中斷優先級相比,哪一個高?
	答:根據中斷向量表查看中斷優先級;
		中斷優先級的分組隊內核和外設同樣適用。當比較的時候,
		只需要把內核外設的中斷優先級的四個位按照外設的中斷優先級來
		分組即可,即人爲的分出【搶佔優先級】和【子優先級】


	實驗:編寫微秒級的延時函數 LED閃爍

		固件庫函數:
			/**
			 * @brief  Initialize and start the SysTick counter and its interrupt.
			 *	簡述:初始化並且開啓系統滴答定時器及其中斷
			 * @param   ticks   number of ticks between two interrupts
				參數:  ticks :兩次中斷的滴答數
			 * @return  1 = failed, 0 = successful
			    返回值:1=失敗,0=成功
			 *
			 * Initialise the system tick timer and its interrupt and start the
			 * system tick timer / counter in free running mode to generate 
			 * periodical interrupts.
				初始化系統計時器及其中斷,並在自由運行模式下
				啓動系統計時計時器/計數器,以生成周期性中斷
			 */
			static __INLINE uint32_t SysTick_Config(uint32_t ticks)
			{ 
			  //判斷tick的值是否大於2^24,如果大於,則不符合規則
			  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */
				
			  //初始化reload寄存器的值
			  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register */
			  
			  //配置中斷優先級,配置爲15,默認爲最底的優先級
			  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Cortex-M0 System Interrupts */
			  
			  //初始化counter的值爲0
			  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
			  
			  //配置systick的時鐘爲72M;使能中斷;使能systick開始計數
			  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | 
							   SysTick_CTRL_TICKINT_Msk   | 
							   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
			  return (0);                                                  /* Function successful */
			}
			
		自己編寫函數:
			/*
			* param:us:微妙數,us=1000,則該函數產生一個1000us的延時
			*/
			void SysTick_Delay_us(uint32_t us)
			{
				uint32_t i;
				SysTick_Config(72);
				
				for(i = 0 ;i < us;i++)
				{
					//counter會從reload的值下減到0
					//當計數器的值減小到0的時候,CTRL寄存器的16位會置1,
					//循環判斷SysTick的CTRL的16位是否爲1 ,如果是,則說明達到1微妙,跳出循環
					while(  !((SysTick->CTRL) & (1<<16))   );
				}
				
				//跳出循環說明時間到,SysTick清零
				SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
			}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章