[SAN4N學習筆記]使用SysTick精準延時

1、準備工做:

     將上一節搭建的LED工程複製一份,命名爲「2.systick」。這一節主要講如何使用系統的SysTick節拍定時器來進行精準延時程序。函數

2、程序編寫:

SysTick是CM3/CM4內核芯片提供的一個定時器,咱們的板子使用的SAM4N芯片是CM4內核的,天然少不了這個定時器。ui

首先在Drivers文件夾中創建delay.c和delay.h文件並添加到工程中,在delay.c中寫入以下代碼:it

#include "delay.h"配置

uint32_t timeout=0;循環

/**************************************************************************下載

* 函數名:SysTick_Handler()定時器

* 參數  :void程序

* 返回值:voidim

* 描述  :系統節拍中斷服務函數命名

**************************************************************************/

void SysTick_Handler(void)

{

/*定時計數自減1*/

    timeout--;

}

/**************************************************************************

* 函數名:systick_hw_init()

* 參數  :void

* 返回值:void

* 描述  :系統節拍初始化函數

**************************************************************************/

void systick_hw_init(void)

{

//選擇系統節拍定時器的時鐘源爲系統內核時鐘

SysTick->CTRL|=0x01<<2;

//設置重裝值,配置系統節拍定時器爲1ms中斷一次

/*1ms <-->SystemCoreClock/1000

* 100us <-->SystemCoreClock/10000

* 10us <-->SystemCoreClock/100000

*/

SysTick->LOAD = SystemCoreClock/1000 - 1;

//使能系統節拍時鐘中斷

SysTick->CTRL|=0x02;

//使能系統節拍時鐘

SysTick->CTRL|=0x01;

}

/**************************************************************************

* 函數名:delay_ms()

* 參數  :uint32_t n  延時的毫秒數

* 返回值:void

* 描述  :使用系統節拍進行精準延時函數

**************************************************************************/

void delay_ms(uint32_t n)

{

   timeout = n;        //設置系統節拍延時

   while(timeout!=0);      //等待延時時間到

}

/**************************************************************************

* 函數名:delay()

* 參數  :uint32_t n  延時的循環個數

* 返回值:void

* 描述  :簡單的循環延時函數

**************************************************************************/

void delay(uint32_t n)

{

while(n--);

}

雖然註釋已經寫得很清楚了,但仍是講一下吧,主要是systick_hw_init函數,這是初始化配置SysTick的代碼,第一步先選擇SysTick的時鐘源,這裏我選擇使用系統內核時鐘做爲時鐘源;第二步是設置SysTick的Load值,這裏設置爲ystemCoreClock/1000 - 1;,這樣SysTick就會每毫秒中斷一次,最後是開啓中斷和使能SysTick。

延時主要是經過設定timeout的值,而後等待timeout爲0,在Systick中斷中,timeout會自減1,直到爲0。這樣就實現了ms級的精準延時函數delay_ms()。

在delay.h中主要寫寫函數聲明,以下:

#ifndef __DELAY_H

#define __DELAY_H

#include "sam4n16c.h"

/**************************************************************************

* 函數名:SysTick_Handler()

* 參數  :void

* 返回值:void

* 描述  :系統節拍中斷服務函數

**************************************************************************/

void SysTick_Handler(void);

/**************************************************************************

* 函數名:systick_hw_init()

* 參數  :void

* 返回值:void

* 描述  :系統節拍初始化函數

**************************************************************************/

void systick_hw_init(void);

/*************************************************************************

* 函數名:delay_ms()

* 參數  :uint32_t n  延時的毫秒數

* 返回值:void

* 描述  :使用系統節拍進行精準延時函數

**************************************************************************/

void delay_ms(uint32_t n);

/**************************************************************************

* 函數名:delay()

* 參數  :uint32_t n  延時的循環個數

* 返回值:void

* 描述  :簡單的循環延時函數

**************************************************************************/

void delay(uint32_t n);

#endif

接下來把main.c中的delay改掉,以下:

int main(void)

{

systick_hw_init();

led_hw_init();

while(1){

led_hw_on();

delay_ms(500);

led_hw_off();

delay_ms(500);

}

}

好了,下載程序到板子,這下是否是延時很準?

相關文章
相關標籤/搜索