文章目錄
STM32簡介
簡介參考自:小馬哥STM32四軸學習平臺–DragonFly四軸STM32單片機軟件入門級飛控算法課程git
單片微型計算機簡稱單片機(MCU(MicrbControl Unit)),咱們本身的我的計算機中,CPU、RAM、ROM、I/O這些都是單獨的芯片,而後這些芯片被安裝在一個主板上,這樣就構成了咱們的PC主板,進而組裝成電腦,而單片機只是將這全部的集中在了一個芯片上而已。單片機又有8位的如51單片機、16位的如MSP430、32位的如STM32,一般咱們說的多少位一般指的是內核(CPU)一次處理的數據寬度。也就是說內核一次處理的位數越多單片機的計算速度就越快,性能也就越強悍。github
STM32是意法半導體(ST)推出一款32位的單片機。STM32具備超低的價格、超多的外設、豐富的型號、優異的實時性、極低的開發成本等優點。STM32憑藉其產品線的多樣化、極高的性價比、簡單易用的庫開發方式,迅速在衆多32位單片機中脫穎而出。算法
STM32芯片內部能夠粗略劃分兩部分:內核+片上外設。若是與電腦類比,內核與片上外設就如同電腦的CPU與主板、內存、顯卡、硬盤的關係。
ARM公司只設計內核不生產芯片,他會將有關內核的技術受權給各半導體廠商例如ST、TI、Atme一、NXP等廠商。這些廠商都是基於這個內核本身設計片上外設如SRAM、ROM、FLASH、USART、GPIO等,而後集成到一個硅片上,這就是咱們如今用的芯片。
芯片內部架構見圖:
微信
芯片內部內核和外設分別是兩個公司設計的,那他們該怎麼聯繫到一塊兒協同高效的工做呢?答案就是總線,學過計算機組成原理的同窗都應該知道計算機五大組成部分運算器、控制器、存儲器、輸入設備、輸出設備他們之間的通訊就是經過總線。咱們上面也說了單片機就是一個集成在硅片上的計算機,因此他內部的鏈接關係也是靠總線。
STM32內部一共有11條總線:
架構
![image-20201123194739287](http://static.javashuo.com/static/loading.gif)
咱們知道,在嵌入式開發中,好比51和Arduino,咱們寫程序燒入芯片就能夠實現控制。那麼咱們寫的程序怎麼就能控制咱們的單片機工做呢或者程序在控制什麼東西呢?
那個東西就是寄存器,其實無論咱們用庫開發仍是寄存器開發咱們本質上就是在控制寄存器上的每一個位的通斷,而且這些寄存器都有其特定的功能。換句話說每一個外設(如GPI0、USART、I2C、SPI.…)都對應有寄存器來對他控制。
ide
因此STM32能夠用寄存器開發也能夠用庫開發。函數
STM的選型
STM32是ST的全部產品的統稱,ST有兩你們族STM8和STM32。STM8主要針對於低成本,對主頻要求比較低、運算速度要求不是很高的低端市場。STM32主要應用於項目對主頻要求較高、運算速度比較快、實時性好的中高端市場。STM32有不少產品大體劃分可分爲主流MCU、高性能MCU、低功耗MCU。其中主流MCU如STM32F1系列、高性能MCU如STM32F四、STM32F7系列、低功耗MCU如STM32L0系列。而且每一個系列產品下面還會根據閃存容量、外設數量、封裝大小分爲不少種類而且價格也是差異很大。工具
![image-20201123193713582](http://static.javashuo.com/static/loading.gif)
STM32型號的說明:以STM32F103RBT6這個型號的芯片爲例,該型號的組成爲7個部分,其命名規則以下:性能
1 | STM32 | STM32表明ARM Cortex-M內核的32位微控制器。 |
---|---|---|
2 | F | F表明芯片子系列。 |
3 | 103 | 103表明加強型系列。 |
4 | R | R這一項表明引腳數,其中T表明36腳,C表明48腳,R表明64腳,V表明100腳,Z表明144腳,I表明176腳。 |
5 | B | B這一項表明內嵌Flash容量,其中6表明32K字節Flash,8表明64K字節Flash,B表明128K字節Flash,C表明256K字節Flash,D表明384K字節Flash,E表明512K字節Flash,G表明1M字節Flash。 |
6 | T | T這一項表明封裝,其中H表明BGA封裝,T表明LQFP封裝,U表明VFQFPN封裝。 |
7 | 6 | 6這一項表明工做溫度範圍,其中6表明-40——85℃,7表明-40——105℃。 |
我手上是一款德飛萊尼莫M3S V2.3開發板。學習
用的是STM32F103ZET6,芯片說明書以下:
![微信截圖_20201120172445](http://static.javashuo.com/static/loading.gif)
以後還購置了一款最小系統板,搭載STM32103C8T6:
![image-20201123201356072](http://static.javashuo.com/static/loading.gif)
編寫程序
先下載keil軟件(官網下載MDK5的安裝包):
注意:
![微信截圖_20201120175054](http://static.javashuo.com/static/loading.gif)
因此要開發C51就得下載C51的Keil,要開發STM32就得下載MDK-Arm。
若是要設置C51和STM32的開發環境,通常須要準備以下文件:
資源連接: 百度網盤密碼:d1cs
安裝能夠參考這個:STM32開發環境搭建(Keil)
和MDK5安裝破解以及安裝stm32與C51支持包(附安裝包)
其中pack文件是STM32的芯片包,能夠在安裝完keil後下載(KEIL公司的軟件包託管網站)雙擊安裝,也能夠去keil的pack Installer安裝。
Keil安裝
選擇安裝路徑時包括選擇MDK核心組件(Core)的安裝路徑和外設包(Pack)的安裝路徑,通常只用選擇 Core 的安裝路徑,Pack 的路徑會自動設置爲 Core 路徑下的ARM/PACK
。
安裝完成後,會自動彈出 Pack Installer 界面,若是沒有的話能夠打開安裝好的 Keil uVision5 軟件,在工具欄上找到 Pack Installer 的圖標,而後點擊進入:
因爲咱們使用的STM32型號爲 STM32F103ZET6,還須要安裝開發所須要的器件支持包(Device Family Pack, i.e. DFP),因此展開STM系列產品的菜單欄,找到芯片設備,點擊左邊Packs中的三個組件,Pack Installer 會自動從網上下載最新版本的組件,下載進度在 Pack Installer 底部狀態欄顯示。(因爲我已經經過雙擊安裝好了,因此是Up to date)
直接用Keil5新建工程(只能用Keil5快速新建工程)。
Project-> New,以後選擇本身的開發板芯片:
![image-20201123172441979](http://static.javashuo.com/static/loading.gif)
肯定以後又跳到運行環境的界面:
![image-20201123181848042](http://static.javashuo.com/static/loading.gif)
必選CMSIS的Core還有Device的Startup。
若是要鏈接外設必須勾選外設的時鐘RCC,通常再勾選上Framework、GPIO、和USART串口。
點擊OK肯定建立項目。項目建立完成後就是這樣的:
![image-20201123182513726](http://static.javashuo.com/static/loading.gif)
能夠看到已經包含了咱們選擇的庫文件。若是還須要什麼能夠再點擊圖上的按鈕再次打開運行環境配置頁面。
![image-20201123182326097](http://static.javashuo.com/static/loading.gif)
以後能夠管理一下項目目錄,自定義一下名字。
![image-20201123183231495](http://static.javashuo.com/static/loading.gif)
而後添加main.c文件:
![image-20201123183211905](http://static.javashuo.com/static/loading.gif)
以後就能夠在main文件中寫代碼了。
![image-20201123183738651](http://static.javashuo.com/static/loading.gif)
寫完能夠編譯一下,若是輸出正確就表示環境配置沒問題。
![image-20201123184915044](http://static.javashuo.com/static/loading.gif)
這裏默認是不會建立Hex文件的,因此還須要進入設置裏面去設置一下。
![image-20201123183932143](http://static.javashuo.com/static/loading.gif)
以後再編譯就能夠在Objects文件夾下面看到Hex文件。
![image-20201123185140948](http://static.javashuo.com/static/loading.gif)
燒寫程序
參考這個:如何使用串口來給STM32下載程序
不過具體還得看官方的開發板說明書。
STLink 上 LED 指示燈用於提示當前的工做狀態,具體狀況以下:
- LED 閃爍紅色:STLink 已經鏈接至計算機。
- LED 保持紅色:計算機已經成功與 STLink 創建通訊鏈接。
- LED 交替閃爍紅色和綠色:數據正在傳輸。
- LED 保持綠色:最後一次通訊是成功的。
- LED 爲橘黃色:最後一次通訊失敗。
說白了就是3步:
1.鏈接芯片:
Tarage -> connect或直接點擊鏈接快捷按鈕:
![20160920161759141](http://static.javashuo.com/static/loading.gif)
2.打開程序
打開hex文件能夠從菜單欄(File -> Open File)打開,也能夠直接講hex文件拖動到FLASH區域:
![20160920161809181](http://static.javashuo.com/static/loading.gif)
3.下載程序
點擊「下載」(能夠Taraget -> Program,也能夠直接點擊下載快捷按鈕,以下圖):
![20160920161820947](http://static.javashuo.com/static/loading.gif)
彈出信息確認窗口,如hex文件路徑、驗證方式等,確認信息無誤後點擊「Start」開始下載程序。
![image-20201123190055806](http://static.javashuo.com/static/loading.gif)
出現「Verification…OK」,說明下載成功。
點亮LED燈
GPIO簡介
GPI0是通用輸入輸出端口的簡稱,從名字上也可看出GPIO最基本的功能就輸入和輸出。它也是芯片內部與外部電路鏈接的惟一的接口,換句話說只要咱們使用片上外設幾乎都會與GPIO打交道。
GPI0基本功能是輸入和輸出,可是STM32自己就是一個很複雜的系統,內部外設繁多,那麼GPIO的基本功能是確定知足不了這麼多外設的需求,芯片廠商爲了解決此問題,將GPI0分爲八種模式(輸入4種+輸出4種)。八種模式分別爲:
-
輸入浮空 GPIO_Mode_IN_FLOATING
-
輸入上拉 GPIO_Mode_IPU
-
輸入下拉 GPIO_Mode_IPD
-
模擬輸入 GPIO_Mode_AIN
-
具備上拉或下拉功能的開漏輸出 GPIO_Mode_Out_OD
-
具備上拉或下拉功能的推輓輸出 GPIO_Mode_Out_PP
-
具備上拉或下拉功能的複用功能推輓 GPIO_Mode_AF_PP
-
具備上拉或下拉功能的複用功能開漏 GPIO_Mode_AF_OD
個人STM32開發闆闆載兩個LED小燈,電路圖以下:
![image-20201123204842471](http://static.javashuo.com/static/loading.gif)
GPIO配置
因爲STM32的GPIO工做模式有8種,因此在GPIO輸出以前要先對要操做的GPIO進行配置:
-
定義GPIO的初始化結構體類型
-
使能GPIO的時鐘
-
配置GPIO的引腳
-
配置GPIO口的輸出類型爲推輓
-
配置GPIO口的輸出速度
-
初始化GPIO(初始化相應的寄存器)
GPIO_InitTypeDef GPIO_InitStructure; // 定義結構體變量 //打開PB口時鐘 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //打開PE口時鐘 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); //PB5,PE5引腳設置 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //設置輸出速率50MHz GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //推輓輸出模式 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //初始化外設GPIOx寄存器 GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_Init(GPIOE, &GPIO_InitStructure);
解釋:
1.定義GPIO的初始化類型結構體:
GPIO_InitTypeDef GPIO_InitStructure;
此結構體的定義是在stm32f10x_gpio.h
文件中,其中包括3個成員。
typedef struct { uint16_t GPIO_Pin; GPIOSpeed_TypeDef GPIO_Speed; GPIOMode_TypeDef GPIO_Mode; }GPIO_InitTypeDef;
(1)uint16_t GPIO_Pin;
來指定GPIO的哪一個或哪些引腳,取值參見stm32f10x_gpio.h
頭文件的宏定義。
(2)GPIOSpeed_TypeDef GPIO_Speed;
GPIO的速度配置,此項的取值參見stm32f10x_gpio.h
頭文件GPIOSpeed_TypeDef
枚舉的定義,其中對應3個速度:10MHz、2MHz、50MHz;
(3)GPIOMode_TypeDef GPIO_Mode;
爲GPIO的工做模式配置,其取值參見stm32f10x_gpio
頭文件GPIOMode_TypeDef
枚舉的定義,即GPIO的8種工做模式。
2.使能GPIO時鐘
ARM與C51單片機不一樣的是,不用外設的時候,如IO口、ADC、定時器等等,都是禁止時鐘的,以達到節能的目的,只有要用到的外設,纔開啓它的時鐘。
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
此函數是在stm32f10x_rcc.c
文件中定義的。其中第一個參數指要打開哪一組GPIO的時鐘,取值參見stm32f10x_rcc.h
文件中的宏定義,第二個參數爲打開或關閉使能,取值參見stm32f10x.h
文件中的定義,其中ENABLE表明開啓使能,DISABLE表明關閉使能。
3.設置GPIO_InitTypeDef結構體三個成員的值
這裏包括引腳、速度和工做模式,取值可參考第一部分。
4.初始化GPIO
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
函數配置GPIO,此函數是在stm32f10x_gpio.c
文件中定義的,其中第一個參數表明要配置哪組GPIO,取值參見stm32f10x.h
文件中的定義,第二個參數是第1步定義的GPIO的初始化類型結構體。
GPIO電平輸出
官方讓GPIO輸出高低電平的函數:
GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
函數就是置位GPIO,即讓相應的GPIO輸出高電平;
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
函數是讓GPIO復位的,即讓相應的GPIO輸出低電平。
程序編寫
# include "stm32f10x.h" #define LED3_OFF GPIO_SetBits(GPIOB,GPIO_Pin_5) #define LED3_ON GPIO_ResetBits(GPIOB,GPIO_Pin_5) void LED_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; // 定義結構體變量 //打開PB口時鐘 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //PB5引腳設置 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //端口速度 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //端口模式,此爲輸出推輓模式 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //初始化對應的端口 GPIO_Init(GPIOB, &GPIO_InitStructure); } int main() { LED_Init(); while(1) { LED3_ON; } }
閃爍LED燈
這個實驗室作的兩個led流水燈。
程序編寫
首先新建一個文件夾MY
:
在該文件夾下新建一個led.h
頭文件:
#ifndef __LED_H #define __LED_H #include "stm32f10x.h" #define LED2_OFF GPIO_SetBits(GPIOE,GPIO_Pin_5) #define LED2_ON GPIO_ResetBits(GPIOE,GPIO_Pin_5) #define LED2_REV GPIO_WriteBit(GPIOE, GPIO_Pin_5,(BitAction)(1-(GPIO_ReadOutputDataBit(GPIOE, GPIO_Pin_5)))) #define LED3_OFF GPIO_SetBits(GPIOB,GPIO_Pin_5) #define LED3_ON GPIO_ResetBits(GPIOB,GPIO_Pin_5) #define LED3_REV GPIO_WriteBit(GPIOB, GPIO_Pin_5,(BitAction)(1-(GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_5)))) void LED_Init(void); #endif
以後新建一個led.c文件:
#include "led.h" void LED_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; // 定義結構體變量 //打開PB口時鐘 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //打開PE口時鐘 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); //PB5,PE5引腳設置 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //端口速度 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //端口模式,此爲輸出推輓模式 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //初始化對應的端口 GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_Init(GPIOE, &GPIO_InitStructure); }
最後編寫main文件:
# include "stm32f10x.h" # include "led.h" int main() { uint32_t i; LED_Init(); //初始化LED LED2_ON; LED3_OFF; for(i=0; i<0xffffff; i++); //for循環不精確延時 while(1) { for(i=0; i<0xfffff; i++); //for循環不精確延時 LED2_REV;//LED2取反 LED3_REV;//LED3取反 } }
結構目錄如圖:
![微信截圖_20201124091425](http://static.javashuo.com/static/loading.gif)
.h
文件默認是不顯示的。編譯經過後,在左側的.C文件上會出現一個「+」號,點開就是該C文件使用到的h
文件。
實驗結果
![GIF-min](http://static.javashuo.com/static/loading.gif)