娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

歷史上的今天

今天是:2025年03月13日(星期四)

正在發(fā)生

2019年03月13日 | 【STM32】SysTick滴答定時(shí)器(delay延時(shí)函數(shù)講解)

發(fā)布者:EnigmaticCharm 來源: eefocus關(guān)鍵字:STM32  SysTick  滴答定時(shí)器  delay延時(shí)函數(shù) 手機(jī)看文章 掃描二維碼
隨時(shí)隨地手機(jī)看文章

STM32F1xx官方資料:

Cortex-M3權(quán)威指南-中文》-第8章最后一個(gè)小節(jié):Systick定時(shí)器


SysTick定時(shí)器

Systick定時(shí)器,是一個(gè)簡(jiǎn)單的定時(shí)器,對(duì)于CM3、CM4內(nèi)核芯片,都有Systick定時(shí)器。Systick定時(shí)器常用來做延時(shí),或者實(shí)時(shí)系統(tǒng)的心跳時(shí)鐘。這樣可以節(jié)省MCU資源,不用浪費(fèi)一個(gè)定時(shí)器。比如UCOS中,分時(shí)復(fù)用,需要一個(gè)最小的時(shí)間戳,一般在STM32+UCOS系統(tǒng)中,都采用Systick做UCOS心跳時(shí)鐘。


Systick定時(shí)器就是系統(tǒng)滴答定時(shí)器,一個(gè)24 位的倒計(jì)數(shù)定時(shí)器,計(jì)到0 時(shí),將從RELOAD 寄存器中自動(dòng)重裝載定時(shí)初值。只要不把它在SysTick 控制及狀態(tài)寄存器中的使能位清除,就永不停息,即使在睡眠模式下也能工作。


SysTick定時(shí)器被捆綁在NVIC中,用于產(chǎn)生SYSTICK異常(異常號(hào):15)。Systick中斷的優(yōu)先級(jí)也可以設(shè)置。


實(shí)際上,Systick就是一個(gè)定時(shí)器而已,只是它放在了NVIC中,主要的目的是為了給操作系統(tǒng)提供一個(gè)硬件上的中斷,稱之為滴答中斷操作系統(tǒng)進(jìn)行運(yùn)轉(zhuǎn)的時(shí)候,也會(huì)有時(shí)間節(jié)拍。它會(huì)根據(jù)節(jié)拍來工作,把整個(gè)時(shí)間段分成很多小小的時(shí)間片,而每個(gè)任務(wù)每次只能運(yùn)行一個(gè)時(shí)間片的時(shí)間長(zhǎng)度,超時(shí)就退出給別的任務(wù)運(yùn)行,這樣可以確保任何一個(gè)任務(wù)都不會(huì)霸占操作系統(tǒng)提供的各種定時(shí)功能,都與這個(gè)滴答定時(shí)器有關(guān)。因此,需要一個(gè)定時(shí)器來產(chǎn)生周期性的中斷,而且最好還讓用戶程序不能隨意訪問它的寄存器,以維持操作系統(tǒng)的節(jié)拍。只要不把它在SysTick控制及狀態(tài)寄存器中的使能位清除,就一直執(zhí)行。 


SysTick相關(guān)寄存器

SysTick有四個(gè)寄存器,分別為CTRL(控制與狀態(tài)寄存器)、LOAD(自動(dòng)重裝載值寄存器)、VAL(當(dāng)前值寄存器)、CALIB(校準(zhǔn)值寄存器)。


在MDK的core_m3.h文件中定義了一個(gè)結(jié)構(gòu)體SysTick_Type,里面也包括了這四個(gè)寄存器。


typedef struct

{

  __IO uint32_t CTRL;                         /*!< Offset: 0x00  SysTick Control and Status Register */

  __IO uint32_t LOAD;                         /*!< Offset: 0x04  SysTick Reload Value Register       */

  __IO uint32_t VAL;                          /*!< Offset: 0x08  SysTick Current Value Register      */

  __I  uint32_t CALIB;                        /*!< Offset: 0x0C  SysTick Calibration Register        */

} SysTick_Type;

它們的各位描述如下面的表格所述:


CTRL寄存器各位描述

位段 名稱 類型 復(fù)位值 描述

16 COUNTFLAG R 0

如果在上次讀取本寄存器后,SysTick已經(jīng)數(shù)到了0,是該位為1.如果讀


取該位,該位自動(dòng)清零。


2 CLKSOURCE R/W 0

0 外部時(shí)鐘源(STCLK)


1 內(nèi)核時(shí)鐘(FCLK)


1 TICKINT R/W 0

1 SysTick倒數(shù)到0時(shí)產(chǎn)生SysTick異常請(qǐng)求


0 數(shù)到0時(shí)無動(dòng)作


0 ENABLE R/W 0 SysTick定時(shí)器的使能位

對(duì)于STM32,外部時(shí)鐘源(STCLK)是HCLK(AHB總線時(shí)鐘)的1/8,內(nèi)核時(shí)鐘(FCLK)是HCLK(AHB總線時(shí)鐘)。


LOAD寄存器各位描述

位段 名稱 類型 復(fù)位值 描述

23:0 RELOAD R/W 0 當(dāng)?shù)箶?shù)至0是,將被重新裝載的值

VAL寄存器各位描述

位段 名稱 類型 復(fù)位值 描述

23:0 CORRENT R/Wc 0

讀取時(shí)返回當(dāng)前倒計(jì)數(shù)的值,寫它則使之清零,同時(shí)還會(huì)清


除在CTRL寄存器的COUNTFLAG位


SysTick相關(guān)庫函數(shù)

SysTick_CLKSourceConfig(),這是Systick的時(shí)鐘源選擇,直接配置CTRL寄存器的值。假設(shè)HCLK為72MHz,選用外部時(shí)鐘源,那么SysTick的時(shí)鐘即9MHz。這就意味著,SysTick的計(jì)數(shù)器VAL每減1代表時(shí)間過去了1/9us。


具體的定義在misc.c文件中。


void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)

{

  /* Check the parameters */

  assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));

  if (SysTick_CLKSource == SysTick_CLKSource_HCLK)

  {

    SysTick->CTRL |= SysTick_CLKSource_HCLK;

  }

  else

  {

    SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;

  }

}

SysTick_Config(uint32_t ticks) ,這是SysTick的初始化函數(shù),時(shí)鐘為HCLK,并開啟SysTick中斷。其中函數(shù)的參數(shù)表示兩次中斷之間時(shí)間間隔期間的SysTick周期,即兩次中斷之間有多少個(gè)SysTick周期。


具體的定義在core_cm3.h文件中。


static __INLINE uint32_t SysTick_Config(uint32_t ticks)

  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */

                                                               

  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register */

  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Cortex-M0 System Interrupts */

  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */

  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | 

                   SysTick_CTRL_TICKINT_Msk   | 

                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */

  return (0);                                                  /* Function successful */

}

void SysTick_Handler(void),這是SysTick的中斷服務(wù)函數(shù)。我們舉一個(gè)例子,利用中斷的方式實(shí)現(xiàn)delay延時(shí)函數(shù),見下面的程序:


static __IO uint32_t TimingDelay;

void Delay(__IO uint32_t nTime)

   TimingDelay = nTime;

   while(TimingDelay != 0);

}

void SysTick_Handler(void)

{

    if (TimingDelay != 0x00) 

     { 

       TimingDelay--;

     }

}

 int main(void)

 {  …

    if (SysTick_Config(SystemCoreClock / 1000)) //systick時(shí)鐘為HCLK,中斷時(shí)間間隔1ms

     {

     while (1);

     }

    while(1)

     { Delay(200);//200ms

     … 

     }

}

 


Delay延時(shí)函數(shù)講解

之前利用中斷實(shí)現(xiàn)延時(shí)函數(shù),但是一直使用中斷會(huì)造成資源的浪費(fèi),不建議這樣實(shí)現(xiàn),我們利用查詢的方式實(shí)現(xiàn)delay延時(shí)。下面主要介紹Delay延時(shí)函數(shù)的實(shí)現(xiàn):


delay_init()

首先是delay_init(),延時(shí)初始化函數(shù)。利用Syst_CLKSourceConfig()函數(shù)選擇SysTick時(shí)鐘源,選擇外部時(shí)鐘(HCLK的1/8);同時(shí)初始化fac_us和fac_ms兩個(gè)變量。


void delay_init()

{

SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //選擇外部時(shí)鐘  HCLK/8

fac_us=SystemCoreClock/8000000;       //為系統(tǒng)時(shí)鐘的1/8,實(shí)際上也就是在計(jì)算1usSysTick的VAL減的數(shù)目

fac_ms=(u16)fac_us*1000; //代表每個(gè)ms需要的systick時(shí)鐘數(shù),即每毫秒SysTick的VAL減的數(shù)目   

}

delay_ms()

其次,delay_ms(),此函數(shù)用來延時(shí)指定的ms。


此時(shí)要注意nms的范圍,SysTick->LOAD為24位寄存器,所以最大延時(shí)為:nms<=0xffffff*8*1000/SYSCLK;SYSCLK單位為Hz,nms單位為ms。對(duì)72M條件下,nms<=1864。如果超出這個(gè)值,建議多次調(diào)用此函數(shù)來實(shí)現(xiàn)。


void delay_ms(u16 nms)

{     

u32 temp;    

SysTick->LOAD=(u32)nms*fac_ms; //時(shí)間加載(SysTick->LOAD為24bit)

SysTick->VAL =0x00;           //清空計(jì)數(shù)器

SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;          //開始倒數(shù)  

do

{

temp=SysTick->CTRL;

}while((temp&0x01)&&!(temp&(1<<16))); //等待時(shí)間到達(dá),看CTRL的第16位(COUNTFLAG)是否為1,看STRL的第0位(ENABLE)是否為1   

SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;       //關(guān)閉計(jì)數(shù)器

SysTick->VAL =0X00;       //清空計(jì)數(shù)器       

這段代碼其實(shí)就是先把延時(shí)的時(shí)間換算成SysTick的時(shí)鐘周期數(shù),然后寫入LOAD寄存器。然后清空當(dāng)前寄存器VAL的內(nèi)容,再開啟倒數(shù)功能。等倒數(shù)結(jié)束即延時(shí)了nms、最后關(guān)閉SysTick,清空VAL的值,實(shí)現(xiàn)一次延時(shí)的操作。


這里特別說一下,temp&0x01,這一句用來判斷SysTick定時(shí)器是否還處在開啟的狀態(tài),可以防止SysTick被意外關(guān)閉導(dǎo)致的死循環(huán)。


delay_us()

最后,delay_us(),此函數(shù)用來延時(shí)指定的us。具體的邏輯和上面一個(gè)函數(shù)類似,就不介紹了。


void delay_us(u32 nus)

{

u32 temp;      

SysTick->LOAD=nus*fac_us; //時(shí)間加載    

SysTick->VAL=0x00;        //清空計(jì)數(shù)器

SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;          //開始倒數(shù)   

do

{

temp=SysTick->CTRL;

}while((temp&0x01)&&!(temp&(1<<16))); //等待時(shí)間到達(dá)   

SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;       //關(guān)閉計(jì)數(shù)器

SysTick->VAL =0X00;       //清空計(jì)數(shù)器  

}

delay延時(shí)的相關(guān)函數(shù)在SYSTEM文件夾下的delay子文件夾,在使用delay_ms()或者delay_us()函數(shù)之前一定不要忘記先初始化delay_init()。


關(guān)鍵字:STM32  SysTick  滴答定時(shí)器  delay延時(shí)函數(shù) 引用地址:【STM32】SysTick滴答定時(shí)器(delay延時(shí)函數(shù)講解)

上一篇:【STM32】GPIO工作原理(八種工作方式超詳細(xì)分析)
下一篇:【STM32】NVIC中斷優(yōu)先級(jí)管理(中斷向量表)

推薦閱讀

  摩托羅拉總部裁員,據(jù)外媒消息,摩托羅拉正在裁掉芝加哥的一部分員工,并且心懷不滿的員工已經(jīng)開始通過在線匿名職位談?wù)摌I(yè)務(wù)決策。根據(jù)這些人的報(bào)道,摩托羅拉最近通知其員工有一次大規(guī)模裁員,據(jù)報(bào)道裁員將影響了芝加哥30%到35%的工人。這2016年發(fā)生的裁員類似。下面就隨手機(jī)便攜小編一起來了解一下相關(guān)內(nèi)容吧。  關(guān)于裁員問題的報(bào)道本周開始在TheL...
STM32F1xx官方資料:《STM32中文參考手冊(cè)V10》-第17章 獨(dú)立看門狗獨(dú)立看門狗概述看門狗的定義在由單片機(jī)構(gòu)成的微型計(jì)算機(jī)系統(tǒng)中,由于單片機(jī)的工作常常會(huì)受到來自外界電磁場(chǎng)的干擾,造成程序的跑飛,而陷入死循環(huán);或者程序的正常運(yùn)行被打斷,由單片機(jī)控制的系統(tǒng)無法繼續(xù)工作,會(huì)造成整個(gè)系統(tǒng)的陷入停滯狀態(tài),發(fā)生不可預(yù)料的后果。所以出于對(duì)單片機(jī)運(yùn)行狀...
使用SWD通過J-Flash燒寫STM32時(shí),會(huì)出現(xiàn)各式各樣的錯(cuò)誤; 總結(jié)下原因: 1、復(fù)位腳被拉低了,這次我遇到的就是復(fù)位引腳的電容焊反了(鉭電容),可以正常連接,但是燒寫程序時(shí)會(huì)出現(xiàn)如下報(bào)錯(cuò) –> - Erasing affected sectors … - ERROR: RAM check failed @ address 0x20000000. - ERROR: Write: 0x03020100 07060504 - ERROR: Read: 0x...
一方面,無人機(jī)侵入國(guó)家機(jī)關(guān)和軍隊(duì)駐地等敏感區(qū)域,會(huì)對(duì)國(guó)家安全造成嚴(yán)重侵害;另一方面,機(jī)場(chǎng)“黑飛”事件嚴(yán)重影響航班正常運(yùn)行,惡意的無人機(jī)飛行也對(duì)電力、石油等產(chǎn)業(yè)的信息安全等產(chǎn)生較大威脅。近年來,無人機(jī)大量使用導(dǎo)致無人機(jī)“黑飛”事件也不斷增多,杭州蕭山國(guó)際機(jī)場(chǎng)黑飛案件、銀川機(jī)場(chǎng)無人機(jī)黑飛事件、昆明長(zhǎng)水機(jī)場(chǎng)無人機(jī)黑飛事件、重慶機(jī)場(chǎng)無人...

史海拾趣

問答坊 | AI 解惑

IPTV加速網(wǎng)絡(luò)寬帶化

本帖最后由 jameswangsynnex 于 2015-3-3 20:03 編輯 …

查看全部問答∨

汽車空調(diào)維修基本注意事項(xiàng)

1:空調(diào)新裝好進(jìn)行充填時(shí),先從高壓側(cè)進(jìn)行時(shí)間在5min以上的抽真空,然后關(guān)閉閥門觀察高低壓力表讀數(shù),再從高、低兩個(gè)方向抽真空這樣可以輔助檢測(cè)系統(tǒng)是否堵塞和泄漏.抽完真空要先關(guān)閉壓力表閥門再切斷真空泵電源,以免真空度下降. 2:填充制 ...…

查看全部問答∨

各種單片機(jī)CPLD/FPGA開發(fā)板

各種單片機(jī)CPLD/FPGA開發(fā)板 詳細(xì)情況請(qǐng)?jiān)L問: http://www.ednchina.com/blog/yangguang1975/…

查看全部問答∨

傳遞信號(hào)用電壓還是電流好

要在兩塊板子上傳遞信號(hào),用電壓信號(hào)好還是電流信號(hào)好?…

查看全部問答∨

急聘嵌入式軟件測(cè)試社會(huì)及實(shí)習(xí)生

一、研究院簡(jiǎn)介     中國(guó)科學(xué)院光電研究院(以下簡(jiǎn)稱光電院)是隸屬于中國(guó)科學(xué)院的科研機(jī)構(gòu),總部設(shè)在北京。院址選定在北京航天城,目前辦公地點(diǎn)在北京海淀區(qū)。     中國(guó)科學(xué)院光電研究院評(píng)測(cè)中心主要從事載人航天工程應(yīng)用系 ...…

查看全部問答∨

那幾所大學(xué)的嵌入式專業(yè)比較好?

小生準(zhǔn)備考研了,小生已經(jīng)瞄準(zhǔn)了嵌入式這塊肥肉,敢問各位兄臺(tái),那所大學(xué)的嵌入式比較好啊?…

查看全部問答∨

VS2005+WinCE6.0

   最近在搞EVC4.2+WinCE4.0遷移到VS2005+WinCE6.0中去,突然發(fā)現(xiàn) 有好多的問題,不知道哪位大哥有在VS2005+WinCE6.0上開發(fā)的經(jīng)驗(yàn)的 請(qǐng)給一些參考書籍或則資料什么的,十分感謝,同樣也希望大家有什么 問題提出來一起交流一下。共同努 ...…

查看全部問答∨

高分求救!!wince下如何讀取光盤扇區(qū)數(shù)據(jù)?

wince下如何按扇區(qū)讀取光盤中的數(shù)據(jù)?…

查看全部問答∨

凌陽單片機(jī)中實(shí)用LCD??

在凌陽的單片機(jī)中,使用LCD的時(shí)候怎么樣寫一個(gè)完整的程序才能把一個(gè)字符顯示在LCD上呢?請(qǐng)說說過程,特別是怎么樣使用的輸入輸出口的?在此先感謝!!…

查看全部問答∨

usb FET升級(jí)的問題

我在用USB FET調(diào)試時(shí),居然提示我說“firmware的版本不對(duì),是否要升級(jí)”。試了幾次,都出現(xiàn)這種情況。本來想明天咨詢了再弄的,結(jié)果熬不住,點(diǎn)了“確定”。這下好了,就看見IAR在進(jìn)行了什么“Erase――”之后,就永遠(yuǎn)地停在那里了。 各位大蝦,這 ...…

查看全部問答∨
小廣播
設(shè)計(jì)資源 培訓(xùn) 開發(fā)板 精華推薦

最新單片機(jī)文章

 
EEWorld訂閱號(hào)

 
EEWorld服務(wù)號(hào)

 
汽車開發(fā)圈

 
機(jī)器人開發(fā)圈

電子工程世界版權(quán)所有 京ICP證060456號(hào) 京ICP備10001474號(hào)-1 電信業(yè)務(wù)審批[2006]字第258號(hào)函 京公網(wǎng)安備 11010802033920號(hào) Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 蓬安县| 新乐市| 丹阳市| 内乡县| 望谟县| 修武县| 竹北市| 类乌齐县| 柘城县| 华宁县| 石狮市| 靖远县| 上虞市| 隆子县| 肃南| 开鲁县| 湖州市| 资兴市| 丰都县| 莫力| 屯留县| 葫芦岛市| 徐闻县| 民乐县| 中卫市| 江孜县| 拉萨市| 张北县| 辽源市| 普陀区| 乌拉特后旗| 东乌珠穆沁旗| 霍州市| 芦溪县| 嵊泗县| 鄂托克旗| 荥经县| 自贡市| 永丰县| 沧州市| 望谟县|