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

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

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

單片機led模塊定義函數(shù)的問題

GReq_mcu168 ? 來源:CSDN ? 作者:CSDN ? 2022-03-11 10:10 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

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

01問題提出

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

#include voidtest(num){ switch(num){ case1:P2_0=0;P2_1=0; break; } } voidmain(void){ test(1); }

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

25a78be2-8f01-11ec-952b-dac502259ad0.png

▲ 圖1.1 實驗板上的未點亮的LED居然微微發(fā)亮

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

#include voidtest(num){ switch(num){ case1:P2_0=0;P2_1=0; break; } } voidmain(void){ test(1); while(1); }

25c67dcc-8f01-11ec-952b-dac502259ad0.png

▲ 圖1.2 實驗板上后面六個LED就不再點亮了

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

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

02程序去哪兒了?

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

注:他是一個膽大心細(xì)的人,觀察還挺仔細(xì)的。

2.1 盤古開天辟地

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

關(guān)于C51是如何啟動的, 在如下面博文中也被測試說明:

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

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

NAME?C_STARTUP ?C_C51STARTUPSEGMENTCODE ?STACKSEGMENTIDATA RSEG?STACK DS1 EXTRNCODE(?C_START) PUBLIC?C_STARTUP CSEGAT0 ?C_STARTUP:LJMPSTARTUP1 RSEG?C_C51STARTUP STARTUP1: IFIDATALEN<>0 MOVR0,#IDATALEN-1 CLRA IDATALOOP:MOV@R0,A DJNZR0,IDATALOOP ENDIF IFXDATALEN<>0 MOVDPTR,#XDATASTART MOVR7,#LOW(XDATALEN) IF(LOW(XDATALEN))<>0 MOVR6,#(HIGH(XDATALEN))+1 ELSE MOVR6,#HIGH(XDATALEN) ENDIF CLRA XDATALOOP:MOVX@DPTR,A INCDPTR DJNZR7,XDATALOOP DJNZR6,XDATALOOP ENDIF IFPPAGEENABLE<>0 MOVPPAGE_SFR,#PPAGE ENDIF IFPDATALEN<>0 MOVR0,#LOW(PDATASTART) MOVR7,#LOW(PDATALEN) CLRA PDATALOOP:MOVX@R0,A INCR0 DJNZR7,PDATALOOP ENDIF IFIBPSTACK<>0 EXTRNDATA(?C_IBP) MOV?C_IBP,#LOWIBPSTACKTOP ENDIF IFXBPSTACK<>0 EXTRNDATA(?C_XBP) MOV?C_XBP,#HIGHXBPSTACKTOP MOV?C_XBP+1,#LOWXBPSTACKTOP ENDIF IFPBPSTACK<>0 EXTRNDATA(?C_PBP) MOV?C_PBP,#LOWPBPSTACKTOP ENDIF MOVSP,#?STACK-1 LJMP?C_START END

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

25e5150c-8f01-11ec-952b-dac502259ad0.jpg

▲ 圖2.1.1 顯示LJMP C_START 就是進(jìn)入 main() 程序

2.2 世界盡頭

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

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

2.2.1 Keil編譯器

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

MOVR0,#0x7F CLRA MOV@R0,A DJNZR0,(3) MOVSP,#0x0C LJMPmain

這幾條語句,前4條,是將我們單片機的內(nèi)存的前128個地址清零,第5條,是定義堆棧,第6條,是將程序重新跳轉(zhuǎn)到main函數(shù)的首行進(jìn)行執(zhí)行。

2.2.2 MAPLAB編譯器

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

※總??結(jié) ※

對于嵌入式系統(tǒng),如果沒有運行RTOS,那么程序開發(fā)中的 主函數(shù)(main())需要通過某種機制使其永遠(yuǎn)愉快的運行下去,它沒有終點。

如果想從main函數(shù)中退出,具體干什么是由所使用的C語言編譯器決定的。

審核編輯 :李倩

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

    關(guān)注

    41

    文章

    3675

    瀏覽量

    131198
  • C51
    C51
    +關(guān)注

    關(guān)注

    5

    文章

    284

    瀏覽量

    59136

原文標(biāo)題:程序結(jié)束后去哪兒了?

文章出處:【微信號:mcu168,微信公眾號:硬件攻城獅】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    51單片機-LED模塊

    LED模塊是通過74573鎖存器芯片與單片機IO口連接,并與數(shù)碼管共用IO口。
    的頭像 發(fā)表于 05-23 09:14 ?9391次閱讀
    51<b class='flag-5'>單片機</b>-<b class='flag-5'>LED</b>燈<b class='flag-5'>模塊</b>

    51單片機C語言延時函數(shù)怎么定義

    描述51單片機C語言延時函數(shù)怎么定義C語言定義延時函數(shù)主要通過無意義指令的執(zhí)行來達(dá)到延時的目的。C程序中可使用不同類型的變量來進(jìn)行延時設(shè)計。
    發(fā)表于 07-15 06:42

    定義單片機寄存器操作和模塊接口相關(guān)的函數(shù)

    :/* 定義單片機寄存器操作和模塊接口相關(guān)的函數(shù), 方便在不同平臺間移植 */// 單片機: STM32F103VE,
    發(fā)表于 12-13 07:43

    單片機控制的LED燈、最小系統(tǒng)及八路流水燈

    1、 單片機控制一個LED燈的C語言程序范例 單片機控制一個LED燈的C語言程序范例1: //用單片機點亮1個
    發(fā)表于 09-06 10:37 ?23次下載

    51單片機C語言延時函數(shù)怎么定義和使用

    比unsigned int更優(yōu)化的代碼,在使用時應(yīng)該使用unsigned char作為延時變量。 以某晶振為12MHz的單片機為例,晶振為12MHz即一個機器周期為1us。
    發(fā)表于 11-16 17:06 ?8.6w次閱讀

    如何使用單片機系統(tǒng)重寫printf函數(shù)

    本文檔的主要內(nèi)容詳細(xì)介紹的是如何使用單片機系統(tǒng)重寫printf函數(shù)。
    發(fā)表于 07-23 17:37 ?1次下載
    如何使用<b class='flag-5'>單片機</b>系統(tǒng)重寫printf<b class='flag-5'>函數(shù)</b>

    51單片機定義端口和定時器中斷與蜂鳴器報警程序等函數(shù)合集

    本文檔的主要內(nèi)容詳細(xì)介紹的是51單片機定義端口和全局變量及定時器中斷與蜂鳴器報警程序等函數(shù)合集免費下載。
    發(fā)表于 07-10 17:40 ?11次下載
    51<b class='flag-5'>單片機</b>的<b class='flag-5'>定義</b>端口和定時器中斷與蜂鳴器報警程序等<b class='flag-5'>函數(shù)</b>合集

    使用MSP430F5529單片機控制LED同時閃爍的庫函數(shù)免費下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是使用MSP430F5529單片機控制LED同時閃爍的庫函數(shù)免費下載。
    發(fā)表于 07-24 08:00 ?10次下載
    使用MSP430F5529<b class='flag-5'>單片機</b>控制<b class='flag-5'>LED</b>同時閃爍的庫<b class='flag-5'>函數(shù)</b>免費下載

    單片機模塊學(xué)習(xí)

    單片機的幾個寄存器學(xué)完了,就是對模塊的學(xué)習(xí),同時也有一些協(xié)議比如iic,spi,單線等等,高級的單片機會用到高級的協(xié)議LED數(shù)碼管鍵盤串口
    發(fā)表于 11-14 14:36 ?1次下載
    <b class='flag-5'>單片機</b><b class='flag-5'>模塊</b>學(xué)習(xí)

    51單片機 點亮一個LED LED閃爍

    ) //循環(huán) { }}使用51單片機點亮一個LED#include <reg52.h> //51單片機頭文件sbit LED=P2^0;
    發(fā)表于 11-23 17:06 ?5次下載
    51<b class='flag-5'>單片機</b> 點亮一個<b class='flag-5'>LED</b> <b class='flag-5'>LED</b>閃爍

    C語言&單片機不定參數(shù)個數(shù)的函數(shù)定義

    在學(xué)習(xí)使用C語言的時候都會告知main函數(shù)是可以接入多個參數(shù)的,那么問題來了,不定參數(shù)個數(shù)的函數(shù)如何定義的呢,它是否可以在單片機中使用呢定義
    發(fā)表于 11-29 09:51 ?8次下載
    C語言&<b class='flag-5'>單片機</b>不定參數(shù)個數(shù)的<b class='flag-5'>函數(shù)</b><b class='flag-5'>定義</b>

    串口調(diào)用單片機函數(shù)(c/c++)[自定義shell]

    調(diào)試單片機常用,參考正點原子USMART寫了個簡單的自用核心內(nèi)容如下1、C語言(stm32)定義typedef struct ShellFun_CLASS{ void* func; //函數(shù)
    發(fā)表于 01-13 13:25 ?1次下載
    串口調(diào)用<b class='flag-5'>單片機</b><b class='flag-5'>函數(shù)</b>(c/c++)[自<b class='flag-5'>定義</b>shell]

    單片機led模塊定義函數(shù)程序去哪了

    正常的程序,都不會跳出main,但是,如果跳出了 main 函數(shù),程序到底去哪兒了,你有相關(guān)這個問題嗎?
    的頭像 發(fā)表于 08-25 10:42 ?1146次閱讀

    如何在單片機中使用malloc函數(shù)

    但是每個嵌入式 RTOS 都會有自己的內(nèi)存管理方式,本文就來聊聊我對 malloc 函數(shù)單片機程序設(shè)計中的一些看法。 本文并不是要說明在單片機中怎么使用 malloc函數(shù),而是
    的頭像 發(fā)表于 04-24 09:50 ?2954次閱讀
    如何在<b class='flag-5'>單片機</b>中使用malloc<b class='flag-5'>函數(shù)</b>

    單片機用按鈕中斷函數(shù)

    單片機用按鈕中斷函數(shù)? 單片機中斷是一種能夠使單片機響應(yīng)外部信號的機制,這種機制允許單片機在處理其他任務(wù)時去響應(yīng)中斷信號,從而提高
    的頭像 發(fā)表于 09-01 10:17 ?1947次閱讀

    電子發(fā)燒友

    中國電子工程師最喜歡的網(wǎng)站

    • 2931785位工程師會員交流學(xué)習(xí)
    • 獲取您個性化的科技前沿技術(shù)信息
    • 參加活動獲取豐厚的禮品