【stm32f407】SysTick實現延時

一.  SysTick介紹:

CM4內核的處理和CM3一樣,內部都包含了一個SysTick定時器,SysTick 是一個24 位的倒計數定時器,當計到0 時 ,將 從RELOAD 寄存器中自動重裝載定時初值。只要不把它在SysTick 控制及狀態寄存器中的使能位清除,就永不停息。我們就是利用STM32的內部SysTick來實現延時的,這樣既不佔用中斷,也不佔用系統定時器

       通常SysTick可以通過中斷的方式來實現,後續會增加,但是目前只是通過輪詢的方式去實現

二.  寄存器介紹

SysTick4個寄存器

對應的代碼在core_cm4.h

typedefstruct
{
  __IO uint32_t CTRL;                    /*!< Offset: 0x000(R/W)  SysTick Control and StatusRegister */
  __IO uint32_t LOAD;                    /*!< Offset: 0x004(R/W)  SysTick Reload Value Register       */
  __IO uint32_t VAL;                     /*!< Offset: 0x008(R/W)  SysTick Current ValueRegister      */
  __I uint32_t CALIB;                  /*!< Offset: 0x00C (R/ ) SysTick Calibration Register       */
} SysTick_Type; 

1) CTR寄存器如圖:

0位:ENABLESystick 使能位  0:關閉Systick功能;1:開啓Systick功能)
1位:TICKINTSystick 中斷使能位    0:關閉Systick中斷;1:開啓Systick中斷)

2位:CLKSOURCESystick時鐘源選擇  0:使用HCLK/8 作爲Systick時鐘;1:使用HCLK作爲Systick時鐘)

16位:COUNTFLAGSystick計數比較標誌,如果在上次讀取本寄存器後,SysTick 已經數到了0,則該位爲1。如果讀取該位,該位將自動清零.

2) LOAD寄存器如圖:

Systick是一個遞減的定時器,當定時器遞減至0時,重載寄存器中的值就會被重裝載,繼續開始遞減。STK_LOAD 重載寄存器是個24位的寄存器最大計數0xFFFFFF

3) VAL寄存器如圖:

也是個24位的寄存器,讀取時返回當前倒計數的值,寫它則使之清零,同時還會清除在SysTick 控制及狀態寄存器中的COUNTFLAG 標誌。

4) CALIB寄存器如圖

一般不會用到

三.  源碼

delay.h

#ifndef _DELAY_H_H_H
#define _DELAY_H_H_H
#include "stm32f4xx.h"

void delay_init(u8 SYSCLK);
void delay_ms(u16 nms);
void delay_us(u32 nus);
#endif

delay.c

#include "delay.h"

static u8  fac_us=0;		   
static u16 fac_ms=0;
void delay_init(u8 SYSCLK)
{
  SysTick->CTRL&=~(1<<2);
  fac_us=SYSCLK/8;
  fac_ms=((u32)SYSCLK*1000)/8;
}
void delay_xms(u16 nms)
{	 		  	  
  u32 temp;		   
  SysTick->LOAD=(u32)nms*fac_ms;
  SysTick->VAL =0x00;
  SysTick->CTRL=0x01 ;
  do
  {
    temp=SysTick->CTRL;
  }while((temp&0x01)&&!(temp&(1<<16)));
  SysTick->CTRL=0x00;
  SysTick->VAL =0X00;	  	    
} 

void delay_ms(u16 nms)
{
  u8 repeat=nms/540;
  u16 remain=nms%540;
  while(repeat)
  {
    delay_xms(540);
    repeat--;
  }
  if(remain)delay_xms(remain);
  
}
void delay_us(u32 nus)
{
  u32 temp;	    	 
  SysTick->LOAD=nus*fac_us;  		 
  SysTick->VAL=0x00;
  SysTick->CTRL=0x01 ;	 
  do
  {
    temp=SysTick->CTRL;
  }while((temp&0x01)&&!(temp&(1<<16)));
  SysTick->CTRL=0x00;
  SysTick->VAL =0X00;  
}



發佈了207 篇原創文章 · 獲贊 561 · 訪問量 79萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章