STM32單片機學(xué)習(xí)
《STM32單片機學(xué)習(xí)》由會員分享,可在線閱讀,更多相關(guān)《STM32單片機學(xué)習(xí)(12頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1、 前言:從51開始,單片機玩了很長時間了,有51,PIC,AVR等等,早就想跟潮流玩玩ARM,但一直沒有開始,原因-----不知道玩了ARM可以做什么(對我自己而言)。如果為學(xué)習(xí)而學(xué)習(xí),肯定學(xué)不好。然后cortex-m3出來了,據(jù)說,這東西可以替代單片機,于是馬上開始關(guān)注。也在第一時間開始學(xué)習(xí),可惜一開始就有點站錯了隊,選錯了型(仍是對我自己而言)。我希望這種芯片應(yīng)該是滿大街都是,隨便哪里都可以買得到,但我選的第一種顯然做不到。為此,大概浪費了一年多時間吧,現(xiàn)在,回到對我來說是正確的道路上來啦,邊學(xué)邊寫點東西。 這里寫的是我的學(xué)習(xí)的過程,顯然,很多時候會是不全面的,不系統(tǒng)的,感悟式
2、的,甚至有時會是錯誤的,有些做法會是不專業(yè)的。那么,為什么我還要寫呢?這是一個有趣的問題,它甚至涉及到博客為什么要存在的問題。顯然,博客里面的寫的東西,其正確性、權(quán)威性大多沒法和書比,可為什么博客會存在呢?理由很多,我非專家,只說我的感慨。 我們讀武俠小說,總會有一些創(chuàng)出獨門功夫的宗師,功夫極高,然后他的弟子則基本上無法超越他。我在想,這位宗師在創(chuàng)造他自己的獨門功夫時,必然會有很多的次的曲折、彎路、甚至失敗,會浪費他的很多時間,而他教給弟子時,則已去掉了這些曲折和彎路,當(dāng)然更不會把失敗教給弟子,按理說,效率應(yīng)該更高,可是沒用,弟子大都不如師。為什么呢?也許知識本身并不是最重要的,獲取知識
3、的過程才是最重要的?也許所謂的知識,并不僅僅是一條條的結(jié)論,而是附帶著很多說不清道不明的東西?如植物的根,一條主根上必帶有大量的小小的觸須? 閑話多了些,就權(quán)當(dāng)前言了。下面準(zhǔn)備開始。 一、條件的準(zhǔn)備 我的習(xí)慣,第一步是先搭建一個學(xué)習(xí)的平臺。原來學(xué)51,PIC,AVR時,都是想方設(shè)法自己做些工具,實驗板之類,現(xiàn)在人懶了,直接購買成品了。 硬件電路板:火牛板 軟件:有keil和iar可供選擇。網(wǎng)上的口水仗不少,我選keil,理由很簡單,這個我熟。目前要學(xué)的知識中,軟、硬件我都不熟,所以找一個我有點熟的東西就很重要。在我相當(dāng)熟練之前,肯定不會用到IAR,如果真的有一天不
4、得不用IAR,相信學(xué)起來也很容易,因為這個時候硬件部分我肯定很熟了,再加上有 keil的基礎(chǔ),所以應(yīng)該很容易學(xué)會了。 調(diào)試工具:JLINK V8。這個不多說了,價格便宜又好用,就是它了。 二、熱身 細(xì)細(xì)端詳,做工精良,尤其那上面的3.2吋屏,越看越喜歡。接下來就是一陣折騰了,裝JLINK軟件,給板子通電,先試試JLINK能不能與電腦和板子通信上了。真順,一點問題也沒有。于是準(zhǔn)備將附帶的程序一個一個地寫進去試一試。一檢查,大部分例子的HEX文件并沒有給出,這要下一步自己生成,但是幾個大工程的例子都有HEX文件,如MP3,如UCCGI測試等,寫完以后觀察程序運行的效果。因為之前也做過
5、彩屏的東西,知道那玩藝代碼量很大,要流暢地顯示并不容,當(dāng)時是用AVR做的,在1.8吋屏上顯示一幅畫要有一段時間?,F(xiàn)在看起來,用STM32做的驅(qū)動顯示出來的畫面還是很快的,不過這里顯示的大部分是自畫圖,并沒有完整地顯示一整幅的照片,所以到底快到什么程度還不好說,看來不久以后這可以作為一個學(xué)習(xí)點的。 一個晚上過去了,下一篇就是要開始keil軟件的學(xué)習(xí)了。 三、開始編程 硬件調(diào)通后,就要開始編程了。 編程的方法有兩種,一種是用st提供的庫,另一種是從最底層開始編程,網(wǎng)上關(guān)于使用哪種方法編程的討論很多,據(jù)說用庫的效率要低一些。但是用庫編程非常方便,所以我還是從庫開始啦。
6、庫是ST提供的,怎么說也不會差到哪里,再說了,用32位ARM的話,開發(fā)的觀念也要隨之改變一點了。 說說我怎么學(xué)的吧。 找個例子,如GPIO,可以看到其結(jié)構(gòu)如下: SOURCE(文件夾) - APP(文件夾) -CMSIS(文件夾) -STM32F10x_StdPeriph_Driver(文件夾) Lis(文件夾) OBJ(文件夾) 其中SOURCE中保存的是應(yīng)用程序,其中又有好多子文件夾,而CMSIS文件夾中和STM32F10x_StdPeriph_Driver文件夾中是ST提供的庫,這樣,如果要做新的工程只要將這個文件夾整個復(fù)制過來就行,
7、其中APP中保存自己的代碼。 因為我們用51單片機時一般比較簡單,有時就一個文件,所以通常不設(shè)置專門的輸出文件夾,而這里做開發(fā),通常會有很多個文件加入一個工程中,編譯過程中會產(chǎn)生很多中間文件,因此設(shè)置專門的文件夾LIS和OBJ用來保存中間文件。 下面就將設(shè)置簡單描述一下。 將復(fù)到過來的GPIO根目錄下的所有文件刪除,因為我們要學(xué)著自己建立工程。 用菜單Project--》New uVision Porject.。.建立新的工程,選擇目標(biāo)器件為STM32103VC,這個過程與建立51單片機的工程沒有什么區(qū)別,這里就偷點懶,不上圖了。接下來看一看怎么設(shè)置。 點
8、那個品字形,打開對話框 這里就給個圖了,相信有一定操作基礎(chǔ)的人應(yīng)該會用。順便提一下,原來用VC或者IAR時總覺得它們的一個功能:就是建立一個是Debug組和Release組,這個功能挺好的,從這個圖可在Keil里也是一樣可以建的。 將剛才那個文件夾圖中CMSIS中的文件加入CMSIS組,一共3個,其中\(zhòng)Source\CMSIS\Core\CM3有兩個C語言源程序文件全部加入,另外還有一個在 \Source\CMSIS\Core\CM3\startup\arm文件夾中,這個文件夾中有4個.s文件, 我們選擇其中的 startup_stm32f10x_hd.s文件。這是根
9、據(jù)項目所用CPU來選擇的,我們用的CPU是103VC的,屬于高密度的芯片,所以選這個。 至于LIB中的文件,就在這兒:\Source\STM32F10x_StdPeriph_Driver\src啦。這里有很多個文件,把什么文件加進去呢?怕麻煩的話,把所有文件全部加進去,這并不會增加編譯后的代碼量,但會增加很多的編譯時間。 接下來設(shè)定目標(biāo)輸出文件夾。上面這個圖怎么出來的就不說啦,單擊“Select Foler for Objects?!?,在彈出來的對話框中選擇OBJ文件夾。 同樣方法,選擇List文件的輸出文件夾。 設(shè)置好后,如果直接編譯是不行的,會出錯。
10、還需要提供頭文件所在位置。單擊c/C++標(biāo)簽頁。 第一次進入時Include Paths 文本框中是空白的,點擊其后的按鈕打開對話框,增加相應(yīng)的路徑 這樣路徑就設(shè)好了。單擊OK,回到上一界面,然后再單擊OK,退出設(shè)置,即可編譯、鏈接。 下一會要試一試新的3.12版的庫效果如何了。 升級庫 光盤中所帶的例子是3.10的,另外還有一個3.12的,我 試著將3.12的庫替代原來的庫,還真有問題,下面就簡述問題及解決方法。 ?。?)將庫文件解壓 庫文件名是:stm32f10x_stdperiph_lib.zip,解壓后放在任意一個文件夾中。 ?。?/p>
11、2)由于原作者做了很好的規(guī)劃,每一個項目中都分成三個文件夾,并且在source文件夾中又做了3個文件夾,其中APP文件夾是放自己寫的文件的,其他的兩個是從庫中復(fù)制過來的,因此,想當(dāng)然地把3.1.2版本中相同的兩個文件夾: CMSIS和STM32F10x_StdPeriph_Driver直接復(fù)制過來,以為一切OK,結(jié)果一編譯,出來一堆錯誤。 其中有錯誤: Source\App\main.c(7): error: #20: identifier “GPIO_InitTypeDef” is undefined 。..。 還有大量的警告: Source\STM32F
12、10x_StdPeriph_Driver\src\stm32f10x_flash.c(130): warning: #223-D: function “assert_param” declared implicitly 看了看,在APP文件夾中還有一些不屬于自己的東西: stm32f10x_conf.h,stm32f10x_it.h,stm32f10x_it.c,打開一看,果然是3.10版本的,沒說的,換。。。。,找到STM32F10x_StdPeriph_Lib_V3.1.2\Project\Template文件夾,用里面的同樣的文件替換掉這幾個文件,這回應(yīng)該萬事大吉了吧。
13、 再一看,依然如故,,沒辦法了,只好細(xì)細(xì)研究了。通過觀察,發(fā)現(xiàn)原來可以編譯通過的工程,在main.c下面掛滿了.h文件,而這個通不過的,則少得很。 這是編譯能通過的工程 這是編譯通不過的工程 顯然,有些文件沒有被包含進來。一點一點跟蹤,發(fā)現(xiàn)大部分的頭文件都包含在stm32f10x_conf.h中,而這個文件又出現(xiàn)在stm32f10x.h中,其中有這樣的一行: #ifdef USE_STDPERIPH_DRIVER #include “stm32f10x_conf.h” #endif 看來,是這個USE_STDPERIPH_DRIVER沒有被
14、定義啊,于是,人為地去掉條件: //#ifdef USE_STDPERIPH_DRIVER #include “stm32f10x_conf.h” //#endif 再次編譯,果然就OK了。可是,可是,也不能就這么去掉啊,怎么辦呢?萬能的網(wǎng)啊,一搜果然就有了。 到設(shè)置 C/C++頁面 在那個define中加入“USE_STDPERIPH_DRIVER,STM32F10X_HD” 當(dāng)然,去掉條件編譯前面的注釋,回到原樣。 再次編譯,一切順利??墒?,原來的工程例子也沒有加這個啊,怎么回事呢?再次打開原來的例子,找到stm32f10x.h,可以
15、看到有這么一行: 而新的stm32f10x.h中則是這樣的: 原來那個3.1.0版的stm32f10x.h被人為地修改了一下,所以,不在define中定義也不要緊,而新升級的3.1.2則不行了。 至此,簡單的升級搞定。 內(nèi)存學(xué)習(xí) ARM中的RO、RW和ZI DATA 一直以來對于ARM體系中所描述的RO,RW和ZI數(shù)據(jù)存在似是而非的理解,這段時間對其仔細(xì)了解了一番,發(fā)現(xiàn)了一些規(guī)律,理解了一些以前書本上有的但是不理解的東西,我想應(yīng)該有不少人也有和我同樣的困惑,因此將我的一些關(guān)于RO,RW和ZI的理解寫出來,希望能對大家有所幫助。 要了解R
16、O,RW和ZI需要首先了解以下知識: ARM程序的組成 此處所說的“ARM程序”是指在ARM系統(tǒng)中正在執(zhí)行的程序,而非保存在ROM中的bin映像(image)文件,這一點清注意區(qū)別。 一個ARM程序包含3部分:RO,RW和ZI RO是程序中的指令和常量 RW是程序中的已初始化變量 ZI是程序中的未初始化的變量 由以上3點說明可以理解為: RO就是readonly, RW就是read/write, ZI就是zero ARM映像文件的組成 所謂ARM映像文件就是指燒錄到ROM中的bin文件,也稱為image文件。以下用Imag
17、e文件來稱呼它。 Image文件包含了RO和RW數(shù)據(jù)。 之所以Image文件不包含ZI數(shù)據(jù),是因為ZI數(shù)據(jù)都是0,沒必要包含,只要程序運行之前將ZI數(shù)據(jù)所在的區(qū)域一律清零即可。包含進去反而浪費存儲空間。 Q:為什么Image中必須包含RO和RW? A:因為RO中的指令和常量以及RW中初始化過的變量是不能像ZI那樣“無中生有”的。 ARM程序的執(zhí)行過程 從以上兩點可以知道,燒錄到ROM中的image文件與實際運行時的ARM程序之間并不是完全一樣的。因此就有必要了解ARM程序是如何從ROM中的image到達實際運行狀態(tài)的。 實際上,RO中的指令至少應(yīng)該有這
18、樣的功能: 1. 將RW從ROM中搬到RAM中,因為RW是變量,變量不能存在ROM中。 2. 將ZI所在的RAM區(qū)域全部清零,因為ZI區(qū)域并不在Image中,所以需要程序根據(jù)編譯器給出的ZI地址及大小來將相應(yīng)得RAM區(qū)域清零。ZI中也是變量,同理:變量不能存在ROM中 在程序運行的最初階段,RO中的指令完成了這兩項工作后C程序才能正常訪問變量。否則只能運行不含變量的代碼。 說了上面的可能還是有些迷糊,RO,RW和ZI到底是什么,下面我將給出幾個例子,最直觀的來說明RO,RW,ZI在C中是什么意思。 1; RO 看下面兩段程序,他們之間差了一條語句,這條語句就
19、是聲明一個字符常量。因此按照我們之前說的,他們之間應(yīng)該只會在RO數(shù)據(jù)中相差一個字節(jié)(字符常量為1字節(jié))。 Prog1: #include 《stdio.h》 void main(void) { ; } Prog2: #include 《stdio.h》 const char a = 5; void main(void) { ; } Prog1編譯出來后的信息如下: =======================================================================
20、========= Code RO Data RW Data ZI Data Debug 948 60 0 96 0 Grand Totals ================================================================================ Total RO Size(Code + RO Data) 1008 ( 0.98kB) Total RW Size(RW Data + ZI Data) 96 ( 0.09kB) Total ROM Size(Code + RO Data + RW Dat
21、a) 1008 ( 0.98kB) ================================================================================ Prog2編譯出來后的信息如下: ================================================================================ Code RO Data RW Data ZI Data Debug 948 61 0 96 0 Grand Totals =======================
22、========================================================= Total RO Size(Code + RO Data) 1009 ( 0.99kB) Total RW Size(RW Data + ZI Data) 96 ( 0.09kB) Total ROM Size(Code + RO Data + RW Data) 1009 ( 0.99kB) ================================================================================
23、 以上兩個程序編譯出來后的信息可以看出: Prog1和Prog2的RO包含了Code和RO Data兩類數(shù)據(jù)。他們的唯一區(qū)別就是Prog2的RO Data比Prog1多了1個字節(jié)。這正和之前的推測一致。 如果增加的是一條指令而不是一個常量,則結(jié)果應(yīng)該是Code數(shù)據(jù)大小有差別。 2; RW 同樣再看兩個程序,他們之間只相差一個“已初始化的變量”,按照之前所講的,已初始化的變量應(yīng)該是算在RW中的,所以兩個程序之間應(yīng)該是RW大小有區(qū)別。 Prog3: #include 《stdio.h》 void main(void) { ; } Pro
24、g4: #include 《stdio.h》 char a = 5; void main(void) { ; } Prog3編譯出來后的信息如下: ================================================================================ Code RO Data RW Data ZI Data Debug 948 60 0 96 0 Grand Totals ==================================================
25、============================== Total RO Size(Code + RO Data) 1008 ( 0.98kB) Total RW Size(RW Data + ZI Data) 96 ( 0.09kB) Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB) ================================================================================ Prog4編譯出來后的信息如下: ======
26、========================================================================== Code RO Data RW Data ZI Data Debug 948 60 1 96 0 Grand Totals ================================================================================ Total RO Size(Code + RO Data) 1008 ( 0.98kB) Total RW Size(RW Data
27、+ ZI Data) 97 ( 0.09kB) Total ROM Size(Code + RO Data + RW Data) 1009 ( 0.99kB) ================================================================================ 可以看出Prog3和Prog4之間確實只有RW Data之間相差了1個字節(jié),這個字節(jié)正是被初始化過的一個字符型變量“a”所引起的。 3; ZI 再看兩個程序,他們之間的差別是一個未初始化的變量“a”,從之前的了解中,應(yīng)該可以推測,這兩個程序之間應(yīng)該
28、只有ZI大小有差別。 Prog3: #include 《stdio.h》 void main(void) { ; } Prog4: #include 《stdio.h》 char a; void main(void) { ; } Prog3編譯出來后的信息如下: ================================================================================ Code RO Data RW Data ZI Data Debug 948
29、 60 0 96 0 Grand Totals ================================================================================ Total RO Size(Code + RO Data) 1008 ( 0.98kB) Total RW Size(RW Data + ZI Data) 96 ( 0.09kB) Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB) =================================
30、=============================================== Prog4編譯出來后的信息如下: ================================================================================ Code RO Data RW Data ZI Data Debug 948 60 0 97 0 Grand Totals =============================================================================
31、=== Total RO Size(Code + RO Data) 1008 ( 0.98kB) Total RW Size(RW Data + ZI Data) 97 ( 0.09kB) Total ROM Size(Code + RO Data + RW Data) 1008 ( 0.98kB) ================================================================================ 編譯的結(jié)果完全符合推測,只有ZI數(shù)據(jù)相差了1個字節(jié)。這個字節(jié)正是未初始化的一個字符型變量“a”所引起的。
32、 注意:如果一個變量被初始化為0,則該變量的處理方法與未初始化華變量一樣放在ZI區(qū)域。 即:ARM C程序中,所有的未初始化變量都會被自動初始化為0。 總結(jié): 1; C中的指令以及常量被編譯后是RO類型數(shù)據(jù)。 2; C中的未被初始化或初始化為0的變量編譯后是ZI類型數(shù)據(jù)。 3; C中的已被初始化成非0值的變量編譯后市RW類型數(shù)據(jù)。 附: 程序的編譯命令(假定C程序名為tst.c): armcc -c -o tst.o tst.c armlink -noremove -elf -nodebug -info totals -info sizes -map -list aa.map -o tst.elf tst.o 編譯后的信息就在aa.map文件中。 ROM主要指:NAND Flash,Nor Flash RAM主要指:PSRAM,SDRAM,SRAM,DDRAM
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年防凍教育安全教育班會全文PPT
- 2025年寒假安全教育班會全文PPT
- 初中2025年冬季防溺水安全教育全文PPT
- 初中臘八節(jié)2024年專題PPT
- 主播直播培訓(xùn)提升人氣的方法正確的直播方式如何留住游客
- XX地區(qū)機關(guān)工委2024年度年終黨建工作總結(jié)述職匯報
- 心肺復(fù)蘇培訓(xùn)(心臟驟停的臨床表現(xiàn)與診斷)
- 我的大學(xué)生活介紹
- XX單位2024年終專題組織生活會理論學(xué)習(xí)理論學(xué)習(xí)強黨性凝心聚力建新功
- 2024年XX單位個人述職述廉報告
- 一文解讀2025中央經(jīng)濟工作會議精神(使社會信心有效提振經(jīng)濟明顯回升)
- 2025職業(yè)生涯規(guī)劃報告自我評估職業(yè)探索目標(biāo)設(shè)定發(fā)展策略
- 2024年度XX縣縣委書記個人述職報告及2025年工作計劃
- 寒假計劃中學(xué)生寒假計劃安排表(規(guī)劃好寒假的每個階段)
- 中央經(jīng)濟工作會議九大看點學(xué)思想強黨性重實踐建新功