
今天在CSDN的单片机led模块定义函数的问题[1]中看到一个有趣的问题。
一个简单的C51程序如下:
(num){switch(num){case1:P2_0=0;P2_1=0;break;}}voidmain(void){test(1);while(1);}
▲图1.2实验板上后面六个LED就不再点亮了
上面两种情况的区别,在于第二个程序中主循环main()函数始终没有退出,而第一个程序,main()函数退出了。似乎前面LED微微点亮应该与主函数退出之后,单片机都干了些啥有关系。
那么就剩下一个问题:对于普通的嵌入式系统,C语言编程中main()函数退出之后,程序去哪儿了?
02程序去哪儿了?从上面提问者书写的代码来看,应该是一位C51的爱好者,使用的是C51的编译器,在一款C51开发板上愉快的进行实验。他一开始没有安装嵌入式程序开发的惯例在主程序voidmain(void)中利用无限循环将程序控制在主程序函数中,就出现了前面实验结果中令人迷惑的情况。
2.1盘古开天辟地对于C语言编程来说,所有的用户程序世界是从主程序main()开始的。给用户程序开天辟地的任务是由一小段盘古代码。
关于C51是如何启动的,在如下两篇博文中也被测试说明:
51单片机程序执行流程(管理Main函数的执行)[2]
下面截取了代码的一段,可以看到盘古在单片机RESET之后做了点准备工作(初始化全局变量、堆栈指针)之后,就直接跳转至:?C_START
$NOMOD51;------------------------------------------------------------------------------;ThisfileispartoftheC51Compilerpackage;Copyright(c)1988-2005KeilElektronikGmbHandKeilSoftware,Inc.;;;***UseConfigurationWizardinContextMenu***;------------------------------------------------------------------------------;:Thiscodeisexecutedafterprocessorreset.;;TotranslatethisfileuseA51withthefollowinginvocation:;;;;;Lx51invocation:;;Lx51yourobjectfilelist,;;------------------------------------------------------------------------------;StandardSFRSymbolsACCDATA0E0HBDATA0F0HSPDATA81HDPLDATA82HDPHDATA83HNAME?C_STARTUP?C_C51STARTUPSEGMENTCODE?STACKSEGMENTIDATARSEG?STACKDS1EXTRNCODE(?C_START)PUBLIC?C_STARTUPCSEGAT0?C_STARTUP:LJMPSTARTUP1RSEG?C_C51STARTUPSTARTUP1:IFIDATALEN0MOVR0,XDATASTARTMOVR7,(HIGH(XDATALEN))+1ELSEMOVR6,PPAGEENDIFIFPDATALEN0MOVR0,LOW(PDATALEN)CLRAPDATALOOP:MOVX@R0,AINCR0DJNZR7,PDATALOOPENDIFIFIBPSTACK0EXTRNDATA(?C_IBP)MOV?C_IBP,HIGHXBPSTACKTOPMOV?C_XBP+1,LOWPBPSTACKTOPENDIFMOVSP,if0;iInitializebankmechanismtocodebank0whenusingL51_(?B_SWITCH0)CALL?B_SWITCH0;initbankmechanismtocodebank00x7FCLRAMOV@R0,ADJNZR0,(3)MOVSP,#0x0CLJMPmain
这几条语句,前4条,是将我们单片机的内存的前128个地址清零,第5条,是定义堆栈,第6条,是将程序重新跳转到main函数的首行进行执行。
2.2.2MAPLAB编译器PIC单片机语言程序进行跟踪,发现main()函数最后一条语句为reset,也就是单片机直接复位,这是MAPLAB编译器根据PIC单片机特点增加的复位语句。
※总结※对于嵌入式系统,如果没有运行RTOS,那么程序开发中的主函数(main())需要通过某种机制使其永远愉快的运行下去,它没有终点。
如果想从main函数中退出,具体干什么是由所使用的C语言编译器决定的。
参考资料[1]
单片机led模块定义函数的问题:
[2]
51单片机程序执行流程(管理Main函数的执行):
[3]
51单片机程序执行流程():