大家好,我是杰哥嵌入式開發(fā)
最近在出定時器系列,
但是線下班有一些學(xué)生在學(xué)習(xí)完C語言之后,
在51接觸各種寄存器和對軟件代碼各種操作是如何在單片機(jī)系統(tǒng)中起到作用的感到非常的不解,
經(jīng)過我的初步分析,是對嵌入式微機(jī)系統(tǒng)的大概雛形系統(tǒng)框架不熟悉導(dǎo)致。
所以我決定出一期基于STM32的系統(tǒng)框架介紹博客。
歡迎大家關(guān)注我的gitee倉庫:
gitee源碼倉庫鏈接跳轉(zhuǎn)
STM32微機(jī)系統(tǒng)框架、內(nèi)存、存儲器、寄存器
微型計(jì)算機(jī)系統(tǒng)組成框圖
來分析一下這個框圖:
眾所周知,計(jì)算機(jī)在發(fā)展初期就是上千萬個晶體管堆疊而成的
逐步發(fā)展成現(xiàn)在的第四代微型集成電路計(jì)算機(jī)
不管是咱們得51 32 香橙派,你們會發(fā)現(xiàn)中間的那個芯片都是由CPU和片上外設(shè)組成
在此基礎(chǔ)上增加外部輸入輸出設(shè)備 如網(wǎng)口、USB、DDR、EMMC等。
這一硬件體系結(jié)構(gòu)采用的是什么,是我們大學(xué)學(xué)計(jì)算機(jī)課經(jīng)常聽到的馮.諾依曼體系
還有另一個叫什么?你們來說!
馮.諾依曼體系的設(shè)計(jì)思想:
1 以二進(jìn)制形式表示指令和數(shù)據(jù)。(計(jì)算機(jī)的語言)
2 程序和數(shù)據(jù)事先存放在存儲器中,計(jì)算機(jī)在工作時能夠高速地從存儲器中取出指令加以執(zhí)行。(內(nèi)存映射)
3 由運(yùn)算器、控制器、存儲器、輸入設(shè)備和輸出設(shè)備等五大部件組成計(jì)算機(jī)硬件系統(tǒng)。 (通過總線結(jié)構(gòu)交互)
下面我們會拿STM32的硬件系統(tǒng)架構(gòu)來講解,講解之前要讓大家了解上面流程圖中各個專業(yè)名詞的定義,讓大家對通用微機(jī)系統(tǒng)有一個基礎(chǔ)文字定義的印象,然后在這里不要問我,我也不會,哈哈哈:
控制器(控制單元CU ):全機(jī)的指揮控制中心。負(fù)責(zé)讀取指令,指令譯碼,形成各種定時控制信號,向內(nèi)部各功能單元發(fā)送相應(yīng)的控制命令,協(xié)調(diào)各部件之間的工作。
寄存器陣列(RA)
相當(dāng)于微處理器內(nèi)部的RAM,用于暫存數(shù)據(jù)和運(yùn)算結(jié)果。我也沒看懂 可以理解為我們上次講的CPU中的cache吧
運(yùn)算器(算數(shù)邏輯單元ALU)
用來進(jìn)行算數(shù)或邏輯運(yùn)算以及移位循環(huán)等操作。
存儲器
計(jì)算機(jī)系統(tǒng)的記憶裝置,用來存儲程序和數(shù)據(jù)。
按工作方式,內(nèi)存可分為兩大類:
隨機(jī)讀寫存儲器RAM(Random Access Memory) 如內(nèi)存條、DDR2 3 4 5
和只讀存儲器ROM(Read Only Memory) 機(jī)械硬盤 固態(tài)硬盤 flash TF-sd卡 emmc
以后面試問你們記得這么說:
- 隨機(jī)讀寫存儲器可被CPU隨機(jī)地讀寫,它用于存放將要被CPU執(zhí)行的用戶程序、數(shù)據(jù)以及部分系統(tǒng)程序。
斷電后,其中存放的所有信息將丟失。 - 只讀存儲器中的信息只能被CPU讀取,而不能由CPU任意地寫入。斷電后,其中的信息不會丟失。
它用于存放永久性的程序和數(shù)據(jù)。如系統(tǒng)引導(dǎo)程序、監(jiān)控程序、操作系統(tǒng)中的基本輸入/輸出管理程序(BIOS)等。
總線
連接微型計(jì)算機(jī)各組成部分的一組信號線,包括 地址總線AB、數(shù)據(jù)總線DB、控制總線CB 等三類。
地址總線AB:在對存儲器或I/O端口進(jìn)行訪問時,
傳送由CPU提供的要訪問存儲單元或I/O端口的地址信息,
以便選中要訪問的存儲單元或I/O端口,是單向總線。
數(shù)據(jù)總線DB:從存儲器取指令或讀寫操作數(shù),對I/O端口進(jìn)行讀寫操作時,
指令碼或數(shù)據(jù)信息通過數(shù)據(jù)總線送往CPU或由CPU送出,是雙向總線。
控制總線CB:各種控制或狀態(tài)信息通過控制總線由CPU送往有關(guān)部件,
或者從有關(guān)部件送往CPU。CB中每根線的傳送方向是一定的。
系統(tǒng)軟件
面向計(jì)算機(jī)的軟件:操作系統(tǒng)、監(jiān)控程序、I/O驅(qū)動程序、編譯與解釋程序和各種診斷、檢查、引導(dǎo)程序等
面向用戶的軟件:各種程序設(shè)計(jì)語言、實(shí)用程序、字處理程序等
應(yīng)用軟件
為了解決各類實(shí)際問題,利用計(jì)算機(jī)以及它所提供的各種系統(tǒng)軟件,編寫解決各種實(shí)際問題的程序。
STM32的硬件系統(tǒng)架構(gòu)
微型計(jì)算機(jī)的硬件系統(tǒng)由微處理器、存儲器、輸入設(shè)備、輸出設(shè)備和系統(tǒng)總線組成。
那stm32呢 是不是也是這個規(guī)律,我們一起來看看:
STM32由驅(qū)動單元、FLASH、SRAM、片上外設(shè)和總線矩陣組成
我們一起來看看STM32芯片手冊的系統(tǒng)結(jié)構(gòu)圖
這是手冊的解釋:
在小容量、中容量和 大容量產(chǎn)品中,主系統(tǒng)由以下部分構(gòu)成:
● 四個驅(qū)動單元:
─ Cortex?-M3內(nèi)核DCode總線(D-bus),和系統(tǒng)總線(S-bus)
─ 通用DMA1和通用DMA2
● 四個被動單元
─ 內(nèi)部SRAM
─ 內(nèi)部閃存存儲器
─ FSMC
─ AHB到APB的橋(AHB2APBx),它連接所有的APB設(shè)備
這些都是通過一個多級的AHB總線構(gòu)架相互連接的
說的還是蠻清楚的啊,看不懂?那我來翻譯翻譯?。?!
左邊三個方框和一個梯形是處理器 由1個cortex-m3核、2個dma和內(nèi)核系統(tǒng)總線組成
(DMA不懂?理解成受精卵版的4090吧)
右邊其他的就是片上外設(shè) 如片內(nèi)的ROM即flash、RAM即SRAM、FSMC即用于連接外部存儲的總線,
還有通過AHB橋接到各種各樣的GPIO、TIM、ADC等等等等。
驅(qū)動單元
芯片手冊上有的就不多說了,上圖自己看。
- 內(nèi)核通過ICode 總線讀取內(nèi)部FLASH代碼指令來執(zhí)行程序.
- DCode這條總線是用來取數(shù)據(jù)的.
- DMA總線與DCode總線一樣主要是用來傳輸數(shù)據(jù),但Dcode總線傳輸數(shù)據(jù)要占用內(nèi)核(cpu)的資源,而DMA總線相當(dāng)于獨(dú)立于內(nèi)核cpu但幫助內(nèi)核cpu傳輸數(shù)據(jù)而不用占用內(nèi)核(cpu)的資源,就是在DMA傳輸數(shù)據(jù)的同時內(nèi)核cpu可以干別的事情比如點(diǎn)亮一個LED燈
- 總線矩陣協(xié)調(diào)內(nèi)核系統(tǒng)總線和DMA主控總線之間的訪問仲裁
被動單元
- FLASH、SRAM這些平時線下班面試題都有說,堆、棧是什么,什么區(qū)別、const是什么、malloc是什么、局部變量是什么、 內(nèi)存分布圖等,相信大家都非常熟悉了
- 內(nèi)存分布說明:
內(nèi)核空間: 放置操作系統(tǒng)相關(guān)的代碼和數(shù)據(jù)。(用戶不能直接進(jìn)行操作 ------ 可以通過調(diào)用系統(tǒng)提供的api函數(shù))
棧又叫堆棧,非靜態(tài)局部變量/函數(shù)參數(shù)/返回值等等,棧是向下增長的。
內(nèi)存映射段是高效的I/O映射方式,用于裝載一個共享的 動態(tài)內(nèi)存庫。用戶可使用系統(tǒng)接口創(chuàng)建共享共享內(nèi)存,做進(jìn)程間通信。
堆用于程序運(yùn)行時動態(tài)內(nèi)存分配,堆是可以上增長的。
數(shù)據(jù)段–存儲全局?jǐn)?shù)據(jù)和靜態(tài)數(shù)據(jù)。
代碼段–可執(zhí)行的代碼/只讀常量。
- FSMC可以用來拓展內(nèi)存的控制器,以后大家工作可能接觸的到
- AHB到APB的橋:掛載著STM32各種各樣的特色外設(shè) GPIO、串口、I2C、SPI。學(xué)習(xí)單片機(jī)的重點(diǎn),就是要學(xué)會編程這些外設(shè)去驅(qū)動外部的各種設(shè)備
內(nèi)存映射
存儲器映射
所以 知道了系統(tǒng)框圖之后,知道了系統(tǒng)有哪些東西之后,有什么用?
我們還是對他們的之間的工作關(guān)系感覺非常的模糊
如:
- 外設(shè)的寄存器怎么訪問和控制,通過地址 地址哪來的?
- 總線怎么讀的FLASH?
我嘗試解釋給大家,好吧!
就是內(nèi)存映射,其實(shí)應(yīng)該是存儲器映射,
我搜了好幾篇博客都這么叫,那就這么叫吧,可能我對內(nèi)存映射有點(diǎn)誤解。
咱們用的這個存儲器,他本身是不具備地址信息的,他的地址是板子啟動初始化的時候分配的,
那這個給存儲器分配地址的過程被稱為存儲器映射,
你可能以為我說的存儲器是RAM、ROM,
但其實(shí)STM32的所有片內(nèi)外設(shè)其實(shí)都是存儲器,
他們都會被映射到一個4GB的線性地址空間內(nèi)
數(shù)據(jù)字節(jié)以小端格式存放在存儲器中
(什么是小端,低地址放低位,高地址放高位)
4GB
又衍生出來一個問題,那為什么是4GB的地址空間?
因?yàn)?存儲空間的大小是由芯片內(nèi)CPU內(nèi)的地址總線的數(shù)量來決定的,而stm32芯片內(nèi)部的總線為32根
2的32次方等于4GB
232B/210/210/210 = 2^2GB = 4GB
所以!STM32中的32是32根地址線?
NO!32位的單片機(jī)的地址線數(shù)量8、16根的都可以
STM32剛好碰巧的是CPU能夠處理的數(shù)據(jù)位寬與地址線數(shù)量恰好都是32
所以什么是CPU能夠處理的數(shù)據(jù)位寬?
MCU芯片內(nèi)部CPU在處理數(shù)據(jù)時,每次可以處理的數(shù)據(jù)位寬為32個bit。
正是由于這個原因,STM32內(nèi)部的寄存器大小都是32位
如果現(xiàn)在一款32單片機(jī)的地址線是8,
那他要訪問一個32位的內(nèi)部寄存器數(shù)據(jù)時,
他可以讀取4次寄存器數(shù)據(jù)到CPU中,cpu一次對這32個位進(jìn)行處理
懂了吧! 我們繼續(xù)。
看看stm32的內(nèi)存映射圖
地址其實(shí)就是門牌號,存儲中的每個字節(jié)就是房間,
存儲器生產(chǎn)出來后,這些房間是沒有地址的(門牌號),
映射的過程其實(shí)就是將這些門牌號分配給這些房間,
分配好后,每個門牌號只能訪問自己的房間,
沒有被分配的地址就是保留地址,
所謂保留地址的意思就是,沒有對應(yīng)實(shí)際存儲空間。
上面的內(nèi)存映射圖4G的空間里 32把他們分成8塊 每塊512M
其中最重要的是代碼區(qū)、靜態(tài)RAM、片上外設(shè)
代碼區(qū)
我們平時寫的代碼就是放到代碼區(qū)的0x0800 0000~0x0807 FFFF
一共512KB,但是咱們上官二號stm32f1就128KB的flash 所以映射也只會使用128KB
可以看MDK-Keil中的jlink燒錄選項(xiàng)界面,就有說燒錄的地址范圍 開始 大小
也提到了RAM的開始地址的大小
這里有個東西跟大家說一下 既然我們燒錄代碼到0x0800 0000之后
可是又印象中說 代碼是從地址0x0開始的,是為什么?
地址重映射!
本來沒有東西 然后還有一個大家影響中的東西叫做啟動方式
stm32可以通過BOOT[1:0]引腳選擇三種不同啟動模式
可以選擇將0x00000000-0x001FFFFF映射到不同的存儲器上
默認(rèn)大部分都是映射的flash 所以這就說的通了
上面代碼區(qū)映射圖里還有個system memory和option bytes
那個是系統(tǒng)存儲器存儲用于存放在系統(tǒng)存儲器自舉模式下的啟動程序(BootLoader),
當(dāng)使用ISP方式加載程序時,就是由這個程序執(zhí)行。
這個區(qū)域由芯片廠寫入BootLoader,然后鎖死,用戶是無法改變這個區(qū)域的。
選項(xiàng)字節(jié)存儲芯片的配置信息及對主存儲塊的保護(hù)信息。
所以stm32也可以像51一樣用串口下載
但是在用串口燒錄代碼的時候需要改變啟動模式到系統(tǒng)存儲器
串口燒錄完,還要把boot引腳改回主閃存存儲器啟動模式
有小伙伴自己學(xué)過stm32,用到過燒錄程序flymcu,這個軟件比較厲害
可以通過DTR和RTS改變BOOT的引腳電平,
達(dá)到不用修改BOOT引腳就可以下載運(yùn)行代碼,
實(shí)際上是軟件替我們做了改變BOOT引腳的操作
以上說的是ISP,
然后還有個IAP是我們自己在flash里面寫用戶自己的bootloader
可以玩的很花,你們自行YY
靜態(tài)ram
這個好像沒什么好講的
不同的型號內(nèi)置sram不一樣 所以性能不一樣
越大越好 越大越貴 甚至能跑圖形界面等等
所以有了FSMC可以外接SDRAM
上官二號好像沒有FSMC外設(shè) 就那幾個引腳 確實(shí)不太夠用
片上外設(shè)
寄存器映射
可算到這了 這個是很多同學(xué)懵逼的地方
寄存器初始化 讀寫這些 很模糊
對單片機(jī)的軟件硬件之間的控制到底哪里來的 在這里可以得到答案
前面內(nèi)存映射圖里面還有一個peripherals外設(shè) 就是片內(nèi)外設(shè)的映射圖
什么是寄存器 給特定功能的的單元取的別名這個別名就叫做寄存器
怎么用寄存器 通過寄存器地址去訪問
地址哪里來 單片機(jī)硬件幫我們把這些映射到內(nèi)存中
這些片上外設(shè)們以四個字節(jié)為一個單元,共32bit,
每一個單元對應(yīng)不同的功能,當(dāng)我們控制這些單元時就可以驅(qū)動外設(shè)工作。
我們可以找到每個單元的起始地址,然后通過C語言指針的操作方式
(既然一個單元是四個字節(jié)那我們就用一次取四個字節(jié)的指針(int *)來操作這些功能單元)
來訪問這些單元,如果每次都是通過這種地址的方式來訪問,
不僅不好記憶還容易出錯,這時我們可以根據(jù)每個單元功能的不同,
以功能為名給這個內(nèi)存單元取一個別名,
這個給已經(jīng)分配好地址的有特定功能的內(nèi)存單元取別名的過程就叫 寄存器映射。
我們想要操作一個外設(shè) 比如GPIOA_Port1
可能是讀取狀態(tài) 可能是設(shè)置狀態(tài), 初始化其實(shí)就是在設(shè)置狀態(tài)
那就需要操作對應(yīng)的寄存器,首先得到GPIOA_Port1的基地址
后根據(jù)要設(shè)置的狀態(tài)所在寄存器位置進(jìn)行地址偏移,即可到達(dá)目標(biāo)點(diǎn)并進(jìn)行讀寫操作
各個寄存器的地址=外設(shè)基地址+寄存器相對于外設(shè)基地址的偏移
51大家都玩過 我就不解釋了 就是你們對那些TMOD TL0 TH0進(jìn)行位操作
都是51頭文件庫幫你們封裝好的寄存器地址
如果大家想嘗試自己用寄存器開發(fā)就是要自己去算去偏移寄存器地址
總結(jié)
這篇就是用來幫助大家拓展微機(jī)系統(tǒng)知識的 不講具體技術(shù)細(xì)節(jié)
讓第一次接觸到單片機(jī)開發(fā)的同學(xué)不那么恐懼
誒 這個變量哪里來的 都沒初始化啊
誒 這個怎么就對它直接 與&或|操作了 我都不知道里面是啥
誒 我這個搞進(jìn)去 怎么就單片機(jī)會有反應(yīng)了 那樣搞進(jìn)去為啥沒反應(yīng)了
我們目前這種學(xué)習(xí)環(huán)境還相對理想
這樣的解釋也足夠了
希望對大家有所幫助?。?!文章來源:http://www.zghlxwxcb.cn/news/detail-742417.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-742417.html
到了這里,關(guān)于STM32微機(jī)系統(tǒng)框架、內(nèi)存、存儲器、寄存器的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!