tft每日頭條

 > 生活

 > 單片機調用函數要寫全部嗎

單片機調用函數要寫全部嗎

生活 更新时间:2024-06-22 18:29:26

作者 | TsinghuaJoking正常的程序,都不會跳出main,但是,如果跳出了 main 函數,程序到底去哪兒了,你有相關這個問題嗎?

一、問題提出今天在單片機led模塊定義函數中看到一個有趣的問題。提問者在進行基本的C51編程實驗,編寫了一個簡單的C51程序如下:#include <REGX51.H>

void test(num) {

switch(num) {

case 1: P2_0=0; P2_1=0;

break;

}

}

void main(void) {

test(1);

}

程序執行完之後,可以看到實驗闆上的有兩個LED被點亮,另外六個居然微微發亮。

單片機調用函數要寫全部嗎(單片機main函數結束幹嘛去了)1

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

嵌入式物聯網需要學的東西真的非常多,千萬不要學錯了路線和内容,導緻工資要不上去!

無償分享大家一個資料包,差不多150多G。裡面學習内容、面經、項目都比較新也比較全!某魚上買估計至少要好幾十。

點擊這裡找小助理0元領取:嵌入式物聯網學習資料(頭條)

單片機調用函數要寫全部嗎(單片機main函數結束幹嘛去了)2

單片機調用函數要寫全部嗎(單片機main函數結束幹嘛去了)3

#include <REGX51.H>

void test(num) {

switch(num) {

case 1: P2_0=0; P2_1=0;

break;

}

}

void main(void) {

test(1);

while(1);

}

上面兩種情況的區别,在于第二個程序中主循環 main()函數始終沒有退出,而第一個程序,main()函數退出了。似乎前面LED微微點亮 應該與主函數退出之後,單片機都幹了些啥有關系。

那麼就剩下一個問題:對于普通的嵌入式系統,C語言編程中main()函數退出之後,程序去哪兒了?二、程序去哪兒了?從上面提問者書寫的代碼來看,應該是一位C51的愛好者,使用的是C51的編譯器,在一款C51開發闆上愉快的進行實驗。

他一開始沒有安裝嵌入式程序開發的慣例 在主程序void main(void)中利用無限循環将程序控制在主程序函數中,就出現了前面實驗結果中令人迷惑的情況。

“注:他是一個膽大心細的人,觀察還挺仔細的。”2.1 盤古開天辟地對于C語言編程來說,所有的用戶程序世界是從主程序main()開始的。給用戶程序開天辟地的任務是由一小段盤古代碼STARTUP.A51。51單片機程序執行流程(STARTUP.A51管理Main函數的執行)下面截取了STARTUP.A51 代碼的一段,可以看到盤古在單片機RESET之後做了點準備工作(初始化全局變量、堆棧指針)之後,就直接跳轉至:?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單片機程序執行流程(STARTUP.A51)中進行逐步調試跟蹤驗證過:2.2 世界盡頭由于進入main()函數是長跳轉,所以main函數是不會正常返回到啟動程序STARTUP.A51,那麼程序去哪了?在博文單片機C語言while(1)的問題中作者對于KEIL編譯器和PIC的MAPLAB編譯器對于main函數的最後時光進行了反彙編查看。Keil編譯器在main函數的最後,程序增加了一下幾行代碼:MOV R0, #0x7F

CLR A

MOV @R0, A

DJNZ R0, (3)

MOV SP, #0x0C

LJMP main

這幾條語句,前4條,是将我們單片機的内存的前128個地址清零,第5條,是定義堆棧,第6條,是将程序重新跳轉到main函數的首行進行執行。MAPLAB編譯器PIC 單片機語言程序進行跟蹤,發現main() 函數最後一條語句為 reset,也就是單片機直接複位,這是 MAPLAB編譯器根據 PIC 單片機特點增加的複位語句。總結對于嵌入式系統,如果沒有運行RTOS,那麼程序開發中的主函數(main())需要通過某種機制使其永遠愉快的運行下去,它沒有終點。如果想從main函數中退出,具體幹什麼是由所使用的C語言編譯器決定的。-- End --聲明:本文轉自“網絡”,版權歸作者所有。如有侵權,請聯系我們删除!

原文作者:TsinghuaJoking

作品來源:單片機愛好者

原文鍊接: 單片機main函數結束幹嘛去了?

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved