利用滴答定時器(SysTick)實現簡單的延時函數


預備知識:

對標准庫來說,如果定義了時鍾頻率,則系統會默認初始化該時鍾頻率。

SysTick是CM4的內核外設,是一個24位的向下遞減計數器,每次計數時間是1/SYSCLK,即1/168000000。
SysTick計數時間的計算:t=重裝載值*1/AHB時鍾頻率。1/AHB時鍾頻率即是計數一次的時間。一般把重裝載值定為128000000/100000=1280,則10us中斷一次;一般不設置為1us中斷一次,這樣中斷頻率太高,偏移了程序重心。

 

正文:

程序源碼:

在main.c中

 

#include "sys.h"
#include "led.h"

// "__IO"在Core_cm4.h中被重定義,原型是"volatile" ①
__IO uint32_t TimingDelay;      

// 延時函數
void Delay(__IO uint32_t nTime)    
{
    TimingDelay = nTime;
    while(TimingDelay != 0);
}

// 主函數
int main(void)
{ 
    // 初始化LED端口
    LED_Init();
    // 初始化SysTick ②
    if(SysTick_Config(SystemCoreClock/1000))  
    {
        // Capture error
        while(1);
    }
    // LED閃爍
    while(1)                                   
    {
        Delay(250);   GPIO_SetBits(GPIOF,GPIO_Pin_9);
        Delay(250); GPIO_ResetBits(GPIOF,GPIO_Pin_9);
    }
}


/*------------------------------------------------------------------------------------
注釋:
    ①:volatile 的作用就是指示編譯器不要因優化而省略此指令,必須每次都直接讀寫其值。
       寫一段測試代碼如下:
         u8  test;
         test = 1;
         test = 2;
         test = 3;

       設置優化級別中級
       運行后test會被直接取值為3 只有最后一個語句被編譯
       
       如用volatile:
         volatile u8 test;
         test = 1;
         test = 2;
         test = 3;
       則所有語句都會被編譯。test先后被設置成1、2、3
       由此可以看出這個作用在IO操作,寄存器操作,特殊變量,多線程變量讀寫都是很重要。
    ②:SysTick_Config的參數,是一個時鍾次數,叫systick重裝定時器的值。意思就是多少個
       1/fosc 時間后中斷一下。
       這里 SystemCoreClock/1000 為沒過1ms中斷一次,SystemCoreClock為系統時鍾頻率。
       計算方法為:
       SystemCoreClock ÷ timer = 1ms
       假設SystemCoreClock為128M,單位為Hz。則:
       1ms = 1128MHz ÷ timer
           = 128M/s ÷ timer
             
                128M
               ------
       timer =   1s
               ------
               0.001s
                                        
                128M
       timer = ------
                1000
              
------------------------------------------------------------------------------------*/

 

在stm32f4xx_it.c中

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_it.h"
 
/* 變量定義 ------------------------------------------------------------------*/
// 利用關鍵字extern,可以在一個文件中引用另一個文件中定義的變量或者函數
extern __IO uint32_t TimingDelay;

/**
  * @brief  This function handles SysTick Handler.
  * @param  None
  * @retval None
  */
void SysTick_Handler(void)
{
    
    if(TimingDelay != 0x00)
    {
        TimingDelay--;
    }
}

注意:

1.在stm32中,中斷函數在stm32f4xx_it.c中,不能像51那樣寫在main.c文件下。

2.關鍵字extern拓展變量作用范圍的用法。

3.__IO == volatile

參考資料:

https://blog.csdn.net/u010834669/article/details/80204195

 


免責聲明!

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



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