最近迫于找工作的壓力,我不得不加快嵌入式學習的步伐,不再和AVR、PIC8位機糾纏了,開始學習32位單片機。開發環境如下:STM32F103RBT6+MDK+JLINK。今天打開了第一個程序:流水燈。程序內容很簡單,只是這個工程的結構看上去很是復雜,不像之前一個工程里就那么幾個C源程序和頭文件。因此,今天很有必要討論一下這個工程的結構,相當于一個程序的骨架。 其實認真研究一下,會發現例程工程和之前我們使用編寫51單片機程序用的工程大同小異。至于剛開始感覺這個結構很復雜,我的原因是之前編寫51程序是將所有的代碼幾乎都寫進主源程序里,頭文件和多個源程序的使用很少。開發STM32時,因為有了官方的封裝的外圍器件驅動代碼庫,這樣我就不得不使用頭文件和多個源程序,感覺不適應,只能說是少見多怪。其實想想,開發STM32的這種編程方式才是科學的。STM32的外圍器件驅動庫的作用其實就是將面向寄存器的操作封裝成為函數,這樣我們在編寫具體的應用程序的時候就可以直接調用這些函數,這樣,一方面降低編寫程序的難度,提高了編程的準確性,另一方面,也提高了程序的可讀性。在編程之前,我們必須將我們的要用到的外圍器件的驅動程序的頭文件(各種宏定義和寄存器操作函數的聲明)和源程序(宏定義和各種寄存器操作函數的實現)從頭到尾看一遍,這樣我們在編寫程序的時候心里才有數,知道用哪些宏定義的變量和函數。 說了這么多,回到工程結構上來。STM32的例程工程通常包含幾個組User,RVMDK,CMSIS,StdPeriph_Driver,DOC。在3.0.0版本的外圍器件驅動庫的例程工程中只有這些,在3.3.0和3.5.0的版本中,還有一個STM32_EVAL組,這個組的源程序和頭文件定義了一些與STM32自己的開發板相關一些變量,如果你用的不是這幾款開發板,這個組就可以刪去。 User組里放的是我們自己的編寫的源代碼和頭文件。 RVMDK組通常存放的是匯編啟動代碼。 CMSIS(Cortex Microcontroler Software InterfaceStandard)組放的時與Cortex-M3相關的文件,如core_cm3.c和system_stmf10x.c。 StdPeriph_Driver組里放的是外圍器件驅動代碼。用什么就向這個組里加入什么。例程中所有的驅動都加上了,這在我們實際使用時是沒有必要的。 DOC組放一些說明文本,這從側面說明說明一個問題,工程這種文件組織形式一方面有利于多個程序文件的編譯,另一方面則方便文件瀏覽。參與編譯的是工程里的啟動代碼(.s),源程序(.c)和頭文件(.h)。這些代碼經compiler編譯生成目標文件(.obj),然后linker再將這些目標文件鏈接成可執行文件(.hex)(在PC環境下則是.exe)。 有一點需要明確,工程結構僅僅是一個映射。它只是使程序看起來有條理。 這么多組只是浮云,在電腦里并不一定要有User,RVMDK,CMSIS,StdPeriph_Driver,DOC這些文件夾。這些組包含的文件都存放在外圍器件驅動壓縮包解壓出得到Library文件夾里。咱們只要把這些文件映射到工程中,并且在工程設置中將這些文件的路徑指明,這樣編譯器在編譯的時候遇到文件包含時就到這個指定路徑里找頭文件。另外,例程模板文件夾里還有兩個文件夾(List和Obj),它們兩個負責存放編譯鏈接過程中產生的中間文件。 我的第一個工程是這樣建立的: 1、建立一個文件夾,并命名為GPIO。 2、在這個文件夾下,新建文件夾,命名為RVMDK,然后在RVMDK文件夾下建立兩個文件夾,分別命名為Obj和List。 3、將例程STM32F10x_StdPeriph_Lib_V3.0.0\Project\Examples\GPIO\IOToggle中的所有文件復制到GPIO文件夾下,我們的程序就以其中的main.c為基礎。 4、接下來就該建立工程了,這和之前建立51工程一樣,我將工程建立在RVMDK文件夾下。 5、將之前提到那些工作組(User,RVMDK,CMSIS,StdPeriph_Driver,DOC)添加到工程中,我只添加了User,Startup,Driver這幾個工作組。然后把從STM32F10x_StdPeriph_Lib_V3.0.0\Project\Examples\GPIO\IOToggle復制的源程序添加到User工作組,把STM32F10x_StdPeriph_Lib_V3.0.0\Libraries\STM32F10x_StdPeriph_Driver\src中的源程序添加到Driver工作組,把STM32F10x_StdPeriph_Lib_V3.0.0\Libraries\CMSIS\Core\CM3下的源程序(.c)和STM32F10x_StdPeriph_Lib_V3.0.0\Libraries\CMSIS\Core\CM3\startup\arm的啟動文件(.s)添加到Startup工作組。這樣工程就搭建好了。 6、之前建立51工程時,工程的設置很簡單。不過在建立STM32工程時,工程的設置很重要。設置的主要內容是指明文件包含路徑。就是指示編譯器在編譯時遇到文件包含是應該到哪兒去尋找被包含的頭文件。如果路徑設置不對或者有遺漏,編譯器一旦找不到要找的頭文件,就會到keil自己的頭文件庫去尋找,由于頭文件庫的版本不配,就會編譯失敗,出現一堆令人頭疼的error。 7、 指示include路徑有 ..\ ..\..\..\Libraries\STM32F10x_StdPeriph_Driver\inc ..\..\..\Libraries\CMSIS\Core\CM3 注:..\ 的意思是工程文件所在路徑的上一層 .\ 則是工程文件的當前路徑,即工程文件所在的文件夾里。 我的工程文件夾GPIO位于與模板(template)相同的路徑(STM32F10x_StdPeriph_Lib_V3.0.0\Project)。 另外還要將USE_STDPERIPH_DRIVER,STM32F10X_MD寫入工程配置面板的C/C++選項面板的define欄里。 現在基本上大功告成了,保存后,按下F7,就 Build target 'GPIO'
compiling main.c...
compiling core_cm3.c...
compiling system_stm32f10x.c...
compiling misc.c...
compiling stm32f10x_gpio.c...
compiling stm32f10x_rcc.c...
linking...
Program Size: Code=2588 RO-data=268 RW-data=24ZI-data=608
FromELF: creating hex file...
".\Obj\GPIO.axf" - 0 Error(s), 0 Warning(s).
|