單片機與程序設計(下)
引導程序的運行D程序計數器
本文引用地址:http://dyxdggzs.com/article/201808/385982.htm一般來(lái)說(shuō),程序就是計算機將所要進(jìn)行的處理按順序排列的指令集。在單片機中,將程序保存在地址空間(存儲器空間)中(上期曾介紹過(guò)),并由CPU來(lái)執行(處理)指令。假設地址空間中的一個(gè)地址保存一條指令,先執行某個(gè)地址中的指令(如“將值置位到CPU中”處理),接著(zhù)執行下一個(gè)地址中的指令,接下來(lái)再執行下一個(gè)地址中的指令……,像這樣通過(guò)連續執行指令,便可執行程序。
那么,CPU是如何判斷執行指令的順序呢?在單片機中,程序被執行的時(shí)候“程序計數器(PC)”的值也同時(shí)被更新。存放在CPU內的指令地址中,程序計數器存儲有下一條CPU將要執行的指令所在的地址。執行了某個(gè)地址的指令后,下一個(gè)該執行哪個(gè)地址中的指令呢?這個(gè)答案由程序計數器來(lái)告訴你。
一般來(lái)說(shuō),程序被保存在連續的地址中,再由CPU按順序執行存放在各個(gè)地址中的指令。圖1為程序計數器的示意圖。圖中,假定(1)執行地址1000h 中的指令,(2)執行地址1000h中的指令后,程序計數器的自動(dòng)增加一個(gè)量并顯示出下一個(gè)地址1001h,接下來(lái),(3)CPU執行地址1001h中的指令。

那么,CPU執行最初的指令時(shí)是一種什么狀況呢?單片機在接通電源或是復位時(shí),如上期所說(shuō)明的,保存在向量表的復位地址中的(程序的起始地址)將被轉移到程序計數器中,該地址中的指令便得到執行(請參照上期的圖2)。
⇒關(guān)于地址空間及向量表的內容,請參照本系列的第五期《單片機與程序設計(上)》。
改變程序的運行路徑D轉移指令
編寫(xiě)程序時(shí),在執行完某個(gè)指令的處理后有時(shí)必須先執行保存“(非連續)的下一個(gè)地址”中的指令。此時(shí),程序計數器的值將被改寫(xiě),而所用的指令被稱(chēng)為“轉移指令”。
圖2所示是轉移指令的示意圖。圖2示例中,(1)地址1000h中存放有轉移指令,即將(2)程序計數器的值改寫(xiě)為下一個(gè)應執行的地址(1100h)的指令。即CPU執行完1000h地址的指令(轉移指令)后,接下來(lái)不是執行1001h地址的指令,而是執行(3)1100h地址的指令。

另外,在轉移指令中,能夠利用“從當前的程序計數器的值向前(更大的地址)/向后(更小的地址)移動(dòng)”的方法來(lái)設定程序計數器的值。
信息的暫時(shí)存放處D堆棧
執行程序時(shí),在運算過(guò)程中僅僅依靠CPU內的數據保存位置(CPU內部寄存器)是不夠的,有時(shí)需在主存儲器中暫時(shí)存放信息。這種信息的暫時(shí)存放位置被稱(chēng)為“堆棧”,而存放“下一個(gè)(暫時(shí))存放的信息地址”的就是“堆棧指針(SP)”。如果一開(kāi)始就設定好堆棧的地址,那么堆棧指針將自動(dòng)更新,且總是指示 “下一個(gè)(暫時(shí))存放的信息地址”。
⇒CPU內部寄存器等單片機的結構請參照《單片機入門(mén)(1)》。
如果執行“將該信息存放(有時(shí)也用“堆積”)在堆棧”的指令,那么被指定的信息將會(huì )被寫(xiě)入堆棧指針所指定的地址中,且堆棧指針的值也將被更新為新的地址(一般為一個(gè)小地址)。該情形如圖3所示。如果(1)CPU將信息存放在堆棧指針所指的地址中,則(2)堆棧指針的將被更新,然后(3)堆棧指針指向下一個(gè)存放信息的位置。

將存放在堆棧中的信息返回CPU時(shí),也將用到堆棧指針。圖4所示的是將信息返回時(shí)的情形。(1)更新堆棧指針的(更新為一個(gè)大的地址),(2)將暫時(shí)存放在堆棧中的信息返送回CPU。此時(shí),(3)堆棧指針指向下一個(gè)寫(xiě)入地址(先前將信息返回CPU后空出的地址)。

但是堆棧中并非可無(wú)限制地保存信息。由于堆棧能使用的范圍僅限于可改寫(xiě)的被稱(chēng)為RAM的存儲器。如果信息存放量過(guò)多而導致堆棧超出了RAM的區域,程序將無(wú)法正常運行。
理解中斷處理
本期是本系列的最后一期。下面我們將以前介紹過(guò)的內容進(jìn)行一個(gè)總結,并以此來(lái)理解單片機是如何運行(處理)的。
我們將以發(fā)生中斷時(shí)的處理為例來(lái)進(jìn)行思考(圖5)。中斷處理就是指在執行某個(gè)程序的過(guò)程中,由于某種原因(產(chǎn)生中斷)而導致開(kāi)始執行完全不同的程序。我們以來(lái)自外設功能之一的獨立的看門(mén)狗計時(shí)器(WDT、所謂的Watch Dog即看門(mén)狗的意思)的中斷為例來(lái)進(jìn)行分析。在程序正常運行時(shí)獨立的看門(mén)狗定時(shí)器將什么也不做,但是在程序失去控制,且沒(méi)有按必要的步驟進(jìn)行處理時(shí)就會(huì )產(chǎn)生中斷。使失去控制的程序停下并讓系統穩定停止的處理是由通過(guò)中斷開(kāi)始的程序來(lái)執行的。中斷處理的流程請參照本系列《中斷功能》的圖2。
⇒關(guān)于中斷的結構和處理流程請參照本系列《中斷功能》的內容。
⇒關(guān)于看門(mén)狗定時(shí)器請參照本系列的《定時(shí)器》的內容。

(1)首先,在產(chǎn)生中斷時(shí),必須使運行中的程序入棧。
(2)在中斷處理 “入棧”時(shí),將信息存放在堆棧指針指向的地址(堆棧)中。進(jìn)行中斷處理時(shí)存放在堆棧中的信息就是正在執行的原先的程序(被中斷的程序)時(shí)的程序計數器的值,即原先的程序執行到哪一步的信息(地址)。另外,顯示CPU內部狀態(tài)的信息和暫時(shí)保存的值也存放在堆棧中。
(3)如果CPU內部的信息存放在堆棧中且完成“交付”準備(入棧)后,將執行中斷程序。中斷程序與正在執行的程序不同且所保存的地址空間也不同,所以程序計數器的值與原先程序也完全不同。中斷程序的起始位置將被寫(xiě)入向量表中。起始位置該寫(xiě)在向量表中的哪一項取決于所產(chǎn)生的中斷。
評論