一、初識STM32
1.什么是STM32
STM32,從字面上來理解,ST 是意法半導體,M 是 Microelectronics 的縮寫,32 表示32 位,合起來理解,STM32 就是指 ST 公司開發(fā)的 32 位微控制器。在如今的 32 位控制器當中,STM32 可以說是最璀璨的新星。
STM32F103 采用的是 Cortex-M3 內核,內核即 CPU,由 ARM 公司設計。ARM 公司并不生產芯片,而是出售其芯片技術授權。芯片生產廠商(SOC)如 ST、TI、Freescale,負責在內核之外設計部件并生產整個芯片,這些內核之外的部件被稱為核外外設或片上外設。如 GPIO、USART(串口)、I2C、SPI 等都叫做片上外設。具體下圖。
2.STM32的應用場景
STM32系列基于專門要求高性能,低成本,低功耗的嵌入式應用專門設計的ARM Cortex-M0,Cortex-M1,Cortex-M3,Cortex-M4,Cortex-M7等。其中Cortex-M0主打的是低功耗和混合信號的處理,M3主要用來替代ARM7,重點側重能耗和性能的均衡,而M7則重點放在高性能控制運算領域。
STM32 屬于一個微控制器,自帶了各種常用通信接口,比如 USART、I2C、SPI 等,可接非常多的傳感器,可以控制很多的設備?,F(xiàn)實生活中,我們接觸到的很多電器產品都有 STM32 的身影,比如智能手環(huán),微型四軸飛行器,平衡車、移動 POST 機,智能電飯鍋,3D 打印機等等。
3.STM32產品命名規(guī)則
以STM32F103C8T6為例:
(1) STM32:表示32位MCU;
(2) F103:表示基礎型;
(3) C:表示芯片上含48個引腳;
(4) 8:表示閃存容量為64K字節(jié);
(5) T:表示QFP封裝;
(6) 6:表示工作溫度范圍在-40°C到85°C;
二、STM32F103C8T6介紹
1.簡要說明
STM32F103C8T6是一款基于ARM Cortex-M內核STM32系列的32位的微控制器,程序存儲器容量是64KB,需要電壓2V~3.6V,工作溫度為-40°C ~ 85°C。
其中, Cortex-M3摒棄了馮· 諾依曼結構(普林斯頓結構),采用了將指令存儲和數(shù)據存儲分開的 的哈佛結構(Harvard Architecture ),這樣一來Cortex-M3同時擁有了獨立的32-bit指令總線和32-bit數(shù)據總線,數(shù)據訪問將不再占用指令總線,同時讀取指令和數(shù)據后提升了MCU運行速度。馮諾依曼和哈弗結構的宏觀對比如下圖所示:
2.基本參數(shù)
參數(shù)名 | 參數(shù)詳情 |
---|---|
類別 | 集成電路(IC) |
家族 | 嵌入式-微控制器 |
總線寬度 | 32-位 |
速度 | 72MHz |
外圍設備 | DMA,電機控制PWM,PWM,溫度傳感器 |
輸入/輸出數(shù) | 37 |
程序存儲器容量 | 64KB (64K x 8) |
程序存儲器類型 | FLASH |
RAM容量 | 20K x 8 |
電壓-電源(Vcc/Vdd) | 2 V ~ 3.6 V |
模數(shù)轉換器 | A/D 10x12b |
振蕩器型 | 內部 |
工作溫度 | -40°C ~ 85°C |
封裝/外殼 | 48-LQFP |
3.最小系統(tǒng)板
【產品介紹】
該系統(tǒng)板是基于STM32F103C8T6為主芯片的ARM核心板,有如下特點:
1、板載了基于MCU的最基本電路,如晶振電路、USB電源管理電路和USB接口等。
2、核心板引出了所有的I/O口資源。
3、帶有SWD仿真調試下載接口,該接口最少需要3根線就可以完成調試下載任務,相比傳統(tǒng)的JTAG調試有不少的好處
4、外形尺寸只有傳統(tǒng)的DIP40封裝(例如AT89S52)的大小,目前還未在淘寶上發(fā)現(xiàn)比我們更小的同規(guī)格的核心板。
5、使用了目前智能手機所使用的Mirco USB接口,使用方便,可做USB通訊和供電。
6、針對STM32 RTC不起振的問題,我們采用了官方建議的低負載RTC晶振方案,并使用了愛普生品牌的晶振,而沒有使用廉價的圓柱晶振。
7、配有優(yōu)質的1*40/2.54mm間距的單排排針,確保導電接觸優(yōu)良,方便用戶將核心板放置到標準的的萬用板或者面包板上。排針默認不焊接,用戶可以根據自己的需要選擇焊接方向。
三、STM32F103系列芯片寄存器映射
1.什么是寄存器
寄存器是中央處理器內的組成部分,是有限容量的高速存貯部件,可用來暫存指令、數(shù)據、地址等。
簡單來說,寄存器用來存放東西的地方,類似于行李寄存,只不過,寄存器存放的不是行李,而是指令、數(shù)據、地址等。不同的·數(shù)據會存放在不同的寄存器中,通過地址區(qū)分不同的寄存器。
2.什么是存儲器映射
存儲器本身不具有地址信息,它的地址是由芯片廠商或用戶分配,給存儲器分配地址的過程就稱為存儲器映射,如下圖所示。如果給存儲器再分配一個地址就叫存儲器重映射。
在存儲器 Block2 這塊區(qū)域,設計的是片上外設,它們以四個字節(jié)為一個單元,共 32bit,每一個單元對應不同的功能,當我們控制這些單元時就可以驅動外設工作。
我們可以找到每個單元的起始地址,然后通過 C 語言指針的操作方式來訪問這些單元,如果每次都是通過這種地址的方式來訪問,不僅不好記憶還容易出錯,這時我們可以根據每個單元功能的不同,以功能為名給這個內存單元取一個別名,這個別名就是我們經常說的寄存器,這個給已經分配好地址的有特定功能的內存單元取別名的過程就叫寄存器映射。
3.確定寄存器地址的方法
片上外設區(qū)分為三條總線,根據外設速度的不同,不同總線掛載著不同的外設,APB1掛載低速外設,APB2 和 AHB 掛載高速外設。
相應總線的最低地址我們稱為該總線的基地址,總線基地址也是掛載在該總線上的首個外設的地址。其中 APB1 總線的地址最低,片上外設從這里開始,也叫外設基地址。
(1)確定GPIOx總線基地址
總線名稱 | 總線基地址 | 相對外設基地址的偏移 |
APB1 | 0x4000 0000 | 0x0 |
APB2 | 0x4001 0000 | 0x0001 0000 |
APB | 0x4001 8000 | 0x0001 8000 |
上述表格的“相對外設基地址偏移”即該總線地址與“片上外設”基地址 0x4000 0000的差值。
(2)找到GPIOx外設基地址
總線上掛載著各種外設,這些外設也有自己的地址范圍,特定外設的首個地址稱為“XX 外設基地址”,也叫 XX 外設的邊界地址。
在此,以 GPIO 外設來講解外設的基地址,GPIO 屬于高速的外設 ,掛載到APB2 總線上:
外設名稱 | 外設基地址 | 相對APB2總線地址的偏移 |
GPIOA | 0x0000 0800 | 0x0 |
GPIOB | 0x4001 0C00 | 0x0000 C000 |
GPIOC | 0x4001 0000 | 0x0001 0000 |
GPIOD | 0x4001 1400 | 0x0001 4000 |
GPIOE | 0x4001 1800 | 0x0001 8000 |
GPIOF | 0x4001 C000 | 0x0001 C000 |
GPIOG | 0x4002 0000 | 0x0002 0000 |
(3)確定端口輸入數(shù)據寄存器
其中,
-
位31:16 保留(寫程序時不用管),始終讀為0;
-
位15:0 IDRy[15:0]:端口輸入數(shù)據(y =0…15),這些位為只讀并只能以**字(16位)**的形式讀出。讀出的值為對應I/O口的狀態(tài)。
-------------------------------------------------【總結】-------------------------------------------------
GPIOA下的某個寄存器,掛載在GPIOA下,地址為GPIOA基地址+偏移量
GPIOA掛載在APB2總線,地址為APB2總線基地址+GPIOA偏移量
ABP2掛載加外設基地址,地址為外設基地址+ABP2偏移量
//外部總線基地址
#define PERIPH_BASE ((uint32_t)0x40000000)
//APB2基地址=外部總線基地址+偏移量
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
//GPIOA基地址=APB2基地址+偏移量
#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)
//GPIOA將地址順序分配給7個32位寄存器(結構體分配)
#define GPIOA ((GPIO_TypeDef*)GPIOA_BASE)
//將寄存器地址映射到7個32位寄存器,分別控制
typedef struct
{
__IO unit32_t CRL;
__IO unit32_t CRH;
__IO unit32_t ODR;
__IO unit32_t IDR;
__IO unit32_t BSRR;
__IO unit32_t BRR;
__IO unit32_t LCKR;
}GPIO_TypeDef;
4.實例說明
比如,我們找到 GPIOB 端口的輸出數(shù)據寄存器 ODR 的地址是 0x4001 0C0C,ODR 寄存器是 32bit,低 16bit有效,對應著 16 個外部 IO,寫 0/1 對應的 IO 輸出低/高電平。現(xiàn)在我們通過 C 語言指針的操作方式,讓 GPIOB 的 16 個 IO 都輸出高電平:
(1)通過絕對地址訪問內存單元
1 // GPIOB 端口全部輸出 高電平
2 *(unsigned int*)(0x4001 0C0C) = 0xFFFF;
0x4001 0C0C在我們看來是 GPIOB端口 ODR的地址,但是在編譯器看來,這只是一個普通的變量,是一個立即數(shù),要想讓編譯器也認為是指針,我們得進行強制類型轉換,把它轉換成指針,即(unsigned int *)0x4001 0C0C,然后再對這個指針進行 * 操作。
(2)通過寄存器別名方式訪問內存單元
1 // GPIOB 端口全部輸出 高電平
2 #define GPIOB_ODR (unsigned int*)(GPIOB_BASE+0x0C)
3 * GPIOB_ODR = 0xFF;
(3)通過寄存器別名訪問內存單元
1 // GPIOB 端口全部輸出 高電平
2 #define GPIOB_ODR *(unsigned int*)(GPIOB_BASE+0x0C)
3 GPIOB_ODR = 0xFF;
四、GPIO端口初始化
第三章節(jié)的介紹只是GPIO端口配置的基礎,因為后續(xù)的所有操作都基于寄存器操作,而對于寄存器的操作就是通過訪問地址實現(xiàn)的,因此在正式進行GPIO的初始化之前需要掌握寄存器地址訪問方法。
GPIO口的初始化大致分成三部分:時鐘配置;輸入輸出模式配置;最大速率配置。
1.時鐘配置
任何外設都需要時鐘,51單片機,STM32等等,因為寄存器是由D觸發(fā)器組成的,往觸發(fā)器里面寫東西,前提條件是有時鐘輸入。
51單片機不需要配置時鐘,是因為一個時鐘開了之后所有的功能都可以使用,而在51中這個時鐘是默認開啟的,但是也存在一個問題,耗能大。
STM32之所以是低功耗,因為它將所有的門都默認設置為disable,在你需要用哪個門的時候,開哪個門就可以,也就是說用到什么外設,只要打開對應外設的時鐘就可以,其他的沒用到的可以還是disable,這樣耗能就會減少。
根據數(shù)據手冊可知,撫慰和時鐘控制RCC(時鐘控制)地址從0x4002 1000開始,根據外設偏移地址為0x18,可以確定APB2的地址為0x4002 1018,根據下圖可得GPIOB的時鐘使能控制位為第3位,因此將位3賦值為1,即開啟GPIOB的時鐘
代碼如下:
RCC_APB2ENR |= (1<<3);
2.輸入輸入配置及最大速率的配置
IO:表示“input”、“output”,就可以當作輸入也可以當作輸出,因此需要通過配置來確定狀態(tài)。
STM32的每個IO都需要4位進行配置,因此一個32位的寄存器最大只能配置8個IO(32位的單片機的寄存器就是32位的)。STM32中,用低寄存器(GPIOx_CRL)來配置引腳Px0-Px7, 用高寄存器(GPIOx_CRH)來配置引腳Px8-Px15。
配置引腳PB0,使用的寄存器是GPIOB_CRLCRL 中包含 0-7 號引腳,每個引腳占用 4 個寄存器位。MODE位用來配置輸出的速度,CNF 位用來配置各種輸入輸出模式。
在代碼實現(xiàn)中,先將控制 PB0 的端口位清 0,然后再向它賦值“0001 b”,從而使
GPIOB0 引腳設置成輸出模式,速度為 10M。
五、實例戰(zhàn)斗——仿真點亮LED燈
1.創(chuàng)建工程
在對應保存目錄下創(chuàng)建文件夾LED,之后在keil中創(chuàng)建工程。具體創(chuàng)建步驟,可以轉到答主之前的博客查看。
2.編寫.h文件
(1)添加.h文件
首先在工程中添加頭文件,在“Target1”-“Source group1”,右鍵-“Add New Item…”,在彈出的窗口中選中“.h”文件,填寫文件名保存,到此完成.h文件的添加。
(2)編寫.h文件
連接 LED 燈的 GPIO 引腳,是要通過讀寫寄存器來控制,寄存器就是給一個已經分配好地址的特殊
的內存空間取的一個別名,這個特殊的內存空間可以通過指針來操作。
在編程之前,首先實現(xiàn)寄存器映射,有關寄存器映射的代碼都統(tǒng)一寫在 Led.h 文件中,代碼如下:
/*片上外設基地址 */
#define PERIPH_BASE ((unsigned int)0x40000000)
/*總線基地址,GPIO 都掛載到 APB2 上 */
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
/*GPIOB 外設基地址*/
#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)
/* GPIOB 寄存器地址,強制轉換成指針 */
#define GPIOB_CRL *(unsigned int*)(GPIOB_BASE+0x00)
#define GPIOB_CRH *(unsigned int*)(GPIOB_BASE+0x04)
#define GPIOB_IDR *(unsigned int*)(GPIOB_BASE+0x08)
#define GPIOB_ODR *(unsigned int*)(GPIOB_BASE+0x0C)
#define GPIOB_BSRR *(unsigned int*)(GPIOB_BASE+0x10)
#define GPIOB_BRR *(unsigned int*)(GPIOB_BASE+0x14)
#define GPIOB_LCKR *(unsigned int*)(GPIOB_BASE+0x18)
/*RCC 外設基地址*/
#define RCC_BASE (AHBPERIPH_BASE + 0x1000)
/*RCC 的 AHB1 時鐘使能寄存器地址,強制轉換成指針*/
#define RCC_APB2ENR *(unsigned int*)(RCC_BASE+0x18)
3.編寫main函數(shù)
(1)在工程中添加main函數(shù)
與上述添加頭文件的步驟一樣:
(2)配置引腳為GPIO輸出模式。
把連接到LED 燈的 GPIO 引腳PB0配置成輸出模式,即配置 GPIO 的端口配置低寄存器 CRL。CRL 中包含 0-7 號引腳,每個引腳占用 4 個寄存器位。
其中,MODE位用來配置輸出的速度,CNF 位用來配置各種輸入輸出模式。在這里將 PB0 配置為通用推挽輸出,輸出的速度為 10M,代碼如下:
// 清空控制 PB0 的端口位
GPIOB_CRL&= ~( 0x0F<< (4*0));
// 配置 PB0 為通用推挽輸出,速度為 10M
GPIOB_CRL |= (1<<4*0);
(3)控制引腳輸出電平
在輸出模式時,對端口位設置/清除寄存器 BSRR 寄存器、端口位清除寄存器 BRR 和ODR 寄存器寫入參數(shù)即可控制引腳的電平狀態(tài),其中操作 BSRR 和 BRR 最終影響的都是ODR 寄存器,然后再通過 ODR 寄存器的輸出來控制 GPIO。
為了操作的簡便性,在這里直接操作 ODR 寄存器來控制 GPIO 的電平。代碼如下
1 // PB0 輸出低電平
2 GPIOB_ODR &= ~(1<<0);
(4)時鐘配置
配置完完 GPIO 的引腳,控制電平之后,還需要將對應的時鐘打開,外設才可以工作。
STM32 的所有外設的時鐘由一個專門的外設來管理,叫 RCC(reset and clockcontrol)。所有的 GPIO 都掛載到 APB2 總線上,具體的時鐘由 APB2 外設時鐘使能寄存器(RCC_APB2ENR)來控制,代碼如下:
1 // 開啟 GPIOB 端口 時鐘
2 RCC_APB2ENR |= (1<<3);
(5)編寫main
函數(shù)
1 int main(void)
2 {
3 // 開啟 GPIOB 端口時鐘
4 RCC_APB2ENR |= (1<<3);
5
6 //清空控制 PB0 的端口位
7 GPIOB_CRL &= ~( 0x0F<< (4*0));
8 // 配置 PB0 為通用推挽輸出,速度為 10M
9 GPIOB_CRL |= (1<<4*0);
10
11 // PB0 輸出 低電平
12 GPIOB_ODR |= (0<<0);
13
14 while (1);
15
16 }
其中,在嵌入式編程中,程序需要處于一個無限循環(huán)中,及死循環(huán)。在嵌入式編程中,初始化完成后,單片機就在死循環(huán)內一遍又一遍的執(zhí)行程序邏輯。復位后,就從頭開始,初始化完成后,再次進入死循環(huán)。
六、軟件仿真
1.編譯成功后,調試
2.調試,軟件仿真
(1)編譯成功后,按下調試按鈕“d”,進入調試;
(2)之后,按下菜單欄的系統(tǒng)分析窗口,選擇邏輯分析儀;
(3)進入setup,設置觀察的信號:
(3)點擊運行按鈕,觀察波形:
根據波形,不難得出GPIOB_ODR輸出一直為低電平,led燈常亮。文章來源:http://www.zghlxwxcb.cn/news/detail-418175.html
七、參考文獻:
[1]https://blog.csdn.net/fantastic_sky/article/details/110229474
[2]http://t.csdn.cn/cLnYh
[3]https://blog.csdn.net/geek_monkey/article/details/86291377文章來源地址http://www.zghlxwxcb.cn/news/detail-418175.html
到了這里,關于STM32F1系列簡單介紹及入門學習的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!