0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

單片機的程序結(jié)束后都干嘛去了?

jf_pJlTbmA9 ? 來源:TsinghuaJoking公眾號 ? 作者:TsinghuaJoking公眾號 ? 2023-10-17 17:16 ? 次閱讀

對于嵌入式系統(tǒng),如果沒有運行RTOS,那么程序開發(fā)中的主函數(shù)main()需要通過某種機制使其永遠(yuǎn)愉快的運行下去,它沒有終點。如果想從main函數(shù)中退出,具體干什么是由所使用的C語言編譯器決定的。

一、問題提出

今天在單片機led模塊定義函數(shù)中看到一個有趣的問題。提問者在進行基本的C51編程實驗,編寫了一個簡單的C51程序如下:

#include 

void test(num) {
    switch(num) {
        case 1: P2_0=0; P2_1=0; 
            break;
    }
}

void main(void) {
    test(1);
}

程序執(zhí)行完之后,可以看到實驗板上的有兩個LED被點亮,另外六個居然微微發(fā)亮。

wKgaomUD3cCAN5uTAA1RmE0XHgg376.png

如果在主程序中,增加一個無限循環(huán):while(1); ,則電路板上的就不再會出現(xiàn)“微微點亮”的現(xiàn)象了。

#include 

void test(num) {
    switch(num) {
        case 1: P2_0=0; P2_1=0; 
            break;
    }
}

void main(void) {
    test(1);
    while(1);
}

上面兩種情況的區(qū)別,在于第二個程序中主循環(huán) main()函數(shù)始終沒有退出,而第一個程序,main()函數(shù)退出了。似乎前面LED微微點亮 應(yīng)該與主函數(shù)退出之后,單片機都干了些啥有關(guān)系。

那么就剩下一個問題:對于普通的嵌入式系統(tǒng),C語言編程中main()函數(shù)退出之后,程序去哪兒了?

二、程序去哪兒了?

從上面提問者書寫的代碼來看,應(yīng)該是一位C51的愛好者,使用的是C51的編譯器,在一款C51開發(fā)板上愉快的進行實驗。他一開始沒有安裝嵌入式程序開發(fā)的慣例 在主程序void main(void)中利用無限循環(huán)將程序控制在主程序函數(shù)中,就出現(xiàn)了前面實驗結(jié)果中令人迷惑的情況。

“注:他是一個膽大心細(xì)的人,觀察還挺仔細(xì)的?!?/p>

2.1 盤古開天辟地

對于C語言編程來說,所有的用戶程序世界是從主程序main()開始的。給用戶程序開天辟地的任務(wù)是由一小段盤古代碼STARTUP.A51。

51單片機程序執(zhí)行流程(STARTUP.A51管理Main函數(shù)的執(zhí)行)

下面截取了STARTUP.A51 代碼的一段,可以看到盤古在單片機RESET之后做了點準(zhǔn)備工作(初始化全局變量、堆棧指針)之后,就直接跳轉(zhuǎn)至:?C_START

NAME    ?C_STARTUP

?C_C51STARTUP   SEGMENT   CODE
?STACK          SEGMENT   IDATA

                RSEG    ?STACK
                DS      1

                EXTRN CODE (?C_START)
                PUBLIC  ?C_STARTUP

                CSEG    AT      0
?C_STARTUP:     LJMP    STARTUP1

                RSEG    ?C_C51STARTUP

STARTUP1:

IF IDATALEN <> 0
                MOV     R0,#IDATALEN - 1
                CLR     A
IDATALOOP:      MOV     @R0,A
                DJNZ    R0,IDATALOOP
ENDIF

IF XDATALEN <> 0
                MOV     DPTR,#XDATASTART
                MOV     R7,#LOW (XDATALEN)
  IF (LOW (XDATALEN)) <> 0
                MOV     R6,#(HIGH (XDATALEN)) +1
  ELSE
                MOV     R6,#HIGH (XDATALEN)
  ENDIF
                CLR     A
XDATALOOP:      MOVX    @DPTR,A
                INC     DPTR
                DJNZ    R7,XDATALOOP
                DJNZ    R6,XDATALOOP
ENDIF

IF PPAGEENABLE <> 0
                MOV     PPAGE_SFR,#PPAGE
ENDIF

IF PDATALEN <> 0
                MOV     R0,#LOW (PDATASTART)
                MOV     R7,#LOW (PDATALEN)
                CLR     A
PDATALOOP:      MOVX    @R0,A
                INC     R0
                DJNZ    R7,PDATALOOP
ENDIF

IF IBPSTACK <> 0
EXTRN DATA (?C_IBP)

                MOV     ?C_IBP,#LOW IBPSTACKTOP
ENDIF

IF XBPSTACK <> 0
EXTRN DATA (?C_XBP)

                MOV     ?C_XBP,#HIGH XBPSTACKTOP
                MOV     ?C_XBP+1,#LOW XBPSTACKTOP
ENDIF

IF PBPSTACK <> 0
EXTRN DATA (?C_PBP)
                MOV     ?C_PBP,#LOW PBPSTACKTOP
ENDIF

                MOV     SP,#?STACK-1
                LJMP    ?C_START

                END
上面的代碼也被博文51單片機程序執(zhí)行流程(STARTUP.A51)中進行逐步調(diào)試跟蹤驗證過:

wKgaomUD3caAYpp7AAG4gK1aF2U913.png

2.2 世界盡頭

由于進入main()函數(shù)是長跳轉(zhuǎn),所以main函數(shù)是不會正常返回到啟動程序STARTUP.A51,那么程序去哪了?

在博文單片機C語言while(1)的問題中作者對于KEIL編譯器和PIC的MAPLAB編譯器對于main函數(shù)的最后時光進行了反匯編查看。

Keil編譯器

在main函數(shù)的最后,程序增加了一下幾行代碼:

MOV R0, #0x7F
CLR A
MOV @R0, A
DJNZ R0, (3)
MOV SP, #0x0C
LJMP main
這幾條語句,前4條,是將我們單片機的內(nèi)存的前128個地址清零,第5條,是定義堆棧,第6條,是將程序重新跳轉(zhuǎn)到main函數(shù)的首行進行執(zhí)行。

MAPLAB編譯器

PIC 單片機語言程序進行跟蹤,發(fā)現(xiàn)main() 函數(shù)最后一條語句為 reset,也就是單片機直接復(fù)位,這是 MAPLAB編譯器根據(jù) PIC 單片機特點增加的復(fù)位語句。

總結(jié)

對于嵌入式系統(tǒng),如果沒有運行RTOS,那么程序開發(fā)中的主函數(shù)(main())需要通過某種機制使其永遠(yuǎn)愉快的運行下去,它沒有終點。如果想從main函數(shù)中退出,具體干什么是由所使用的C語言編譯器決定的。

來源:TsinghuaJoking公眾號
免責(zé)聲明:本文為轉(zhuǎn)載文章,轉(zhuǎn)載此文目的在于傳遞更多信息,版權(quán)歸原作者所有。本文所用視頻、圖片、文字如涉及作品版權(quán)問題,請聯(lián)系小編進行處理

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 單片機
    +關(guān)注

    關(guān)注

    6030

    文章

    44489

    瀏覽量

    631990
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1617

    瀏覽量

    49015
  • maplab
    +關(guān)注

    關(guān)注

    0

    文章

    3

    瀏覽量

    1252
收藏 人收藏

    評論

    相關(guān)推薦

    單片機怎么寫入程序

    程序通常涉及以下幾個步驟: 選擇單片機和開發(fā)環(huán)境 : 確定項目需求,選擇合適的單片機型號。 安裝相應(yīng)的開發(fā)環(huán)境,如Keil、IAR、MPLAB等。 硬件連接 : 將單片機連接到開發(fā)板或
    的頭像 發(fā)表于 10-21 11:21 ?217次閱讀

    單片機的中斷機制

    單片機的中斷機制是一種重要的處理方式,它允許單片機在執(zhí)行主程序的過程中,能夠暫停當(dāng)前任務(wù),轉(zhuǎn)而處理外部或內(nèi)部緊急事件。這種機制極大地提高了系統(tǒng)的響應(yīng)速度和處理能力,使得單片機在各種應(yīng)用
    的頭像 發(fā)表于 10-17 18:03 ?294次閱讀

    單片機hex文件反編譯成C語言的過程

    使用C語言編寫,然后編譯成機器碼并燒錄到單片機的存儲器中。 Hex文件是一種用于存儲單片機程序的文件格式,它包含了程序的機器碼和一些附加信息,如起始地址、
    的頭像 發(fā)表于 09-02 10:49 ?2129次閱讀

    keil可以讀出單片機程序

    Keil是一款廣泛應(yīng)用于單片機程序開發(fā)的軟件,它提供了包括C編譯器、宏匯編、連接器、庫管理和一個功能強大的仿真調(diào)試器等在內(nèi)的完整開發(fā)方案。然而,關(guān)于Keil是否能直接“讀出”單片機程序
    的頭像 發(fā)表于 09-02 10:32 ?602次閱讀

    單片機燒錄程序用什么軟件

    單片機燒錄程序單片機開發(fā)過程中的一個重要環(huán)節(jié),涉及到將編寫好的程序代碼通過燒錄器寫入單片機的ROM中,以實現(xiàn)對
    的頭像 發(fā)表于 09-02 10:05 ?736次閱讀

    單片機燒錄程序可以重新燒嗎

    單片機(Microcontroller Unit, MCU)是一種集成電路芯片,它將計算機的CPU、存儲器、輸入/輸出接口等集成在一塊芯片上,用于控制各種電子設(shè)備。單片機燒錄程序是指將編寫
    的頭像 發(fā)表于 09-02 10:04 ?779次閱讀

    單片機燒錄程序的線比單片機上的少還能燒錄嗎

    單片機燒錄原理 單片機燒錄是指將編寫好的程序代碼通過一定的方式傳輸?shù)?b class='flag-5'>單片機的存儲器中,使其能夠按照程序的指令運行。這個過程通常需要使用燒錄器
    的頭像 發(fā)表于 09-02 09:54 ?367次閱讀

    單片機燒錄程序的基本步驟是什么

    單片機燒錄程序單片機開發(fā)過程中非常重要的一步,它涉及到將編寫好的程序代碼通過一定的方式傳輸?shù)?b class='flag-5'>單片機內(nèi)部的存儲器中,使
    的頭像 發(fā)表于 09-02 09:47 ?697次閱讀

    stm32單片機燒錄程序會擦除原來的程序

    在STM32單片機燒錄程序的過程中, 通常情況下會擦除原來的程序 ,并將新程序寫入單片機的閃存(Flash)中。這一過程是通過燒錄工具(如S
    的頭像 發(fā)表于 09-02 09:42 ?1174次閱讀

    單片機中斷功能及其應(yīng)用

    單片機中斷功能及其應(yīng)用? 單片機中斷是指在程序執(zhí)行過程中,根據(jù)特定的條件或事件自動暫時中斷當(dāng)前程序的執(zhí)行,轉(zhuǎn)而執(zhí)行特定的中斷服務(wù)程序。中斷是
    的頭像 發(fā)表于 01-30 14:45 ?4796次閱讀

    單片機芯片怎么寫入程序

    單片機芯片的程序寫入是通過將程序代碼寫入單片機芯片的非易失性存儲器(如Flash)中實現(xiàn)的。 在計算機科學(xué)和電子工程領(lǐng)域,單片機是一種集成電
    的頭像 發(fā)表于 01-05 14:06 ?7681次閱讀

    單片機程序讀取需要什么工具

    單片機程序讀取的工具可以分為硬件工具和軟件工具兩類。下面將詳細(xì)介紹這些工具的種類、功能和使用方法。 一、硬件工具 單片機開發(fā)板:單片機開發(fā)板是最基本的硬件工具之一,它通常由主控芯片、輸
    的頭像 發(fā)表于 01-02 18:10 ?3562次閱讀

    51單片機for循環(huán)結(jié)束之后還在運行

    當(dāng)我們設(shè)計并編寫嵌入式系統(tǒng)時,使用51單片機編寫程序時,常常會用到循環(huán)結(jié)構(gòu)來重復(fù)執(zhí)行一段代碼。然而,有時我們可能會遇到51單片機在循環(huán)結(jié)束之后還在運行的問題,這可能會導(dǎo)致系統(tǒng)的功能異常
    的頭像 發(fā)表于 12-26 14:06 ?973次閱讀

    單片機boot腳干嘛

    單片機boot腳是單片機的引導(dǎo)腳,用于控制單片機的啟動和引導(dǎo)過程。在單片機系統(tǒng)中,boot腳的作用十分重要,它影響著整個單片機的工作狀態(tài)和功
    的頭像 發(fā)表于 12-19 09:47 ?9128次閱讀

    pic單片機匯編程序實例

    以下是一個簡單的PIC單片機匯編程序示例,這個程序將實現(xiàn)一個LED閃爍的功能。 首先,我們需要了解PIC單片機的結(jié)構(gòu)和指令集。PIC單片機
    的頭像 發(fā)表于 12-14 11:01 ?1716次閱讀