ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

就如同軟件工程師第一個程序永遠是“Hello World”一樣,電子工程師第一個實驗是點亮你的LED。當然,第一章的內容絕不僅僅是點亮個小燈那麼簡單,而是要通過一個最簡單的入門實驗,讓讀者充分了解STM32開發的基本流程。

11.1 軟件安裝

51單片機用的是Keil C51,而開發ARM要用Keil MDK(Multimedia Development Kit),同一個姓,不同名字的兄弟倆。值得注意的是,這兩個軟件同時安裝會衝突,因此學習STM32建議先把Keil C51卸載掉,再來安裝Keil MDK。如果想讓兩個軟件並存,方法較為複雜,讀者可以到網上搜索解決方法。Keil MDK位於“Kingst-32F1開發板配套光盤\相關工具軟件\Keil安裝包及PACK”文件夾中。

1、首先準備Keil uVision5安裝源文件,雙擊安裝文件,彈出安裝的歡迎界面,如圖1-1所示。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-1 Keil安裝歡迎界面

2、點擊“Next >>”按鈕,彈出“License Agreement”對話框,如圖1-2所示。這裡顯示的是安裝許可協議,需要在“I agree to all the terms of the preceding License Agreement”打勾。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-2 “License Agreement”對話框

3、點擊“Next >>”按鈕,彈出Folder Selection對話框,如圖1-3所示。主要是設置軟件和Pack的安裝路徑,選擇默認設置即可。單擊“Browse…”可以修改安裝路徑,如果修改,必須使用英文路徑,不要包含中文字符。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-3 “Folder Selection”對話框

4、點擊“Next >>”按鈕,彈出“Customer Information”對話框,如圖1-4所示。輸入用戶名、公司名稱以及E-mail地址,不能空著。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-4 用戶信息

點擊“Next >>”按鈕,彈出Setup Status對話框,如圖1-5所示。此時開始自動安裝軟件,中途會提示安裝驅動,選擇“安裝”即可,等待安裝完畢。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-5 安裝過程

5、點擊“Next >>”按鈕,彈出 Keil MDK-ARM Setup completed對話框,如圖1-6所示,把“Show Release Notes”的選項去掉即可。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-6 安裝完成

6、點擊“Finish”,彈出 Pack Installer窗口,如圖1-7所示。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-7 Device列表下載

7、點擊“OK”,如果此時連接網絡,會自動下載一個各廠商芯片的device列表,等待右下角的進度條完成後,列表更新完畢,如圖1-8所示。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-8 Device 列表

8、點擊左上角“File -> Import”,選中“Keil.STM32F1xx_DFP.2.1.0”,點擊打開,PACK就會自動導入,如圖1-9所示,等待右下角的進度條完成,PACK安裝完畢,關閉Pack Installer窗口,至此,編程軟件安裝完畢。

.

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-9 手動添加PACK文件

21.2 仿真器驅動安裝

ARM常用的通用仿真器有J-Link和U-Link,而ST公司也為本公司的芯片專門設計了ST-Link仿真器。Kingst-32F1開發板所採用的是ST-Link仿真器,仿真和下載程序前,必須安裝這個仿真器的驅動。直接雙擊ST-Link_V2_USBDriver這個文件,一直往下執行,安裝完畢,如圖1-10所示。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-10 安裝ST-Link Driver

驅動安裝完畢後,將下載線連接到電腦,對開發板上電,等待下載器指示燈由閃爍變為常亮。打開設備管理器,在設備管理器下會多出一個“STM32 STLink”,如圖1-11所示。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-11 ST-Link驅動安裝成功

31.3 單片機資源

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-12 STM32單片機內部結構圖

對於單片機用戶來講,單片機提供給的三大資源分別是程序存儲空間、數據存儲空間、特殊功能寄存器。顧名思義,程序存儲空間用來存儲用戶寫的程序代碼的,數據存儲空間用來存儲程序運行過程中需要的以及產生的數據。特殊功能寄存器,就是用來控制單片機執行各種不同功能,用戶通過讀寫特殊功能寄存器讓單片機執行不同的功能。STM32F103ZE這款單片機,有512K字節的FLASH(程序存儲空間),64K字節的靜態SRAM(數據存儲空間),另外還有大量的特殊功能寄存器提供給用戶來實現其功能。

41.4 單片機最小系統

單片機最小系統,也叫做單片機最小應用系統,是指用最少的元件組成單片機可以工作的系統。單片機最小系統的三要素就是電源電路、晶振電路、復位電路,如圖1-13所示。STM32F103ZE一共有144個引腳,在圖1-13中只是將它的和最小系統有關的引腳標識出來,其他引腳並沒有在這張圖體現。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-13 STM32F103ZE最小系統

1.4.1 電源電路

目前主流單片機的電源分為5V和3.3V這兩個標準,STM32F103所用的是3.3V的供電系統。和標準51單片機的5V供電系統比較,在同樣工作電流的前提下,STM32的工作電壓低,功率小一些,更能體現低功耗環保。從圖1-13可以看出,STM32不像51只有一組電源,而是有很多組。STM32功能更強大,內部的功能模塊更多,一方面要能夠給他提供足夠的電流支撐單片機的正常工作,而由於芯片內部走線很細,單電源不足以提供足夠的電流,需要多個電源並聯供電;另一方面各個模塊在單片機內部分佈分散,模塊獨立供電更有利於保持電源的穩定性,保證模塊的正常工作。細心的讀者會發現,電源還是成對存在的,一個VDD引腳(比如17腳)附近必然有一個對應的VSS(即GND,對應16引腳),設計線路板的時候,成對的VDD和VSS之間,在引腳附近必須加去耦電容,保證單片機的EMC特性。

1.4.2 晶振電路

電路採用了一個8M的晶振作為STM32的主時鐘源,但是學過51單片機的讀者不要簡單認為STM32的工作頻率就只能到8M了。STM32內部有PLL((Phase Locked Loop,即鎖相環),可以起到倍頻的作用,STM32F103ZE最大工作頻率可以達到72M。也就是說,輸入時鐘雖然是8M的外部晶振,但是通過配置寄存器可以實現最大72M的工作頻率。

1.4.3 復位電路

從STM32F103的復位電路可以看出這是個低電平復位電路。電源電路、晶振電路、復位電路構成了單片機最小系統的三要素,也就是說,一個單片機具備了這三個條件,就可以運行下載的程序了,其他的比如LED小燈、數碼管、液晶等設備都是屬於單片機的外部設備,即外設。最終完成想要的功能就是通過對單片機編程來控制各種各樣的外設實現的。

51.5 LED小燈電路

既然第一個程序是點亮LED小燈,首先根據電路原理圖確定小燈的控制引腳,如圖1-14和表1-1所示。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-14 LED小燈電路

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

61.6 新建工程

任何一個完整的單片機程序都需要一個載體,這個載體就是工程。因此,在寫程序之前需要創建一個工程。打開Keil軟件後,點擊:Project -> New uVision Project...如圖1-15所示。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-15 新建工程

每一個工程,需要建立一個獨立的文件夾方便管理,所以在硬盤上提前建立一個Lesson1的目錄,然後把剛剛建立的工程路徑指定到這裡,並且給這個工程起一個名字叫做Lesson1_1,軟件會自動添加擴展名,如圖1-16所示。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-16 保存工程

點擊保存,彈出“Select Devices For Target”對話框,如圖1-17所示。本書所用型號是STM32F103ZE,軟件上依次選擇“STMicroelectronics -> STM32F1 Series -> STM32F103 -> STM32F103ZE”。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-17 Select Devices For Target

點擊“OK”保存,彈出“Manage Run-Time Environment”對話框,如圖1-18所示。這裡直接點擊“Cancel”關閉。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-18 Manage Run-Time Environment

工程創建完畢後,接下來要在工程中編寫程序代碼,還需要新建文本文件來編寫程序。單擊“File ->New”或者單擊工具欄中的 “空白頁”符號新建一個文本文件,如圖1-19所示。然後點擊“File -> Save”,或者點擊“保存”按鈕。將文本保存在新建的工程文件夾內,名稱為“main.c”。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-19 新建文件

點中“Source Group 1”,單擊鼠標右鍵,選擇“Add Existing File to Source Group1”,如圖1-20所示。選擇剛剛建立的“main.c”文件,點擊“Add”,將其添加到工程中來。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-20 添加文件

除此之外,還需要添加一個非常重要的文件——“啟動文件”。該文件負責執行微控制器從“復位”到“開始執行main函數”中間這段時間(稱為啟動過程)所必須進行的工作。每一款單片機都有啟動文件,只是有些單片機的啟動文件是由編譯器自動提供的,不需要開發者額外操作,比如之前學習的51單片機。STM32為了方便開發,可以直接對啟動文件進行操作,因此需要向工程添加啟動文件。將“Kingst-32F1開發板配套光盤\Kingst-32F1開發板資料\啟動文件-已修改”文件夾內的‘startup_stm32f10x_hd.s’文件複製到Lesson1文件夾內。

再次點擊“Source Group 1”, 單擊鼠標右鍵,選擇“Add Existing File to Source Group1 ”,找到Lesson1文件夾,選擇文件類型為“All files(*.*)”,選中“startup_stm32f10x_hd.s”,點擊“Add”,將其添加到工程中來。文本添加完成後,還需要修改一下啟動文件。如圖1-21所示,啟動文件150~152這三行代碼如果未註釋掉,則使用分號“;”註釋掉,不執行這三條語句,後面使用庫函數開發時才會使用。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-21 修改啟動文件

修改完成後,就可以在main.c文本中編寫程序代碼,整體的界面如圖1-22所示。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-22 工程界面

71.7 配置工程

STM32F103的編寫程序、在線仿真、下載程序,全部由Keil一個軟件完成,不需要額外的下載軟件。因此需要對建立好的工程進行配置。

1、點擊工具欄中的“Options for Target”按鈕,如圖1-23所示。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-23 配置工程

2、在“Options for Target”對話框,點擊“Debug”選項卡,如圖1-24。右上角下拉菜單選擇“ST-Ling Debugger”選項。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-24 Debug選項卡

3、如果此刻開發板驅動正常並且正常通電,點擊“ST-Link Debugger”右側“Settings”按鈕,彈出“驅動設置選項卡”,如圖1-25所示,在“Port”處選擇“SW”。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-25驅動設置選項卡-Debug

4、點擊“Flash Download”選項,將“Reset and Run”勾選上,否則下載程序後,需要手動復位,程序才能運行,然後如圖1-26所示。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-26驅動設置選項卡-Flash Download

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-27 字體設置(一)

6、要使用中文的話在Editor欄中“Encoding選項”中選擇Chinese GB2312(Simplified),並勾選“Insert spaces for tabs ”,設置Tab size為4,如圖1-28所示。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-28 字體設置(二)

8、點擊Colors&Fonts選項卡,在Window一欄選擇C/C++ Editor file,中間Element一欄選擇Text,最後點擊右側Font一欄中的Font對應的按鈕可以選擇字體,一般選擇SimSun-ExtB,Size為11,字體大小可以根據自己的習慣進行設置,如圖1-29所示。其餘的Keil本身都是有默認設置的,可以直接使用默認設置,改完後直接點OK看效果就可以了。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-29 字體設置(三)

81.8 程序代碼編寫

1.8.1 單片機寄存器的訪問

單片機內部有許許多多的特殊功能寄存器,控制著單片機的各個模塊,完成了單片機強大的功能。比如要把一個單片機的引腳設置成高電平,只需要通過編程將這個引腳對應的寄存器設置成相應的數值,單片機就可以自動輸出高電平。單片機內部的寄存器非常多,為了管理這些寄存器,就給他們分配了許多個房間,每個房間都有個房間號,即地址。編寫程序通過訪問這個地址,設置對應地址的特殊功能寄存器來完成單片機強大的功能,也叫做地址映射。

學習51單片機的時候,由於51單片機內部結構的特殊性,RAM地址和寄存器地址有重複的區間,所以映射寄存器用的是sfr這個關鍵字,不能對寄存器地址直接操作。比如sfr P0= 0x80; P0=0x01;表達的意思是將0x01賦值給0x80這個地址對應的寄存器。對於其他類型的單片機的寄存器操作,大多數可以對寄存器地址直接操作。比如對STM32的寄存器操作*(unsigned int *)0x4001100C = 0x01;表達的意思就是將0x01賦值給0x4001100C這個地址對應的寄存器。0x4001100C是個地址,使用(unsigned int *)強制轉換成指針,前邊再加*相當於訪問這個指針指向的內容,最終對這個內容進行賦值。

1.8.2 寄存器地址分配

一棟99層的大樓,有很多個房間,如何區分?比如0312這個房間,通常認為03是樓層,3樓的第1個房間的房間號就是0301,那0312這個房間號代表的就是第3層的第12個房間。STM32的寄存器也分成了很多個組,每一組都有一個起始地址,也稱之為基地址,回到樓層的例子上,基地址就相當於0300(與現實的房間號不同的是MCU從0開始計數);每一組裡邊又包含多個寄存器,每個寄存器都相對基地址存在地址偏移,也稱之為偏移地址,12就是房間0312相對0300的偏移地址。STM32F103的寄存器基地址和偏移地址都可以從《STM32中文參考手冊》“2.3節 存儲器映像”查閱到,寄存器起始地址如表1-2所示,這個表格瞭解即可,用到隨時查閱。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

表1-2 寄存器組起始地址

STM32F103的IO口統稱為GPIO(General Purpose Input Output通用輸入/輸出),這是單片機一個重要的外設。STM32F103ZE的IO口多達112個,為了方便管理這麼多IO口,將其分為A、B、C、D、E、F、G一共7組,每一組有16個IO口,同樣也產生了7組管理GPIO口的寄存器,每一組寄存器都有基地址,每一個寄存器都有其相對基地址的偏移地址,這麼多寄存器負責管理和控制單片機GPIO口的輸入輸出模式和數據。

1.8.3 STM32的GPIO端口配置流程

以點亮LED為例介紹一下STM32F103的IO口輸出操作流程,一共三個步驟:配置端口時鐘、配置端口模式、配置輸出數據,如圖1-30所示。通過原理圖得知,實驗板的2個LED小燈分別接在STM32的端口G的第7、8引腳,因此可以通過表1-2查詢端口G的寄存器的基地址為“0x40012000”。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-30 GPIO端口配置

1、配置端口時鐘。為有效控制噪聲和功耗,STM32各個模塊時鐘可以獨立控制打開或關閉。STM32的GPIO外設是掛在APB2總線上的,通過查找表1-2,“復位和時鐘控制(RCC)寄存器”的基地址是0x40021000,其中“APB2外設時鐘使能寄存器”的偏移地址是0x18,是該寄存器的第8位控制端口G的時鐘使能,置‘1’為開啟,清‘0’為關閉,如圖1-31所示。開啟端口G時鐘使能的語句為*(unsigned int *)0x40021018 |= (1 << 8)。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-31 APB2外設時鐘使能寄存器

2、配置端口模式。STM32的IO口模式有8種。分別是浮空輸入、上拉輸入、下拉輸入、模擬輸入、開漏輸出、推輓輸出、推輓式複用功能、開漏複用功能,本節先介紹輸出模式。如表1-3所示,其中CNF1和CNF0兩位用來表示模式,MODE1和MODE0用來表示輸出速率。

當模式為輸入時,默認MODE1和MODE0是00;當模式為輸出時,MODE1和MODE0的三種組合表示三種不同的最大輸出速率,注意這裡的速率指的是I/O口驅動電路的響應速度而不是I/O口輸出信號的速度。而CNF1和CNF0的組合代表了4種不同的輸出模式。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

表1-3 I/O口配置模式

GPIO端口G的基地址是0x40012000,模式寄存器有高低之分,這裡高寄存器的偏移地址0x04,控制同一端口下的8~15這8個IO口,低寄存器偏移地址0x00,控制同一端口下的0~7這8個IO口。特別注意復位值是0x44444444,如圖1-32所示。把復位值代入到寄存器可以觀察到CNFx[1:0]是01,MODEx[1:0]是00,即每個IO口復位後是浮空輸入模式。

要配置為推輓輸出,速率為10MHz,即CNFx[1:0]是00,MODEx[1:0]是01,合起來就是0001。比如配置GPIO端口G的第7引腳,即配置端口配置低寄存器的28~31位為0001,代碼為:

*(unsigned int *)0x40012000 &= ~(0xFU << 28);

*(unsigned int *)0x40012000 |= 1 << 28;

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-32 端口配置寄存器

3、配置輸出數據。STM32的GPIO輸出數據寄存器相對於端口的偏移地址為0x0C,通過圖1-33可以看到,輸出數據寄存器的16~31位被保留了,也就是沒有使用。因此餘下的0~15位這16個數據位分別對應GPIO端口的16個IO口。對數據位置‘1’為輸出高電平,清‘0’為輸出低電平,復位值為0x0000 0000,默認復位後輸出低電平。比如控制GPIO端口G的第7引腳輸出高電平:

*(unsigned int *)0x4001200C |= 1<<7;

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-33 端口輸出數據寄存器

1.8.4 程序編寫

原理清楚後,程序編寫很簡單。特別注意的是,寫51單片機程序的時候,main函數定義為void類型,STM32的程序要求是int類型。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

1.8.5 編譯下載

程序編寫完成後,鼠標點擊圖1-34中下劃線標註的快捷圖標。

1、Translate,僅編譯當前文件,不生成最終程序文件;

2、Build,構建生成,編譯所有已修改文件,生成最終程序文件;

3、Rebuild,重新構建生成,重新編譯所有文件,生成最終程序文件。

通常推薦使用第2個,可以有效節省編譯時間。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-34 編譯程序

編譯完成後,在Keil下方Output窗口會出現相應的提示,如圖1-35,Program Size: Code=1348的意思是代碼佔用了1348個字節的程序存儲空間。RO-data(Read Only)是隻讀常量的大小,RW-data(Read/Write)是已初始化的可讀寫變量的大小,ZI-data(Zero Initialize)未初始化的可讀寫變量的大小。

當提示“0 Error(s), 0 warning(s)”表示的程序沒有錯誤和警告,如果出現有錯誤和警告提示的話,就是Error和warning不是0,那麼就要對程序進行檢查,找出問題,解決好了再重新編譯。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-35 編譯輸出信息

到此為止,程序就編譯好了。連接好下載器,點擊圖1-36所示的按鈕或者點擊“Flash->Download”將代碼下載到單片機中,即可完成程序下載,同時也完成了點亮LED小燈實驗。

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

圖1-36 下載程序

91.9 LED閃爍

上一節學習瞭如何點亮LED燈,接下來繼續深入學習LED燈閃爍。在“1.8.3節 STM32的GPIO端口配置流程”講過,控制GPIO端口輸出“高電平”還是“低電平”的寄存器為“端口輸出數據寄存器”,輸出高電平“置1”,輸出低電平“置0”;結合前面所寫的點亮LED燈的程序,得到LED閃爍代碼:

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED

ARM嵌入式編程與實戰應用(STM32F1系列)第1章 點亮你的LED


分享到:


相關文章: