龙空技术网

单片机main函数结束干嘛去了?

嵌入式开发卡贝 444

前言:

如今朋友们对“c语言退出系统的函数怎么写”大约比较关注,小伙伴们都需要了解一些“c语言退出系统的函数怎么写”的相关文章。那么小编同时在网络上网罗了一些对于“c语言退出系统的函数怎么写””的相关内容,希望同学们能喜欢,各位老铁们一起来了解一下吧!

作者 | 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被点亮,另外六个居然微微发亮。

如果在主程序中,增加一个无限循环:while(1); ,则电路板上的就不再会出现“微微点亮”的现象了。

嵌入式物联网需要学的东西真的非常多,千万不要学错了路线和内容,导致工资要不上去!

无偿分享大家一个资料包,差不多150多G。里面学习内容、面经、项目都比较新也比较全!某鱼上买估计至少要好几十。

点击这里找小助理0元领取:嵌入式物联网学习资料(头条)

#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函数结束干嘛去了?

标签: #c语言退出系统的函数怎么写