0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

单片机led模块定义函数程序去哪了

硬件攻城狮 来源:硬件攻城狮 作者:硬件攻城狮 2022-08-25 10:42 次阅读

正常的程序,都不会跳出main,但是,如果跳出了 main 函数,程序到底去哪儿了,你有相关这个问题吗?

一、问题提出

今天在单片机led模块定义函数中看到一个有趣的问题。提问者在进行基本的C51编程实验,编写了一个简单的C51程序如下:

#include

voidtest(num){
switch(num){
case1:P2_0=0;P2_1=0;
break;
}
}

voidmain(void){
test(1);
}

程序执行完之后,可以看到实验板上的有两个LED被点亮,另外六个居然微微发亮。

7728f790-238e-11ed-ba43-dac502259ad0.png

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

#include

voidtest(num){
switch(num){
case1:P2_0=0;P2_1=0;
break;
}
}

voidmain(void){
test(1);
while(1);
}
77472c38-238e-11ed-ba43-dac502259ad0.png

上面两种情况的区别,在于第二个程序中主循环 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_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单片机程序执行流程(STARTUP.A51)中进行逐步调试跟踪验证过:

776f4858-238e-11ed-ba43-dac502259ad0.png

2.2 世界尽头

由于进入main()函数是长跳转,所以main函数是不会正常返回到启动程序STARTUP.A51,那么程序去哪了?

在博文单片机C语言while(1)的问题中作者对于KEIL编译器和PIC的MAPLAB编译器对于main函数的最后时光进行了反汇编查看。

Keil编译器

在main函数的最后,程序增加了一下几行代码:

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

这几条语句,前4条,是将我们单片机的内存的前128个地址清零,第5条,是定义堆栈,第6条,是将程序重新跳转到main函数的首行进行执行。

MAPLAB编译器

PIC 单片机语言程序进行跟踪,发现main() 函数最后一条语句为 reset,也就是单片机直接复位,这是 MAPLAB编译器根据 PIC 单片机特点增加的复位语句。

总结

对于嵌入式系统,如果没有运行RTOS,那么程序开发中的主函数(main())需要通过某种机制使其永远愉快的运行下去,它没有终点。如果想从main函数中退出,具体干什么是由所使用的C语言编译器决定的。

审核编辑:彭静
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6032

    文章

    44513

    浏览量

    632900
  • 程序
    +关注

    关注

    116

    文章

    3775

    浏览量

    80840
  • 函数
    +关注

    关注

    3

    文章

    4304

    浏览量

    62426
  • LED模块
    +关注

    关注

    0

    文章

    27

    浏览量

    13013

原文标题:单片机main函数结束干嘛去了?

文章出处:【微信号:mcu168,微信公众号:硬件攻城狮】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    单片机LED点阵显示keil程序

    本内容提供单片机LED点阵显示keil程序,欢迎大家下载学习 //单片机LED点阵显示keil
    发表于 11-09 17:58 343次下载

    单片机控制的LED灯、最小系统及八路流水灯

    1、 单片机控制一个LED灯的C语言程序范例 单片机控制一个LED灯的C语言程序范例1: //用
    发表于 09-06 10:37 23次下载

    51单片机C语言延时函数怎么定义和使用

    C语言定义延时函数主要通过无意义指令的执行来达到延时的目的。下面给出一个经典的延时函数。C程序中可使用不同类型的变量来进行延时设计。经实验测试,使用unsigned char类型具有
    发表于 11-16 17:06 8.5w次阅读

    AVR单片机的延时函数程序免费下载

    本文档的主要内容详细介绍的是AVR单片机的延时函数程序免费下载
    发表于 11-16 08:00 7次下载
    AVR<b class='flag-5'>单片机</b>的延时<b class='flag-5'>函数</b><b class='flag-5'>程序</b>免费下载

    51单片机常用库函数程序免费下载

    本文档的主要内容详细介绍的是51单片机常用库函数程序免费下载。
    发表于 08-29 17:28 24次下载
    51<b class='flag-5'>单片机</b>常用库<b class='flag-5'>函数</b><b class='flag-5'>程序</b>免费下载

    51单片机定义端口和定时器中断与蜂鸣器报警程序函数合集

    本文档的主要内容详细介绍的是51单片机定义端口和全局变量及定时器中断与蜂鸣器报警程序函数合集免费下载。
    发表于 07-10 17:40 11次下载
    51<b class='flag-5'>单片机</b>的<b class='flag-5'>定义</b>端口和定时器中断与蜂鸣器报警<b class='flag-5'>程序</b>等<b class='flag-5'>函数</b>合集

    单片机的主程序是如何执行的

    我们从单片机的工作原理可以看出单片机是执行程序来完成我们所要求的任务的,在单片机中有很多子程序单片机
    的头像 发表于 10-30 17:28 1w次阅读
    <b class='flag-5'>单片机</b>的主<b class='flag-5'>程序</b>是如何执行的

    单片机按键使用程序 (51单片机

    单片机独立按键使用程序 (51单片机)独立按键是单片机中很重要的一个器件,在这篇文章里,通过这个用独立按键控制LED灯的小
    发表于 11-11 18:36 108次下载
    <b class='flag-5'>单片机</b>按键使用<b class='flag-5'>程序</b> (51<b class='flag-5'>单片机</b>)

    单片机模块化编程

    单片机模块化编程步骤:1、先建5个文件夹:LED总文件夹、project、user、output和bsp文件夹project文件夹主要放工程项目;user文件夹主要放main程序和pb
    发表于 11-14 19:36 10次下载
    <b class='flag-5'>单片机</b><b class='flag-5'>模块</b>化编程

    51单片机 点亮一个LED LED闪烁

    ) //循环 { }}使用51单片机点亮一个LED#include <reg52.h> //51单片机头文件sbit LED=P2^0;
    发表于 11-23 17:06 5次下载
    51<b class='flag-5'>单片机</b> 点亮一个<b class='flag-5'>LED</b> <b class='flag-5'>LED</b>闪烁

    单片机程序是如何执行的?指令数据写?

    单片机的运行需要执行程序,同时硬件也是必不可少的,二者缺一不可。大家都知道单片机的运行需要执行写好的程序,但是单片机的指令数据都被写在
    发表于 11-23 17:51 9次下载
    <b class='flag-5'>单片机</b><b class='flag-5'>程序</b>是如何执行的?指令数据写<b class='flag-5'>哪</b><b class='flag-5'>了</b>?

    单片机程序是如何执行的:指令数据写

    单片机的运行需要执行程序,同时硬件也是必不可少的,二者缺一不可。大家都知道单片机的运行需要执行写好的程序,但是单片机的指令数据都被写在
    发表于 12-01 16:06 7次下载
    <b class='flag-5'>单片机</b><b class='flag-5'>程序</b>是如何执行的:指令数据写<b class='flag-5'>哪</b><b class='flag-5'>了</b>

    单片机led模块定义函数的问题

    对于嵌入式系统,如果没有运行RTOS,那么程序开发中的 主函数(main())需要通过某种机制使其永远愉快的运行下去,它没有终点。如果想从main函数中退出,具体干什么是由所使用的C语言编译器决定的。
    的头像 发表于 03-11 10:10 1613次阅读

    C语言编程中main函数退出后程序哪儿

    PIC 单片机语言程序进行跟踪,发现main() 函数最后一条语句为 reset,也就是单片机直接复位,这是 MAPLAB编译器根据 PIC 单片机
    发表于 05-31 15:28 406次阅读
    C语言编程中main<b class='flag-5'>函数</b>退出后<b class='flag-5'>程序</b><b class='flag-5'>去</b>哪儿<b class='flag-5'>了</b>?

    单片机用按钮中断函数

    单片机用按钮中断函数  单片机中断是一种能够使单片机响应外部信号的机制,这种机制允许单片机在处理其他任务时
    的头像 发表于 09-01 10:17 1461次阅读