【單片機系列】51單片機的內(nèi)存映射(二)
本篇主要講述單片機的FLASH內(nèi)存映射,首先來看一下FLASH的內(nèi)存映射表:

? ? ? 上圖中啟動地址是0x0000,也就是單片機上電后PC指向的這個位置,我們把需要執(zhí)行的程序的首地址放在其中,對應的匯編語言如下圖所示:

? ? ? ? 0地址去執(zhí)行內(nèi)部RAM的初始化工作,后面的代碼控制寄存器指揮PC去取地址,以此來決定程序的運行!
? ? ? ? 在這里大家有沒有覺得很奇怪:51單片機里面為什么沒有時鐘的初始化和中斷向量表的初始化呢?其實原因很簡單, 51單片機對12M晶振的時鐘進行12分頻,它就是固定的1M,因此就不需要設置時鐘了。而STM32就不一樣了,用戶可以隨意配置單片機的工作時鐘。另外還有一個問題,單片機為什么不去中斷向量表的注冊呢?這是因為51在內(nèi)部ROM中做了固定的映射,不需要再去重定向,所以在線升級就很難了。而STM32是支持中斷向量表重定義的,它是將注冊好的中斷向量表搬運到SRAM中去,然后NVIC就會對中斷作出更加快速的響應,顯然51中斷向量表在ROM中,中斷反應就沒有那么迅速了。這就是51單片機不需要做系統(tǒng)時鐘的初始化和注冊中斷向量表的原因。

? ? ? 接下來要做的工作是初始化系統(tǒng)堆棧和可重入函數(shù)棧的初始化,下面是51系統(tǒng)堆棧初始化的匯編代碼:

注意:匯編里面用 ; 號來表示代碼的注釋。
? ? ? ? 棧的大小是可以重新設計的,因為SP初始化的時候它指向的地址是0x07,為了不讓它與中斷向量表和位尋址區(qū)重疊,我們可以將SP設置在30H以后(推薦0x60),即通用RAM區(qū)以后最安全。這是因為一般的C編譯器是將局部變量放入棧中,而C51是將其放入內(nèi)部RAM,開辟一片存儲空間,多個函數(shù)共享該覆蓋區(qū)。【是不是很怪異呢?】這樣我們不得不留出一部分空間給局部變量。其實這并沒什么好奇怪的,51只是單純的想用SP傳遞參數(shù)和保護現(xiàn)場以及恢復現(xiàn)場等功能,這和一些單片機是有區(qū)別的,但是也導致了一些問題,各函數(shù)之間沒有直接或間接的調用關系,則其局部變量空間便可覆蓋。
? ? ? ? 如果一個函數(shù)同時被多個函數(shù)調用,可能會造成某些變量被沖掉,因此C51中的函數(shù)基本上都是不可重入的。也就說明一個問題,51沒法調用遞歸函數(shù),多任務調用同一個函數(shù)時會把一些參數(shù)覆蓋掉。因為他們占用的內(nèi)存地址是一樣的,當然會被沖刷掉啦!!但我們也不必為之煩惱,51為我們提供了如下的解決方案,啟動器文件中的可重入棧的設置和關鍵字reentrant。

? ? ? ? 上圖是設置可重入??臻g的匯編代碼,不過該棧是向上增長的,上面代碼就是初始化了棧頂而已。
? ? ? ? 再看下圖:

這樣,關鍵字reentrant的使用就可以實現(xiàn)函數(shù)的遞歸調用,上圖中的程序就是一個遞歸程序案例,以此來實現(xiàn)一個數(shù)的階乘運算。

再看看我們的ROM是如何擴展的。

? ? ? ? P0是地址總線的低八位,和數(shù)據(jù)總線共用同一個端口,ALE決定了你輸出的是地址還是數(shù)據(jù),幸運的是ALE的高低電平CPU會自動控制,不需要我們?nèi)ゲ僮?。PSEN連接EPROM的片選。最后P2端口連接EPROM的高八位地址總線,這樣就實現(xiàn)了內(nèi)部ROM的擴展。

? ? ? ? 好了,讓我們再來回顧總結一下以上內(nèi)容吧,本篇主要講述了三個方面的內(nèi)容:
? ? ? ?第一,51單片機ROM向量表地址和啟動地址。
? ? ? ?第二,系統(tǒng)棧以及可重入棧的初始化,可重入棧的重要作用(尤其是在可重入函數(shù)傳遞參數(shù)方面的使用)。其實這兩個方面的內(nèi)容也可以說是51單片機進入C世界所進行的大部分設置。
? ? ? ?第三,講述了51單片機在硬件電路設計上擴展ROM(最大可擴展64K.因為只有16跟地址線)的方式。
