從今天開始的3天,我們會以更底層的角度來了解單晶片的架構,若只是要會使用STM32可以暫時先略過
接觸STM32到現在,是不是還不清楚為什麼他叫STM32而不是STM31或STM33呢?那是因為STM32的CPU為Cortex-M4,由ARM設計,而這個CPU為32位元的處理器。那什麼是32位元的處理器呢?
首先介紹兩個常見的名詞,位(bit)與位元組(byte)。bit是內部資料儲存的最小單位,狀態就只有0、1兩種。而我們通常不會只處理一個位元,計算機中資料的處理基本單位為位元組,1byte = 8bit。再來這個可能比較少人聽過:字(word),計算機進行資料處理時,一次處理、傳送的長度稱為字。更具體一點的來說,CPU與各單元、周邊設備溝通時是使用排線所組成的匯流排(bus),而32位元處理器就是有32個排線所組成的匯流排(32稱為匯流排寬度,也就是1個word的大小),一次4bytes的資料。
剛剛所說的匯流排更詳細的說應稱為資料匯流排(data bus),而還有另一種匯流排為位址匯流排(address bus),一個處理器寬度為32的匯流排,可定址的大小為2^32,也就是4GB。而一般資料匯流排的大小與位址匯流排的大小是相同的。因此STM32可以定址的大小最大為4GB,若我們以十六進位表示則為0x00000000~0xFFFFFFFF(0x表示以16進位表示法表示)
定址在了解底下記憶體映射之後會比較好理解
而一般來說資料匯流排為雙向的,CPU可以傳送資料給記憶體(寫入),記憶體也可以傳送資料給CPU(讀取),而位址匯流排為單向,通常只要CPU告訴記憶體你現在所要操作的記憶體位址即可
記憶體本身是沒有位址的,記憶體內部就只是一堆半導體元件(AND、OR邏輯閘等),就好像一個社區,裡面有很多棟房子,起初這些房子是沒有門牌的,且每一棟房子都長一樣,後來才按照順序的幫它編號。實際上我們就是利用32條線所組成的位址匯流排,每一根線的電位高低不同來為記憶體編號,於是每個記憶體也就有了所謂的地址。
這裡所說的映射與數學上的映射道理是相同的。在集合論當中,若A中的任一元素x,依照某種規律,必有B中唯一確定的元素與y對應,則稱f是一個從A到B的映射
但要強調的是32的意思是最大可以定址的大小為32bytes,並不代表有這麼大的記憶體,繼續以社區來做舉例,我們可以從1編號到1000,但可能只有其中的1~100、301~400是有對應到房子的。另外稍微想一下,一般筆電差不多是8G的記憶體,如果一個單晶片上有4G的記憶體,那豈不是都快跟電腦一樣了。
那既然沒有這麼大的記憶體,那為什麼我們需要定址到這麼大呢?因為我們並不想讓所有的記憶體位址全部連在一起,通常我們會做初步的分類,如下圖:
上面的圖稱為記憶體圖(memory map),在這4GB的地址空間中,大致被分為8塊(Block),每塊的大小都有512MB,這還是相當大的,一般只用其中的一小部分。
序號 | 用途 | 地址範圍 |
---|---|---|
Block0 | SRAM | 0x0000 0000 ~ 0x1FFF FFFF(512MB) |
Block1 | SRAM | 0x2000 0000 ~ 0x3FFF FFFF(512MB) |
Block2 | 單晶片上外設 | 0x4000 0000 ~ 0x5FFF FFFF(512MB) |
Block3 | FMC | 0x6000 0000 ~ 0x7FFF FFFF(512MB) |
Block4 | FMC | 0x8000 0000 ~ 0x9FFF FFFF(512MB) |
Block5 | FMC | 0xA000 0000 ~ 0xBFFF FFFF(512MB) |
Block6 | FMC | 0xC000 0000 ~ 0xDFFF FFFF(512MB) |
Block7 | Cortex-M4 內部外設 | 0xE000 0000 ~ 0xFFFF FFFF(512MB) |
我們對STM32的記憶體掌握大致分成兩個,分別是快閃記憶體,簡稱Flash,與靜態隨機儲存記憶體,簡稱SRAM,這兩種記憶體的特性不同,Flash在沒有電源時資料仍然能儲存,這也是我們程式存放的位置(想像我們在做機器人的時候,並不需要每次都上傳程式碼,即使沒有電源,Flash仍會記得上次上傳的程式),而SRAM則是關電會導致資料不見(具有揮發性)。 |
用途說明 | 地址範圍 |
---|---|
APB1外設 | 0x4000 0000 ~ 0x4000 7FFF(32KB) |
預留 | 0x4000 8000 ~ 0x4000 FFFF |
APB2外設 | 0x4001 0000 ~ 0x4001 6BFF(~27KB) |
預留 | 0x4001 6C00 ~ 0x4000 7FFF |
AHB1外設 | 0x4002 0000 ~ 0x4007 FFFF(~384KB) |
預留 | 0x4008 0000 ~ 0x4FFF FFFF |
AHB2外設 | 0x5000 0000 ~ 0x5006 0BFF(~387KB) |
預留 | 0x5006 0C00 ~ 0x 5FFF FFFF |
今天大致介紹了STM32記憶體的架構,以及記憶體映射的概念,明天開始我們就要來真正的探究這些記憶體是如何存放資料決定GPIO是輸入還是輸出、輸出高電位還是低電位...各種設定。也會引入暫存器的概念。今天的內容實在是不容易,我在撰寫的時候也查閱了大量的書籍以及資料,內容若是有誤,再請各位指正。