1. 第一個工程 翻轉(zhuǎn)引腳
上一篇文章我們詳細介紹了 STM32F030 從復位時取得復位向量,系統(tǒng)初始化,然后跳轉(zhuǎn)到 main( ) 函數(shù)的過程。下面我們結(jié)合一個最簡單的例子,對 Cube 庫的使用做一個簡單的介紹。我們用 Keil 打開下面這個工程:STM32Cube_FW_F0_V1.11.0ProjectsSTM32F030R8-NucleoExamplesGPIOGPIO_IOToggleMDK-ARMProject.uvprojx
編譯下載運行此代碼,會看到一個 LED燈(連至MCU的 PA5引腳)不停地閃爍。為了完成這個簡單的功能,我們看到這個工程里包含了不少文件:
如果是初次用這種庫的方式做開發(fā),乍一看還真感覺有點亂。不過讓我們一個一個看一下這些文件,理清它們的關系后就會體會到這種方式的巨大優(yōu)點。
2. 文件分類解釋
工程里的文件分為五大類:啟動代碼,M0內(nèi)核初始化,驅(qū)動,板級支持包(BSP),用戶代碼。一般來說我們開發(fā)應用程序,主要關注用戶代碼文件就行了。如果硬件電路板做了改動,則修改BSP里的內(nèi)容。在早期的單片機開發(fā)中,芯片內(nèi)資源很少,通常的情況是一個工程師就從硬件到軟件編程都做了,是沒有 BSP(Board Support Package)這種概念的。BSP概念來源于較復雜的CPU系統(tǒng)的開發(fā),一般是廠家設計主板,并提供 BSP(包含啟動代碼,驅(qū)動,Bootloader等)。我們這里的 BSP 概念稍有不同,它是指對某一塊兒以 MCU 為核心的電路板的支持代碼包。啟動代碼,內(nèi)核初始化和驅(qū)動,沒有包含在內(nèi)。BSP會調(diào)用驅(qū)動層的代碼。對于 STM32 Nucleo 這塊兒開發(fā)板來說,板上資源很少,所以BSP只提供了相應的按鍵(BUTTON)和指示燈(LED)支持代碼。里面的ADC,SPI,LCD等代碼是支持其它板子的,可以先忽略。
啟動代碼
為理解匯編代碼,我們先熟悉一下這些偽指令:
ALIGN 變量或代碼對齊。如:
ALIGN = 3 以8(2的3次方)字節(jié)對齊。
EQU 給標號賦值。如:
Stack_SizeEQU 0x400;
DCD 分配1個或多個字(words)的內(nèi)存空間。如:
Data DCD 1,5,8; 定義3個字并賦值為 1,5 和 8。
AREA 定義一個代碼或數(shù)據(jù)段(section),命名并指定屬性。如:
AREA Func01, CODE, READONLY;
定義了一個名字為 Func01 的只讀代碼段。
SPACE 保留一段空間并初始化為 0。如:
Data SPACE 100; 為 Data 保留 100個字節(jié)初始化為 0 的內(nèi)存空間。
IMPORT 導入其它文件中的標號,以在當前文件中引用。如:
IMPORT SystemInit
LDR R0, =SystemInit
BLX R0
從文件 system_stm32f0xx.c 中導入 SystemInit 這個函數(shù)并調(diào)用。
EXPORT 導出能被連接器(Linker)識別的標號。從ASM文件導出的標號可以在C中引用。
[WEAK] 如果在其它地方定義了相同的標號,則此處定義被覆蓋。
PROC 定義一個函數(shù)的起始地址。
ENDP 標志當前函數(shù)結(jié)束。
例子:
SysTick_Handler PROC
EXPORT SysTick_Handler [WEAK]
B.
ENDP
導出 SysTick_Handler 這個中斷處理函數(shù)。如果在其它地方定義了一個新的 SysTick_Handler 函數(shù),那么新函數(shù)將覆蓋此處定義的這個陷阱函數(shù)。匯編語句 B.為在當前語句死循環(huán)。下面我們看一下啟動文件 startup_stm32f030x8.s
定義堆和棧:
中斷向量表:
現(xiàn)在這個工程用到的只有綠線框中的幾個向量:
__initial_sp
初始堆棧指針
Reset_Handler
復位向量,我們在上一篇文章已經(jīng)講到如何從復位向量一步一步執(zhí)行到用戶代碼中的主程序main( )。
SysTick_Handler
系統(tǒng)時鐘中斷向量。此程序每 1ms 產(chǎn)生一次中斷。
需要注意的是 SysTick_Handler 這個中斷處理函數(shù)在用戶代碼文件stm32f0xx_it.c
中進行了重定義,所以當 SysTick 中斷發(fā)生時,實際會跳轉(zhuǎn)到用戶代碼的中斷處理函數(shù),而不是跳到下圖所示的匯編代碼中斷處理函數(shù)進入死循環(huán)。
再往下可以看到,對所有芯片級中斷定義了一個共享的陷阱函數(shù)。用戶在實際使用到某一個中斷的時候,要在中斷處理文件 stm32f0xx_it.c 中用相同的函數(shù)名定義,從而在中斷發(fā)生時跳轉(zhuǎn)到實際的中斷處理函數(shù)。
在此文件的最下面的代碼,是用來傳遞堆棧信息給庫的:
在芯片資源比較少時,可以通過選中 Options for Target->Target->Use MicroLIB 選項,使用簡化版的庫來實現(xiàn) printf 等操作。若資源充足時使用標準庫,庫將調(diào)用下面的 __user_initial_stackheap 函數(shù)來獲得堆棧信息。
M0 內(nèi)核初始化
system_stm32f0xx.c此文件只有兩個函數(shù):SystemInit( ),在啟動代碼中調(diào)用,把系統(tǒng)時鐘復位到初始默認狀態(tài)(8MHz的高頻內(nèi)部時鐘 HSI)。SystemCoreClockUpdate( ), 在用戶調(diào)用庫函數(shù)更改時鐘配置后,需要調(diào)用此函數(shù)以更新全局系統(tǒng)時鐘變量 SystemCoreClock。其它模塊基于此時鐘的計算才會正確。一般來說更改時鐘配置的 HAL函數(shù)已經(jīng)包含此函數(shù)的調(diào)用,如 HAL_RCC_ClockConfig( ), 無需用戶再次調(diào)用。
驅(qū)動
stm32f0xx_hal_cortex.c包含 Cortex 內(nèi)核中兩個重要模塊的驅(qū)動:可嵌套中斷向量控制器 NVIC(Nested Vectored Interrupt Controller),系統(tǒng)滴答時鐘 SYSTICK。
stm32f0xx_hal.c
此文件包含用戶程序必須首先調(diào)用的 HAL_Init( ),它會使能數(shù)據(jù)和指令緩存,預取指令隊列;配置系統(tǒng)滴答時鐘產(chǎn)生 1ms 中斷;調(diào)用 HAL_MspInit( )回調(diào)函數(shù)。
HAL_MspInit( )函數(shù)用來做系統(tǒng)級的初始化,配置某一模塊相關的 時鐘,引腳,DMA,中斷等資源,但是在所有的例程中都沒有實際用到此函數(shù)??梢韵群雎浴?/p>
stm32f0xx_hal_rcc.cstm32f0xx_hal_rcc_ex.c
RCC(Reset and Clock Controller)模塊的驅(qū)動。一個模塊為什么要兩個驅(qū)動文件呢?前一個文件提供了基本的通用的功能驅(qū)動,后一個文件是擴展功能驅(qū)動,通常針對某一特定型號的芯片。如同我們吃飯需要餐具,_rcc.c 提供碗筷等常用必備工具,_rcc_ex 可能提供的就是酒杯,燭臺等這些東西。
stm32f0xx_hal_gpio.c
GPIO 模塊的驅(qū)動。
BSP 板級支持包
stm32f0xx_nucleo.c
針對 STM32 Nucleo 開發(fā)板的類型,宏定義,支持代碼。
用戶代碼
main.c 主程序
stm32f0xx_it.c 中斷處理
前面介紹了一大堆文件,主要是為了清除系統(tǒng)的工作流程。在開發(fā)中使用庫還是很簡單的。在主程序中調(diào)用庫,只需要通過 main.h 包含下面這個頭文件:stm32f0xx_hal.h如果有 BSP 則包含 BSP 的頭文件,在本工程是:stm32f0xx_nucleo.h
使用到哪個模塊就在配置文件中打開使能該模塊的宏定義。
stm32f0xx_hal_conf.h
然后第一步必須調(diào)用 HAL_Init( )。
第二步,如果希望系統(tǒng)時鐘工作在默認內(nèi)部時鐘(8MHz HIS)以外的頻率,則需要調(diào)用 SystemClock_Config( )。此函數(shù)又調(diào)用 HAL_RCC_ClockConfig( ) 完成新配置。
下面是應用代碼:
所有模塊一般都是這三個步驟:使能模塊的時鐘,初始化模塊,使用模塊的功能。
stm32f0xx_it.c 中的中斷處理函數(shù) SysTick_Handler( ) 很簡單,每次進入就對滴答計時變量 uwTick 加1,其它 HAL 函數(shù)可以基于此變量計時。
審核編輯:劉清
-
單片機
+關注
關注
6043文章
44623瀏覽量
638839 -
led燈
+關注
關注
22文章
1592瀏覽量
108452 -
中斷處理
+關注
關注
0文章
94瀏覽量
11017 -
STM32F0
+關注
關注
0文章
61瀏覽量
17140
發(fā)布評論請先 登錄
相關推薦
STM32F030數(shù)據(jù)手冊
STM32F030之IAP代碼編寫
![<b class='flag-5'>STM32F030</b>之IAP代碼編寫](https://file.elecfans.com/web1/M00/4F/93/pIYBAFre2XuANcIXAACKrDG8wvw168.png)
STM32F030F4單片機的出廠程序詳細資料免費下載
![<b class='flag-5'>STM32F030F</b>4<b class='flag-5'>單片機</b>的出廠程序詳細資料免費下載](https://file.elecfans.com/web1/M00/66/9E/pIYBAFu9m9GAKJkiAAK7l6Gdgvo647.png)
使用STM32F030單片機讀取溫濕度傳感器SHT20的C語言源代碼免費下載
![使用<b class='flag-5'>STM32F030</b><b class='flag-5'>單片機</b>讀取溫濕度傳感器SHT20的C語言源代碼免費下載](https://file.elecfans.com/web1/M00/95/4A/o4YBAFz-HmSAGjz4AA5StlYw54E844.png)
STM32F030新建工程模板資料免費下載
![<b class='flag-5'>STM32F030</b>新建工程模板資料免費下載](https://file.elecfans.com/web1/M00/A2/0D/pIYBAF1Hg16AJ1xsAAGBvDmZUr8318.png)
STM32F030單片機和TFT薄膜晶體管的電路原理圖免費下載
![<b class='flag-5'>STM32F030</b><b class='flag-5'>單片機</b>和TFT薄膜晶體管的電路原理圖免費下載](https://file.elecfans.com/web1/M00/AC/E0/o4YBAF3I0kqAckW-AAGlVLomj6w439.png)
STM32F030F4P6單片機的電路原理圖免費下載
![<b class='flag-5'>STM32F030F</b>4P6<b class='flag-5'>單片機</b>的電路原理圖免費下載](https://file.elecfans.com/web1/M00/CC/3F/pIYBAF-Wi6iAAt8pAAFFiOO57z4866.png)
STM32F030芯片的IAP升級
![<b class='flag-5'>STM32F030</b>芯片的IAP升級](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
stm32f030系列時鐘介紹
![<b class='flag-5'>stm32f030</b>系列時鐘<b class='flag-5'>介紹</b>](https://file.elecfans.com//web2/M00/9A/84/pYYBAGQbtPSAFz0VAAGv1sBTSUE260.jpg)
評論