微控制器的ROM與RAM

2021-06-09 05:26:27 字數 3096 閱讀 9770

**:

rom:(read only memory)程式儲存器

在微控制器中用來儲存程式資料及常量資料或變數資料,凡是c檔案及h檔案中所有**、全域性變數、區域性變數、』const』限定符定義的常量資料、startup.asm檔案中的**(類似arm中的bootloader或者x86中的bios,一些低端的微控制器是沒有這個的)通通都儲存在rom中。

ram:(random access memory)隨機訪問儲存器

用來儲存程式中用到的變數。凡是整個程式中,所用到的需要被改寫的量,都儲存在ram中,「被改變的量」包括全域性變數、區域性變數、堆疊段。

程式經過編譯、彙編、鏈結後,生成hex檔案。用專用的燒錄軟體,通過燒錄器將hex檔案燒錄到rom中(究竟是怎樣將hex檔案傳輸到mcu內部的rom中的呢?),因此,這個時候的rom中,包含所有的程式內容:無論是一行一行的程式**,函式中用到的區域性變數,標頭檔案中所宣告的全域性變數,const宣告的唯讀常量,都被生成了二進位制資料,包含在hex檔案中,全部燒錄到了rom裡面,此時的rom,包含了程式的所有資訊,正是由於這些資訊,「指導」了cpu的所有動作。

可能有人會有疑問,既然所有的資料在rom中,那ram中的資料從**來?什麼時候cpu將資料載入到ram中?會不會是在燒錄的時候,已經將需要放在ram中資料燒錄到了ram中?

要回答這個問題,首先必須明確一條:rom是唯讀儲存器,cpu只能從裡面讀資料,而不能往裡面寫資料,掉電後資料依然儲存在儲存器中;ram是隨機儲存器,cpu既可以從裡面讀出資料,又可以往裡面寫入資料,掉電後資料不儲存,這是條永恆的真理,始終記掛在心。

清楚了上面的問題,那麼就很容易想到,ram中的資料不是在燒錄的時候寫入的,因為燒錄完畢後,拔掉電源,當再給mcu上電後,cpu能正常執行動作,ram中照樣有資料,這就說明:ram中的資料不是在燒錄的時候寫入的,同時也說明,在cpu執行時,ram中已經寫入了資料。關鍵就在這裡:這個資料不是人為寫入的,cpu寫入的,那cpu又是什麼時候寫入的呢?聽我娓娓道來。

上回說到,rom中包含所有的程式內容,在mcu上電時,cpu開始從第1行**處執行指令。這裡所做的工作是為整個程式的順利執行做好準備,或者說是對ram的初始化(注:rom是唯讀不寫的),工作任務有幾項:

1、             為全域性變數分配位址空間---à如果全域性變數已賦初值,則將初始值從rom中拷貝到ram中,如果沒有賦初值,則這個全域性變數所對應的位址下的初值為0或者是不確定的。當然,如果已經指定了變數的位址空間,則直接定位到對應的位址就行,那麼這裡分配位址及定位位址的任務由「聯結器」完成。

2、             設定堆疊段的長度及位址---à用c語言開發的微控制器程式裡面,普遍都沒有涉及到堆疊段長度的設定,但這不意味著不用設定。堆疊段主要是用來在中斷處理時起「儲存現場」及「現場還原」的作用,其重要性不言而喻。而這麼重要的內容,也包含在了編譯器預設的內容裡面,確實省事,可並不一定省心。平時怎麼就沒發現呢?奇怪。

3、             分配資料段data,常量段const,**段code的起始位址。**段與常量段的位址可以不管,它們都是固定在rom裡面的,無論它們怎麼排列,都不會對程式產生影響。但是資料段的位址就必須得關心。資料段的資料時要從rom拷貝到ram中去的,而在ram中,既有資料段data,也有堆疊段stack,還有通用的工作暫存器組。通常,工作暫存器組的位址是固定的,這就要求在絕對定址資料段時,不能使資料段覆蓋所有的工作暫存器組的位址。必須引起嚴重關注。

這裡所說的「第一行**處」,並不一定是你自己寫的程式**,絕大部分都是編譯器代勞的,或者是編譯器自帶的demo程式檔案。因為,你自己寫的程式(c語言程式)裡面,並不包含這些內容。高階一點的微控制器,這些內容,都是在startup的檔案裡面。仔細閱讀,有好處的。

通常的做法是:普通的flashmcu是在上電時或復位時,pc指標裡面的存放的是「0000」,表示cpu從rom的0000位址開始執行指令,在該位址處放一條跳轉指令,使程式跳轉到_main函式中,然後根據不同的指令,一條一條的執行,當中斷發生時(中斷數量也很有限,2~5個中斷),按照系統分配的中斷向量表位址,在中斷向量裡面,放置一條跳轉到中斷服務程式的指令,如此如此,整個程式就跑起來了。決定cpu這樣做,是這種rom結構所造成的。

其實,這裡面,c語言編譯器作了很多的工作,只是,你不知道而已。如果你仔細閱讀編譯器自帶的help檔案就會知道很多的事情,這是對編譯器了解最好的途徑。

i/o口暫存器:

也是可以被改變的量,它被安排在乙個特別的ram位址,為系統所訪問,而不能將其他變數定義在這些位置。

中斷向量表:

中斷向量表是被固定在mcu內部的rom位址中,不同的位址對應不同的中斷。每次中斷產生時,直接呼叫對應的中斷服務子程式,將程式的入口位址放在中斷向量表中。

rom的大小問題:

對於flash型別的mcu,rom空間的大小通常都是整位元組的,即為ak*8bits。這很好理解,一眼就知道,rom的空間為ak。但是,對於某些otp型別的微控制器,比如holtek或者sonix公司的微控制器,經常看到資料手冊上寫的是「otp progarming rom  2k*15bit。。。。。」,可能會產生疑惑,這個「15bit」認為是1個位元組有餘,2個位元組又不足,那這個rom空間究竟是2k,多於2k,還是4k但是少了一點點呢?

這裡要明確兩個概念:乙個是指令的位寬,另乙個是指令的長度。指令的位寬是指一條指令所佔的資料位的寬度;有些是8位位寬,有些是15位位寬。指令長度是指每條指令所佔的儲存空間,有1個位元組,有2個位元組的,也有3個位元組甚至4個位元組的指令。這個可以打個形象的比方:我們做廣播體操時,有很多動作要做,但是每個複雜的動作都可以分解為幾個簡單的動作。例如,當做伸展運動時,我們只聽到廣播裡面喊「2、2、3、4、5、6、7、8」,而這裡每乙個數字都代表乙個指令,聽到「3」這個指令後,我們的頭、手、腰、腿、腳分別作出不同的動作:兩眼目視前方,左手叉腰,右手往上抬起,五指伸直自然併攏開啟,右腿伸直,左腿成弓步······等等一系列的分解動作,而要做完這些動作的指令只有乙個「3」,要執行的動作卻又很多,於是將多個分解動作合併成乙個指令,而每個分解動作的「位寬」為15bits。實事上也確實如此,當在反彙編或者彙編時,可以看到,復合指令的確是有簡單的指令組合起來的。

到此,回答前面那個問題,這個otp的rom空間應該是2k,指令位寬為15位。一般的,當指令位寬不是8的倍數時,則說明該mcu的大部分指令長度是乙個位元組(注:該位元組寬度為15位,不是8位),極少數為2個或多個位元組,雖然其總的空間少,但是其能容下的空間資料並不少。

微控制器中ROM和RAM

在微控制器中用來儲存程式資料及常量資料或變數資料,凡是c檔案及h檔案中所有 全域性變數 區域性變數 const 限定符定義的常量資料 startup.asm檔案中的 類似arm中的bootloader或者x86中的bios,一些低端的微控制器是沒有這個的 通通都儲存在rom中。ram randoma...

微控制器的RAM 和ROM 儲存了哪些東西?

首先從 編譯的結果來看首先從 編譯的結果來看 text data bss dec aaa bbb ccc ddd 首先text 意思就是 下方數字就是 段所佔空間大小,單位為位元組 byte text 區儲存著 以及常量 const 宣告的常量。data意思就是資料,下方數字就是資料區所佔空間大小,...

10 4 51微控制器RAM區域的劃分

前邊介紹微控制器資源的時候,我們提到過 stc89c52 共有 512 位元組的 ram,是用來儲存資料的,比如我們定義的變數都是直接存在 ram 裡邊的。但是微控制器的這 512 位元組的 ram在地位上並不都是平等的,而是分塊的,塊與塊之間在物理結構和用法上都是有區別的,因此我們在使用的時候,也...