色yeye在线视频观看_亚洲人亚洲精品成人网站_一级毛片免费播放_91精品一区二区中文字幕_一区二区三区日本视频_成人性生交大免费看

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 講師博文 > STM32F030 Nucleo-做個準確的延時SysTick

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

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

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

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

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

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

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

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

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

(1)SysTick就是內核系統定時器(不管它,咱還是叫滴答定時器)

(2)SysTick的時鐘源來自HCLK

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

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

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

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

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

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

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

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

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

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

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

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

從這個圖我們可以得知,第一次出這個文檔的時間,而且從未修改過!哈哈 !不管了!談談感受些。

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

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

第一件事,找到庫中相應的操作函數接口,所以我在keil中全工程搜索了一下,結果如下:

從上圖可以看出了,只看到了兩個與SysTick相關的函數(我用紅框標出了),分別是:void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)函數和__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)函數,(在Linux中__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)這種類型的函數叫內聯函數,不知道這是不是這樣叫),其中,void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)函數的作用,是是選擇SysTick的時鐘和初始化SysTick(從注釋和函數名就可以看出來了)。__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)函數就是“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跑起來使用這兩函數的確足夠了,但是想想哪里不對勁啊??咱的目的是做個延時程序,希望能夠精確的延時,并且咱隨時指定延時多久,這怎么還玩起中斷來了,不對,不對,這不靠譜(我說的不靠譜是和我們的目的不靠譜,并非這個庫不靠譜,哈哈!),唉!沒辦法,只能對ST的攻城獅說,你不給咱寫好,咋就自己玩了!哈哈!那砸門就自己玩!

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

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

繼續曬圖:

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

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

Bit 0 ----- 0位,SysTick的開關,置1使能

Bit 1-----1位,SysTick的異常開關,其實就是中斷開關,置1,當SysTick計時到0時,產生中斷

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

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

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

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

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

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

看看下一個:

看標題就知道了,SysTick的當前計數值寄存器,想知道此時計數到哪里了,讀它就好了!

下一個!

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

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

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

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

現在要干的第一件事是,我們應該怎樣才能操作寄存器:

方法1:直接操作

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

方法2:使用庫的定義

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

從注釋來看,它說這就是SysTick的寄存器結構體!OK!怎么證明呢??

再往下:

有這么幾個信息:

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

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

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

(4)分析得下圖:

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

當然,喜歡玩寄存器的童鞋,我建議就應該用以上的方法1的方法,這才是玩寄存器啊,!直接使用ST定義好的結構,多沒意思!!哈哈!!

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

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

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

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

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

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

看到沒:SysTick_CLKSource_HCLK_Div8的值也是0xFFFFFFFB

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

SysTick的時鐘:Fsystick = HCLK/8

SysTick計數一次的時間:Tsystick = 1/Fsystick

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

咱們來個毫秒延時:

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

那么實現是怎么樣的呢??

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

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

1.將計數值裝載到裝載寄存器

2.清空計數器

3.計數開始

4.等等計數到達

5.關閉計數器

6.清空計數器

過程就如上6步了。

注意一點�。篠ysTick->CTRL = 0x01;開啟計時器時是對寄存器直接賦值,而不是操作某一位啊!所以這樣的話,是不會產生中斷的!因為中斷被關了啊!

OK!毫秒延時就這樣!!

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

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

來看看咱怎么調用吧!

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

縱觀IT界,一個簡單的東西內說個20頁可能也就是我這種逗逼了!哈哈!不過呢!我只是想解決一些初學者迷�;蛘咄卵膯栴}!高手的問題咱不敢解決!

 
 

上一篇:STM32F030 Nucleo-多樣的SPI通信之Master標準模式-SPIFlash讀寫

下一篇:udev機制

华清图书馆

0元电子书,限时免费申领

10本华清图书PDF版

扫码关注华清远见公众号
自动回复“2”,即可申领!
熱點文章推薦
華清學員就業榜單
高薪學員經驗分享
熱點新聞推薦
前臺專線:010-82525158 企業培訓洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,京ICP備16055225號-5,京公海網安備11010802025203號

回到頂部

主站蜘蛛池模板: 高中生高潮抽搐喷出白浆视频 | 久久久精品人妻一区二区三区 | 色吊丝AV中文字幕 | 脱了老师内裤猛烈进入 | 精品无码一区二区三区爱与 | 老子影院午夜精品无码 | 欧美变态杂交xxxx | 激情综合丁香五月 | 人妻aⅴ中文字幕 | 18成禁人视频免费网站 | 爱色av | 1314成人网| 无码人妻精品中文字幕免费东京热 | 天天天天做夜夜夜做 | 艳妇臀荡乳欲伦69调教视频 | 夜夜爽妓女8888视频免费观看 | 成人av一区二区三区在线观看 | 伊人大杳焦在线 | 在线a亚洲v天堂网2018 | 日本黄网站色大片免费观看 | 永久免费av无码国产网站 | 免费无码又爽又刺激动态图 | av片一区二区| 亚洲中文字幕婷婷在线 | 老司机午夜av | 美女视频黄频A免费 | 午夜福利啪啪体验区 | 无码国产玉足脚交极品网站 | 亚洲欧美国产成人久久 | 色婷婷欧美在线播放内射 | 两个女人互添下身高潮视频 | 李思思一级毛片 | 国产真实愉拍系列在线视频 | 狼群社区WWW在线中文 | 欧美BBBWBBWBBWBBW 91久久精品国产91久久性色也 | 久久天堂综合亚洲伊人hd妓女 | 最新国产免费AV片在线观看 | 精品国产不卡在线观看免费 | 国产佗精品一区二区三区 | 亚洲国产日韩欧美综合A | 真人做爰高潮全过程免费视看 |