日韩在线免费播放-日韩在线免费av-日韩在线免费-日韩在线毛片-国产高清不卡视频-国产高清不卡

當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > STM32F030 Nucleo-做個準(zhǔn)確的延時SysTick

STM32F030 Nucleo-做個準(zhǔn)確的延時SysTick 時間:2018-08-16      來源:未知

寫過單片機程序的人都知道,軟件延時是不準(zhǔn)確的,當(dāng)然,當(dāng)在我們可接受的情況下,很多地方還是用軟件延時的!但是在情況允許的條件下,我們還是希望延時越準(zhǔn)確越好,這樣可以保證我們Demo的一些精度或者時候準(zhǔn)確性。

在所以的ST32位MCU中,基本上都存在這么一個定時器,很多人都叫它“滴答定時器”,也就是SysTick,在我移植過的好幾個實時操作系統(tǒng)中,這個滴答定時器都用來作為操作系統(tǒng)調(diào)度的定時器了。其實這個定時器的使用非常簡單,但是基本上很多人又覺得它是神秘的!為毛呢??打開MCU的DadaSheet,參考手冊,都很少提到SysTick,并且提到的地方也就是一句話帶過,庫手冊也就是說明一下操作它的接口!然后!然后!然后就沒有然后了。

那么我們怎么樣使用它呢??有可能我們根本就不了解這個定時器,就算它再簡單,沒資料,呵呵!玩起來也是很費勁的啊!這個疑問先放起來!看看下一個疑問??

文章的開頭不是“做個準(zhǔn)確的延時”么??那么它和SysTick有毛關(guān)系呢??(可能多遠單片機程序員來說,延時就是:delay_ms(x)這種),其實我就想用SysTick來給我做延時,因為MCU的運行時鐘在配置好之后,就基本上是穩(wěn)定的了!穩(wěn)定的時鐘數(shù)山羊,那就可以計算出每數(shù)一次山羊所用的時間,更可以算出在一定時間內(nèi)能數(shù)多少只山羊了(還記得小時候的數(shù)山羊游戲嗎?)。所以就是利用這么個思想來干這種事。

當(dāng)然,問題又來了,STM32有那么多個通用定時器和特殊定時器,干嘛非得用SysTick啊??我個人給的答案就是:(1)只要你開心,想怎么樣都好。(2)對于通用定時器和特殊定時器而言,他們除了定時功能之外,還有其他的很多特殊復(fù)用功能,比如說PWM的輸出等等,非得這么干的話你這是在浪費資源(當(dāng)然,你若開心,便是晴天),然而,SysTick據(jù)我本人所知,它就是ARM核用來數(shù)山羊的,就這么個定時計時功能,不用它用誰??

回到上面的問題,我們怎么使用SysTick定時器呢??

首先,第一件事就是找到它再時鐘樹的位置(還是時鐘樹,可以想想它的地位有多重要了)。如下圖:

上圖還是時鐘樹(Clock Tree)從上圖我們可以得到這么幾個信息:

(1)SysTick就是內(nèi)核系統(tǒng)定時器(不管它,咱還是叫滴答定時器)

(2)SysTick的時鐘源來自HCLK

(3)SysTick的時鐘為HCLK的8分頻,即Fsystick = HCLK/8

(4)藍色框表示系統(tǒng)時鐘咱在前面的帖子已經(jīng)配置好了!哈哈!

好!第一件事干完了,也得到了相應(yīng)的信息,那么咱們干第二件事:

還記得在準(zhǔn)備資料的時候,特別提示,一點要將MCU的編程手冊下載下來嗎???在這里就用到它了!

就是上圖這個東西,名字叫STM32F0xxx Cortex-M0 programming manual ---->STM32F0xxx 系列Corte-M0編程手冊。

打開這個手冊,我們可以看到很多的東西,我簡單介紹一下吧!

瀏覽整個目錄,分為5章,如下:

第一章從技術(shù)角度來說,可能不是那么重要,但是對于不了解ST說明文檔的布局的童鞋而言,我個人認為還是必須瀏覽第一章的,因為他介紹了,本文檔的格式和關(guān)鍵詞使用還有必要的說明格式等,再就是簡單的介紹了文章的布局,和所包含的內(nèi)容,這對于閱讀文檔,找到想要的資料是快速的方法。

第二章基本上就是對Cortex-M0內(nèi)核的簡單介紹了,比如模式,堆棧,內(nèi)核寄存器,數(shù)據(jù)類型,內(nèi)存,低功耗模式等等的介紹了。

第三章看到這些想都不用想,就知道這是Cortex-M0內(nèi)核的匯編指令,操作指令了。

第四章,哈哈哈哈哈哈!看到標(biāo)題沒??Core peripherals 我想英語水平再差的人都知道這是Cortex-M0的核心外設(shè)了,那就是說這是ARM架構(gòu)Cortex-M0核有的東西,并不只有ST的才有。OK!SysTick就是核心外設(shè)之一啦!這就是為毛找它的原因了啊!哈哈!!等等,還有第五章,得裝完B再說。

下去!看看!就可以看到!第五章就是記錄著修訂歷史的,如下圖:

從這個圖我們可以得知,第一次出這個文檔的時間,而且從未修改過!哈哈 !不管了!談?wù)劯惺苄?/p>

首先,我覺得這個手冊是寫給程序員看的!它不是真正的Cortex-M0手冊,因為從手冊的內(nèi)容來看,它再教我們怎么使用,怎么寫程序配置,而不是解釋Cortex-M0內(nèi)核(當(dāng)然,從名字就知道了!哈哈!)。這一點很重要,所以它是非常重要的手冊,比庫函數(shù)手冊重要N倍。

OK!廢話了一大堆!先把滴答定時器用起來吧!

第一件事,找到庫中相應(yīng)的操作函數(shù)接口,所以我在keil中全工程搜索了一下,結(jié)果如下:

從上圖可以看出了,只看到了兩個與SysTick相關(guān)的函數(shù)(我用紅框標(biāo)出了),分別是:void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)函數(shù)和__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)函數(shù),(在Linux中__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)這種類型的函數(shù)叫內(nèi)聯(lián)函數(shù),不知道這是不是這樣叫),其中,void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)函數(shù)的作用,是是選擇SysTick的時鐘和初始化SysTick(從注釋和函數(shù)名就可以看出來了)。__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)函數(shù)就是“The function initializes the System Timer and its interrupt, and starts the System Tick Timer.

Counter is in free running mode to generate periodic interrupts.”初始化SysTick和中斷,開啟定時器。

從注釋上來分析,要讓SysTick跑起來使用這兩函數(shù)的確足夠了,但是想想哪里不對勁啊??咱的目的是做個延時程序,希望能夠精確的延時,并且咱隨時指定延時多久,這怎么還玩起中斷來了,不對,不對,這不靠譜(我說的不靠譜是和我們的目的不靠譜,并非這個庫不靠譜,哈哈!),唉!沒辦法,只能對ST的攻城獅說,你不給咱寫好,咋就自己玩了!哈哈!那砸門就自己玩!

那么怎么玩呢???這就是為毛在開篇的時候一大堆廢話談《Cortex-M0編程手冊》的原因了,咱自己玩,得靠它啊!OK!繼續(xù)--0------>

看到上圖,我想再不明白的人也要明白了!這就清清楚楚的介紹了SysTick的使用了哈!(翻譯就算了,水平太菜了,不惡心人了)。

繼續(xù)曬圖:

哈哈哈!看到了沒??SysTick的寄存器被我看到了!既然看到了寄存器,那要搞它就不難了。哈哈!繼續(xù)再往下!再往下!再往下!

嘎嘎!你看到的沒錯,你沒眼花,這里清清楚楚的說明了SySTick的第一個寄存器STK_CSR的功能和使用了。東西比較少,我就解釋一下:

Bit 0 ----- 0位,SysTick的開關(guān),置1使能

Bit 1-----1位,SysTick的異常開關(guān),其實就是中斷開關(guān),置1,當(dāng)SysTick計時到0時,產(chǎn)生中斷

注意:SysTick數(shù)山羊的方式和咱小時候玩的不太一樣,人家要倒著數(shù),到0說明完成一次數(shù)山羊

Bit 2-----2位,SysTick的時鐘資源選擇,置0,使用外部參考時鐘;置1,使用處理器的時鐘

Bit 16---16位,定時器數(shù)山羊數(shù)到0的時候,返回1

這個寄存器就這么愉快的搞定了!!!哈哈哈哈!繼續(xù)裝B!

看到這個,就知道了,STK_RVR寄存器就是SysTick的裝載寄存器了,用來裝山羊的個數(shù)的嘛,哈哈!但是注意哦,因為SysTick是24位的定時器(前面文檔有介紹),所以別越界了哦!越界就像是用個吃飯的碗來裝一桶水,肯定裝不完啦!肯定會溢出啦!不懂啥事溢出的話,就想想水從碗里溢出來的現(xiàn)象哈哈!只是在這里是數(shù)據(jù)溢出而言!

所以這個寄存器沒啥好解釋的了(沒解釋也廢話了半天。。。汪汪)!

看看下一個:

看標(biāo)題就知道了,SysTick的當(dāng)前計數(shù)值寄存器,想知道此時計數(shù)到哪里了,讀它就好了!

下一個!

SysTick的校準(zhǔn)定時器!!!!咱不校準(zhǔn),想校準(zhǔn)的童鞋自己看看!多么簡單的東西!

到這里,我們得到的信息是:

(1)我們需要操作的寄存器:STK_CSR、STK_RVR和STK_CVR

(2)寄存器的地址:如下圖

現(xiàn)在要干的第一件事是,我們應(yīng)該怎樣才能操作寄存器:

方法1:直接操作

在頭文件里直接定義這三個寄存器的物理地址(特別注意:寄存器是32位的),相應(yīng)操作寄存器的某一位只需要操作TK_CSR、STK_RVR和STK_CVR的相應(yīng)的某一位即可。就是這么簡單!

方法2:使用庫的定義

在core_m0.h文件中,有如下定義:

從注釋來看,它說這就是SysTick的寄存器結(jié)構(gòu)體!OK!怎么證明呢??

再往下:

有這么幾個信息:

(1)基地址為 SCS_BASE (0xE000E000UL) ,即基地址就是0xE000E000了

(2)SysTick的基地址為:(SCS_BASE + 0x0010UL),即為:0xE000E010 咦是不是和STK_CSR寄存器地址一樣了呢??對的,就是一樣的,再往下

(3)宏#define SysTick ((SysTick_Type *) SysTick_BASE ),首先SysTick的基地址SysTick_BASE被強制轉(zhuǎn)換為結(jié)構(gòu)體SysTick_Type類型的指針(也就是以這個地址為起點sizeof(SysTick_Type)大小的空間成為這個結(jié)構(gòu)體類型),然后定義成宏SysTick,所以宏SysTick就成為了SysTick_Type的指針。再往下分析:

(4)分析得下圖:

SysTick的地址就是0xE000E010了,而根據(jù)結(jié)構(gòu)體的貼心,第一個成員的地址和結(jié)構(gòu)體的地址值是相等的,所以就有了上圖(要是不懂的話,建議好好的去補補C語言,把基本功打扎實了,沒點功力腫么能玩轉(zhuǎn)物理地址呢??),所以,結(jié)構(gòu)體的成員和SysTick的寄存器就對應(yīng)上了。哈哈!其實ST的庫里面的寄存器的結(jié)構(gòu)都是這么干的,定義寄存器的方法都是一樣的!

當(dāng)然,喜歡玩寄存器的童鞋,我建議就應(yīng)該用以上的方法1的方法,這才是玩寄存器啊,!直接使用ST定義好的結(jié)構(gòu),多沒意思!!哈哈!!

好的!完事具備!只欠程序了!如下:

首先,先定義兩個本文件全局變量(記住這兩個全局變量只適用在本文件),分別是:fac_ms和fac_us,啥意思呢??它倆就是分別用來記錄1ms和1us時間內(nèi)SysTick能計的數(shù)。

變量定義玩了,就是初始化SysTick了!其實初始化SysTick就是一句話SysTick->CTRL = 0xfffffffb;,就是操作TK_CSR寄存器。至于為毛是這個值,那就自己看手冊了!

但是,其實適用庫函數(shù)接口也是可以的:就是這個:

void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource),這個函數(shù)的注釋是選擇SysTick的時鐘,其實就是初始化了,但是必須注意:參數(shù)必須是:SysTick_CLKSource_HCLK_Div8即HCLK的8分頻,證據(jù)就是前面的時鐘樹。但是將到這里咱不放看看這個函數(shù)的原型,

從函數(shù)中,也可以看出也是操作TK_CSR寄存器,因為參數(shù)必須是SysTick_CLKSource_HCLK_Div8,所以我們可以看看SysTick_CLKSource_HCLK_Div8的定義值如何:

看到?jīng)]:SysTick_CLKSource_HCLK_Div8的值也是0xFFFFFFFB

OK!初始化解決了!那么,這個初始化函數(shù)還有一個參數(shù),干啥的呢??其實就是系統(tǒng)時鐘啦!比如,咱的系統(tǒng)時鐘已經(jīng)配置成48MHz,那么調(diào)用的時候,直接SysTick_Init(48);即可,其實這個參數(shù)就是用來計算fac_ms和fac_us的值的,公式如下:

SysTick的時鐘:Fsystick = HCLK/8

SysTick計數(shù)一次的時間:Tsystick = 1/Fsystick

有了以上兩個公式(對于哪來的公式,別問我,問手冊去),那么計算fac_ms和fac_us的值就不難了!哈哈!OK!初始化結(jié)束。

咱們來個毫秒延時:

上面函數(shù)的意思就是:延時nms,比如需要延時100毫秒,就調(diào)用:delay_ms(100);即可。

那么實現(xiàn)是怎么樣的呢??

其實在編程手冊里面就教了我們怎么使用:

哈哈!人家明明白白的告訴了咱怎么使用,并且列出了1,2,3,那咱就不能客氣了!哈哈!

1.將計數(shù)值裝載到裝載寄存器

2.清空計數(shù)器

3.計數(shù)開始

4.等等計數(shù)到達

5.關(guān)閉計數(shù)器

6.清空計數(shù)器

過程就如上6步了。

注意一點啊:SysTick->CTRL = 0x01;開啟計時器時是對寄存器直接賦值,而不是操作某一位啊!所以這樣的話,是不會產(chǎn)生中斷的!因為中斷被關(guān)了啊!

OK!毫秒延時就這樣!!

下面就是微秒延時了!哈哈!

毫秒延時都講的這么清楚了,微秒延時就不說了,都是一個媽生的!過程沒啥說的!

來看看咱怎么調(diào)用吧!

調(diào)用就如上圖了!記住哦,先配置好系統(tǒng)時鐘哦!要是順序搞反了,搞不出來就該打屁屁了哦!哈哈哈!

縱觀IT界,一個簡單的東西內(nèi)說個20頁可能也就是我這種逗逼了!哈哈!不過呢!我只是想解決一些初學(xué)者迷茫或者吐血的問題!高手的問題咱不敢解決!

 
 

上一篇:STM32F030 Nucleo-多樣的SPI通信之Master標(biāo)準(zhǔn)模式-SPIFlash讀寫

下一篇:udev機制

熱點文章推薦
華清學(xué)員就業(yè)榜單
高薪學(xué)員經(jīng)驗分享
熱點新聞推薦
前臺專線:010-82525158 企業(yè)培訓(xùn)洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權(quán)所有 ,京ICP備16055225號-5京公海網(wǎng)安備11010802025203號

回到頂部

主站蜘蛛池模板: xiazai| 艺术影院| 谁的青春不迷茫 电影| 美女x| 坐月子吃什么| 搜狐视频官网| 海滩修学旅程行| 猛鬼差馆 电影| 黑暗森林 电影| ..k| 第一次美国电影| 青山知可子最经典十部电视剧| 少年派3免费观看完整版电视剧| 蒋锐| 富含维生素c的水果和蔬菜| 无常电影| 悦时光电影完整版免费观看| 对称度| 名字简写设计| 1988年英国的白蛇传说| 第九区电影免费观看完整版| 丁尼| 42个奥特曼大全图| 电影二十条剧情介绍| 风花电影完整版免费观看| 闺房外的春天| 搜狐网站官网| 徐若晗个人简历| 第五单元初试身手| 低糖食物一览表| 爱情岛视频论坛| 阿尔法变频器说明书| 柏拉图的电影| 电影继母劳拉| 玉匣记全文免费| 洛可希佛帝| 台湾1895| 满天星的电影都有哪些| douying.com| 都市频道今日节目表| 《密爱》|