1. 程式人生 > >利用STM32的SysTick設計精確延時函式

利用STM32的SysTick設計精確延時函式

在專案中使用I2C介面感測器時要求有比較精確的延時,在網上搜了下,如果不想用中斷SysTick定時器可以做到,找到如下資料:

主要仿照原子的《STM32不完全手冊》。SYSTICK 的時鐘固定為HCLK 時鐘的1/8,在這裡我們選用內部時鐘源72M,所以SYSTICK的時鐘為9M,即SYSTICK定時器以9M的頻率遞減。SysTick 主要包含CTRLLOADVALCALIB 個暫存器,

SysTick->CTRL

位段

名稱

型別

復位值

描述

16

COUNTFLAG

R

0

如果在上次讀本暫存器後systick已為0,則該位為1,若讀該位自動清零

2

CLKSOURCE

RW

0

0:外部時鐘源 1:內部時鐘

1

TICKINT

RW

0

0:減到0無動作;1:減到0產生systick異常請求

0

ENABLE

RW

0

systick定時器使能位

SysTick-> LOAD

位段

名稱

型別

復位值

描述

23:0

RELOAD

RW

0

減到0時被重新裝載的值

SysTick-> VAL

位段

名稱

型別

復位值

描述

23:0

CURRENT

RW

0

讀取時返回當前倒計數的值,寫則清零,同時還會清除在systick

控制及狀態暫存器中的COUNTFLAG 標誌

SysTick-> CALIB 不常用,在這裡我們也用不到,故不介紹了。

/*定時器初始化函式*/
void Delay_Init(u8t SYSCLK) //SYSCLK為系統時鐘頻率除以1000000後的值,例:如果系統時鐘頻率為72MHz,則呼叫該函式時此處的實參為72
{
	SysTick->CTRL&=0xFFFFFFFB;
	fac_us=SYSCLK/8;
	fac_ms=(u16t)(fac_us*1000);		
}

/*1微秒延時函式*/
void Delay_us(u32t nus)
{
	u32t temp;
	SysTick->LOAD=nus*fac_us;
	SysTick->VAL=0x00;
	SysTick->CTRL=0x01;
	do
	{
		temp=SysTick->CTRL;
	}
	while(temp&0x01&&!(temp&0x10000));
	SysTick->CTRL=0x00;
	SysTick->VAL=0x00;	
}

/*1毫秒延時函式*/
void Delay_ms(u16t nms)
{
	u32t temp;
	SysTick->LOAD=(u32t)(nms*fac_ms);
	SysTick->VAL=0x00;
	SysTick->CTRL=0x01;
	do
	{
		temp=SysTick->CTRL;
	}
	while(temp&0x01&&!(temp&0x10000));
	SysTick->CTRL=0x00;
	SysTick->VAL=0x00;	
}


相關推薦

利用STM32的SysTick設計精確函式

在專案中使用I2C介面感測器時要求有比較精確的延時,在網上搜了下,如果不想用中斷SysTick定時器可以做到,找到如下資料: 主要仿照原子的《STM32不完全手冊》。SYSTICK 的時鐘固定為HCLK 時鐘的1/8,在這裡我們選用內部時鐘源72M,所以SYSTICK的時

STM32中通過普通函式精確

在STM32中處處會用到延時函式,一般而言,對於普通的控制延時,並不會要求特別精確,所以可以使用普通的延時函式,例如 void delay(u32 time) { while(time--);

DOS下面關於精確1ms的函式(理論上可以非常精確到10微妙級別)

在微軟的MSC7.0以及MSVC1.52下面都沒有Borland C++的精確延時函式:delay(經過測試可以非常精確的延時到1ms)同時看了一下計時器的相關內容,自己寫了一個精確延時函式,但不敢保證在所有的電腦上都可以精確延時原始碼:/****void xdelay(unsigned int ms)**P

unity函式

新建一個工具類 public class DelayToInvoke : MonoBehaviour{ public static IEnumerator DelayToInvokeDo(Action action, float delaySeconds){yield return new Wai

linux核心 訊號量與自旋鎖、函式比較

       在驅動程式中,當多個執行緒同時訪問相同的資源時(驅動程式中的全域性變數是一種典型的共享資源),可能會引發"競態",因此我們必須對共享資源進行併發控制。Linux核心中解決併發控制的最常用方法是自旋鎖與訊號量(絕大多數時候作為互斥鎖使用)。   自

不使用中斷實現通用定時器精確

網上大多數延時函式都是通過中斷方式的通用定時器來實現,如果實現1us的延時那麼每1us就來一次中斷,很影響cpu的效率。 本文不使用中斷通過是用通用定時器來實現精確延時。 程式碼如下(基於stm32f103) static void udelay(uint32_t us) { uint

STM32使用systick定時器定義硬體精準函式

前言 博文基於STM32F103ZET6和標準韌體庫V3.5.0在MDK5環境下開發; 本博文討論的是晶片不執行作業系統的情況下完成1s的延時功能; 如有不足之處還請多多指教; SysTick—系統滴答定時器是什麼? 是一個24位的硬體倒計數定時器; Sys

Systick滴答定時器-函式

1、參考資料       《STM32F1開發指南-庫函式版本》-5.1小節 delay資料夾介紹           《Cortex-M3權威指南-中文》-第8章最後一個小節:Systick定時器 2、Systick定時器     Systick定時器,是一個簡單的定時器

一個超簡單的 android 函式

因java初學,總是帶著一些VB的語法思路,想在一個 for迴圈裡面暫停個幾毫秒以實現指定的動畫效果,又不想用動畫函式(因為只是移動文字的位置),所以只好學著VB裡面一樣,弄一個延時函式來用用了: private void delay(int ms){ try {

SysTick定時器應用之一——用於函式

SysTick為簡單的向下計數的24位計時器,可以使用處理器時鐘或外部參考時鐘(通常是片上時鐘源)。當不使用OS時,SysTick定時器可以用作簡單的定時器外設,用以產生週期性中斷、延時或者時間測量。 用於延時函式的話比較簡單,SysTick定時器操作存在4個暫存器 Sy

【51微控制器】函式計算問題以及如何準確

幾種週期介紹 週期名稱 描述 時間 振盪(時鐘) 微控制器提供時鐘脈衝訊號的振盪源的週期 T=1/f 狀態 振盪週期經二分頻後得到的 2T 機器 在一個機器週期內,CPU可以完成一個獨立的 操作

STM32的SysTick定時器與Delay函式

1.BB一下 原子哥的Delay延時函式,在沒有使用OS的情況下,沒有使用SysTick中斷,而筆者希望通過該中斷記錄系統時間 不使用OS,使用SysTick中斷 不使用OS,不使用SysTick

CC2530微控制器函式實際測試

    因為要檢測不同的波形,所以對時間要求很高,但是發現Zstack本身提供的微秒級的延時其實有誤差。    因此特地寫了測試函式,然後用示波器觀察了時間。詳細如下:     先說CC2530與普通8051微控制器時鐘的不同,CC2530的每個指令是一個時鐘,而標準的80

【STM32】SysTick滴答定時器(delay函式講解)

STM32F1xx官方資料:《Cortex-M3權威指南-中文》-第8章最後一個小節:Systick定時器SysTick定時器Systick定時器,是一個簡單的定時器,對於CM3、CM4核心晶片,都有Systick定時器。Systick定時器常用來做延時,或者實時系統的心跳時

微控制器函式實現

在編寫微控制器程式時,我們經常要用到延時函式,記得我們在學51微控制器時,第一個延時是通過軟體延時來實現的,程式碼如下: void delay(volatile uint32_t cnt){ volatile uint32_t i = 0; volatile uint

對MSP430微控制器__delay_cycles精確的說明及改正

在這裡, 我來討論一下關於MSP430微控制器使用__delay_cycles延時的問題. IAR for MSP430編譯器提供了一個編譯器內聯的精確延時函式(並非真正的 函式)以提供使用者精確延時使用, 該函式原型是: __intrinsic void __delay_cy

STM32使用systick實現精確

SYSTICK暫存器初始化 void SysTick_Configuration(void) {     if (SysTick_Config(SystemCoreClock / 100))          {         while (1);   }     NVIC_SetPriority(

stm32 使用正點原子delay函式,主函式失效

最近在做一個東西時,發現一個現象。之前一直沒有發現過,或者發現也沒有仔細研究過,在此為大家分享。 在使用原子哥的延時函式時,發現主函式裡面的延時函式失效了。沒有起任何作用。下面簡單分析一個整個過程。 先直接上程式碼,很簡單的一個例項 int main(void) {

Linux kernel 核心函式

其他參考:http://blog.csdn.net/lixiaojie1012/article/details/44229009 當一個裝置驅動需要處理它的硬體的反應時間, 涉及到的延時常常是最多幾個毫秒. 在這個情況下, 依靠時鐘嘀噠顯然不對路. The kerne

用SysTick值抓取法,實現DelayUS()的微妙函式

程式說明:(1)在bsp_timer.c中加入bsp_DelayUS()的微妙延時函式(2)用定時器6實現程式執行時間測量,最小單位0.083us。         下面使用TIM6測量bsp_DelayUS(10)的執行時間,實際測試結果        Time = 10