单片机C语言中while(1)的问题

2023-10-26

单片机C语言的主程序,通常要用一个while(1)语句来让程序进入一个无限循环,目的是为了让程序一直保持在我们需要运行的情况下。
  虽然这种做法毋庸置疑,在网上还是有不少朋友有疑问,如果程序不加while(1)会出现什么情况,对于这种好学精神,还是值得赞扬的,做学问就需要有追根问底的精神。
  首先,大家要理解一件事情,我们编写的C语言程序,最终下载到单片机当中去,在我们单片机的程序存储空间FLASH当中存储的全部是2进制数字代码。比如0x00,0x01,一直到0xff。而我们编写的C代码,依靠的是编译软件,比如keil软件,首先将C语言编译成为汇编语言,最终汇编语言变成2进制代码,也就是我们的HEX文件当中的数据,下载到单片机当中去。
  因此,查找这个问题,首先从源头来找,首先是C语言,然后,我们再看一下软件给我们编译的汇编语言是什么样子。用KEIL软件编写一个程序,然后simulator的方式进行仿真,进入仿真环境后,在View窗口下有个Disassembly window,打开,里边就会出现刚才我们的C语言所对应的汇编语言了(KEIL软件会自动将C编译成汇编),找到里边的主函数,找到你最后一行的程序所对应的汇编,找到后,会发现在最后一行程序结束后,KEIL这个软件还会自动给加入几行汇编代码,这几行代码就是(1)MOV R0, #0x7F;(2)CLR A; (3)MOV @R0, A; (4) DJNZ R0, (3); (5)MOV SP, #0x0C;(6) LJMP main;这几条语句,前4条,是将我们单片机的内存的前128个地址清零,第5条,是定义堆栈,第6条,是将程序重新跳转到main函数的首行进行执行。
  从这里我们可以看出,最终下载到单片机运行的程序包含两部分,一部分是我们编写的程序代码,另外一部分是编译器自动生成的代码,因此,用KEIL软件编写的程序在没有while(1)的情况下运行到最后一行,会自动跳转到main函数第一行运行。
  本着严谨的态度,笔者又查找PIC单片机的编译开发环境MAPLAB IDE,找到其中的汇编程序,在Disassembly window汇编程序中没有发现跳转到主函数的语句或者是复位语句。笔者不甘心,于是继续查找,打开了Promgram Memory,这也是最终下载到单片机当中的程序,通过仔细查看笔者在其后边,发现了在main函数的最后,有一条“reset”语句,这是一条PIC单片机的复位语句,也就是说PIC单片机在进行程序编译的过程中,如果没有while(1)语句,最后则会直接执行复位,这MAPLAB隐藏的可够深的。
  我在论坛上看到一个发帖者提出他下载进AVR单片机的没有while(1)的程序,但是单片机却没有复位,这点我没有再去验证,因为我们的程序通常都是要加while(1)这个循环,因此呢,问题到了这里,单片机程序没有while(1)会出现什么情况,这一点已经不重要了。但是有一点已经可以确认了,一部分单片机在没有while(1)的情况下,运行到最后一行出现的情况受到编译开发环境的影响。
  当然了,一个严谨的开发环境,就应该像KEIL和MAPLAB这样,在程序员编译程序可能出现漏洞的地方给与防护,避免程序跑飞程序员无法查找程序问题。


深有体会。刚学单片机不久,参考别人的程序写了LCD驱动,在买来的实验板上运行时,显示正常。在自己用面包板上搭建的系统运行时,只能显示几秒钟,之后一片空白,当时怀疑面包板供电不稳定,或者信号线干扰,折腾几小时后,在程序末尾加一句“while(1);”,显示完全正常。


不加不稳定,有时候会在main()里面循环,有时候会乱码。


这里的while(1)并不是防止程序“跑飞”的,而是防止main()返回。 在嵌入式中main是不能返回的。不同的C语言实现的单片机初始化代码会有不同的表现,有的是在call _main后jmp,而有的是jmp  0,等等这些会导致不可预料的结果。
②    在我们写的C语言后转换成汇编,再观察单片机的代码区,你会发现没有写程序的部分例如全1或者全0区域,程序运行到这里,就会有可能造成意料不到的结果。若无while(1)循环,程序全部执行后,跳转至程序起始处重新执行。

http://www.51c51.com/bbs/redirect.php?fid=3&tid=32479&goto=nextnewset


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

单片机C语言中while(1)的问题 的相关文章

  • 【系统移植】开发板的启动过程(认识uboot)

    在系统移植之前 需要先了解开发板启动的大致流程 了解了大致流程后 才知道开发板启动需要哪些东西 了解开发板启动的时候 一定会遇到闻所未闻的东西 所以我们了解的顺序是 了解开发板启动时涉及到的部件 了解启动过程中涉及到的文件 uboot 内核
  • 继电器、并联的二极管和驱动三极管选型实战演练

    继电器选型原则 继电器的选用原则参见下表 在表中 必须确定 栏中有 号的项目被确定之后 就可选定一款继电器 如果有进一步的要求 需要进一步考虑 参考 栏中有 号的相应项目 下面对表格中的所有参数进行详细说明 触点 1触点负载 确定继电器所能
  • ANDROID

    1 环境构建 2 模拟测试 3 Activity 4android中的资源 5 UI 6 各种控件
  • 使用嵌入式linux完全手册光盘的arm-linux-gcc 遇到问题 自己编译

    Redhat9下重新生成交叉编译器gcc 3 4 5 glibc 2 3 6 看到论坛上有兄弟也遇到 arm linux gcc lib tls libc so 6 version GLIBC 2 4 not found required
  • golang1.9编译openwrt运行程序 ,window7下liteide编译

    网上看了好多资料发现都很过时了 基本都是用的https github com gomini go mips32编译的 但是go1 9早就支持mips了 设置好编译参数 开始build 这时在go pkg下会出现linux mips目录 就是
  • 我的第一个Imx6ULL应用《百度图像识别》

    Imx6ULL填坑计划 此次用到的所有资料我都放到了奶牛快传里 下载的话速度极快 https c t work s fe0b4a22171342 我买这个板子已经很久了 跟着野火正点原子的教程踉踉跄跄学了一段儿 对很多基础知识也是一知半解
  • STM32与Python上位机通过USB虚拟串口通信

    文章目录 前言 1 查看原理图 2 新建工程 3 添加代码与烧录 4 python代码编写 总结 问题解决思路 前言 在详细阅读广大网友的教程之后 我对STM32和Python通过USB通信的流程烂熟于心 尝试用ST公司的NUCLEO L4
  • QT基础学习(12)---事件过滤

    文章目录 事件过滤 一 事件过滤 实现该功能的方法就是在目标部件 自定义的图片显示部件 上注册事件过滤器 此时的事件过滤器就是我们所说的监视对象 完成这些步骤之后 当目标部件有事件产生后 首先会传递给监视对象 事件过滤器 进行处理而不是该事
  • 再介绍一种低成本的负电源电路

    前面介绍了几种产生负电源的方法 几种常用的产生负电源的方法 今天再来介绍一种低成本的负电源电路 用分离元件搭建 配合程序控制 实现正电源转负电源 先看电路 图中Q1 D1 L2和C1构成最基本的Buck Boost电路 L1 C2为一级LC
  • 嵌入式杂谈之中断向量表

    虽说接触了好久的单片机或者说嵌入式开发 不过对于有些概念还是比较模糊 因此此系列将会从一些零碎的小知识点出发 慢慢的遍历整张嵌入式开发的地图 这次先来看一下中断向量表 至于为什么会提到中断向量表 主要是因为我自己在学习嵌入式Linux开发的
  • stm32USB之模拟U盘

    STMF0 W25Q32模拟U盘 1 第一次写博客 如有错误 请及时指正 如有表达不通顺的地方 敬请谅解 2 本篇文章主要描述如何使用STM32cube配置USB 使用的主控为STM32F072 Flash为W25Q32 使用的主控RAM只
  • 按键的短按和长按检测

    方法一 常用的加延时函数 在中断服务函数中加一个比如10ms的延时函数 延时时间的长短取决于实际所用的按键特性 只要延时时间比抖动时间略大即可 原理很简单 加了延时就避开了抖动的这段时间 在延时之后判断引脚电平 如果为低电平就表示是按下 v
  • 在vmware里面看不到已经设置的共享文件夹

    查看你是否设置了共享文件夹 vmware hgfsclient 在上图的虚拟机点击安装vmware tools 之后会在vmware tools文件里面有一个压缩的文件 把它复制到自己创的文件夹并解压 自己创建文件夹使用mkdir p mo
  • STM32 IAP 在线升级详解

    扩展 IAP主要用于产品出厂后应用程序的更新作用 考虑到出厂时要先烧写IAP 再烧写APP应用程序要烧写2次增加工人劳动力基础上写了 STM32 IAP APP gt 双剑合一 链接稍后发 一 在进入主题之前我们先了解一些必要的基础知识 s
  • 四位数显表头设计

    去年帮别人定制了一个四位数显小表头 可以用于测量4 20mA或者0 5V 0 10V输出的的各种传感器 可设置显示范围 上下限报警灯 由于后面更改方案 此方案暂时搁置不用 今天来分享一下软硬件的设计过程 1 硬件设计 1 1电源 电源采用一
  • STM32F103C8移植uCOSIII(HAL库)

    少年 一 随笔 二 uCOSIII源码 三 项目导入文件整理 四 导入文件和增加头函数路径 五 代码改动 六 参考资料 一 随笔 移植一个嵌入式系统用了一天时间 只能说不愧是我 在不了解的情况下还是少一些自己的操作 自己挖坑埋自己 记录一下
  • 为何在新建STM工程中全局声明两个宏

    在uVision中新建STM32工程后 需要从STM32标准库中拷贝标准外设驱动到自己的工程目录中 此时需要在工程设置 gt C C 选项卡下的Define文本框中键入这两个全局宏定义 STM32F40 41xxx USE STDPERIP
  • 属性,服务,事件

    属性 即设备支持的可读和 或可设置的参数功能 以一个灯为例 灯的开关就可以定义为一个属性 用户可以读取该属性的当前数值来得知灯的开关状态 也可以通过对该属性进行设置来打开或者关闭这个灯 服务 如果设备的某个功能只能设置 不能获取 那么可以将
  • STM32CubeMX HAL库串口+DMA+IDLE空闲中断不定长度数据接收和发送

    本文开发环境 MCU型号 STM32F103ZET6 IDE环境 MDK 5 29 代码生成工具 STM32CubeMx 5 3 0 HAL库版本 STM32Cube FW F1 V1 8 0 STM32Cube MCU Package f
  • FreeRTOS中断管理

    目录 说明 一 中断基础 1 1 中断理解 1 2 中断执行步骤 1 3 中断寄存器选择位 1 4 中断优先级分类 二 中断优先级分组设置 2 1 分类 2 2 特点 三 中断有关寄存器 3 1 SHPR1寄存器 3 2 SHPR2寄存器

随机推荐

  • chatgpt和copilot有关系吗

    chatgpt和copilot之间并没有直接的关系 chatgpt是一个开源的聊天机器人项目 是由谷歌开发的深度学习模型GPT 2 Generative Pre training Transformer 2 提供自然语言生成能力的一个实现
  • 学习笔记-Matlab算法篇-动态规划

    动态规划 01介绍 介绍 动态规划 dynamic programming 是运筹学的一个分支 是求解决策过程 decision process 最优化的数学方法 动态规划是求解某类问题的一种方法 是考察问题的一种途径 而不是一种特殊算法
  • weex实践初探

    weex是阿里2016年开源的项目 号称通过撰写HTML CSS JavaScript来开发原生android ios的UI界面 并且接近原生的性能体验 写一次 多端编译 一直是无线移动追求的目标 既然阿里牛皮吹得这么大 本人也非常迫切体验
  • EncodedResource类解读

    EncodedResource类解读 EncodedResource介绍 EncodedResource是spring中Resource编码相关的封装类 EncodedResource里面封装了一个Resource成员属性 其实主要功能就是
  • MySQL索引类型与索引原理

    1 索引类型 索引可以提升查询速度 会影响where查询 以及order by排序 MySQL索引类型如下 从索引存储结构划分 B Tree索引 Hash索引 FULLTEXT全文索引 R Tree索引 从应用层次划分 普通索引 唯一索引
  • Uncaught ReferenceError: xxx is not defined at HTMLInputElement.onclick已解决

    触发标签的onclick事件报错如下 Uncaught ReferenceError http is not defined at HTMLInputElement onclick list do pageType initialize 2
  • Flutter1.0入门基础

    Flutter1 0入门基础 注 原课程视频是基于Flutter1的 目标 开发入门 工具 环境搭建 入门必备 开发技巧 导航框架 常用功能 开发流程 网络 数据存储 列表 Flutter与Native混编 工程封装 模块开发 AI结合 项
  • java初始化map的四种方式

    第一种 最常见的方式 新建Map对象 public class Demo private static final Map
  • extern指针和数组的用法

    对extern我们先来一段直白的告白 extern是计算机语言中的一个函数 可置于变量或者函数前 以表示变量或者函数的定义在别的文件中 提示编译器遇到此变量或函数时 在其它模块中寻找其定义 另外 extern也可用来进行链接指定 来自百度百
  • 毕业设计:电子/通信/物联网/计算机专业选题目参考(嵌入式linux/单片机STM32/web/图像)

    本文推荐的毕业设计题目涉及以下技术 嵌入式Linux 单片机STM32 Opencv Qt Web 百度AI YOLO 目标检测 深度学习 等 适用于 电子信息 通信 物联网 计算机 等专业的毕业设计题目 支持服务 题目定制 选题答疑 代做
  • Android自定义View实现图片裁剪功能(本地选择图片进行裁剪)

    使用安卓自带的裁剪工具 发现有版本兼容问题 而且图片模糊问题也不好解决 于是自己动手绘制一个裁剪工具 先看效果 最终效果 自定义截图 实现思路 打开本地相册 获得图片Uri Uri转为Bitmap 用自定义View绘制可拖动选框 获得用户的
  • PhotonServer游戏服务器学习一

    步骤一 1 PhotonServe的官方网站https www photonengine com zh CN Photon 进入到官网后点击SDKs 选择Server 工程 点击SeverSDK ON PREMISES进行下载 需要注册一个
  • JDBC连接Access数据库的几种方式介绍

    接下来总结一下常用的几种连接方式 例如有如下的Access数据库student 表basic 以及6条记录 现在通过几种方式在Jsp中将他们的数据显示出来 如图所示 对于几种连接Access数据库的方式 基本上都是基于JDBC ODBC方式
  • 关于pytorch、torch_geometric安装 22.12.25

    系统坏了 重装系统 一开始以为电脑只能装cuda9 2版本一下 装了之后 显卡驱动自动更新了 然后显示可以装CUDA11 7版本一下 cuda 9 2 torch geometric 1 61 pytorch 1 6 0 python3 8
  • Linux 根目录爆掉,怎么办?

    极力推荐文章 欢迎收藏Android 干货分享 本篇文章主要介绍 Linux 开发中的部分知识点 通过阅读本篇文章 您将收获以下内容 一 cannot create temp file for here document No space
  • WebStorm 2023 下载、安装、汉化

    1 下载WebStorm 1 1 官网下载地址 https www jetbrains com webstorm https www jetbrains com webstorm download download thanks html
  • 问题解决:DatabaseMetaData.getTables()方法,返回了所有库中的表

    一 问题描述 DatabaseMetaData getTables 方法常常用来获取数据库中的所有表信息 但我想要获取我的本地数据库db test中的表信息 出现了错误 try Connection conn DBManager getCo
  • BigDecimal保留小数

    Java中BigDecimal取整方法 BigDecimal bd new BigDecimal 12 1 long l bd setScale 0 BigDecimal ROUND UP longValue 向上取整 long l bd
  • 【Docker存储】Docker容器的数据持久化

    Docker存储 Docker容器的数据持久化 一 Docker数据持久化方式 二 本次实践介绍 2 1 本次实践简介 2 2 本次实践环境介绍 三 容器的挂载目录 3 1 创建测试容器web01 3 2 查看容器信息 3 3 编辑测试文件
  • 单片机C语言中while(1)的问题

    单片机C语言的主程序 通常要用一个while 1 语句来让程序进入一个无限循环 目的是为了让程序一直保持在我们需要运行的情况下 虽然这种做法毋庸置疑 在网上还是有不少朋友有疑问 如果程序不加while 1 会出现什么情况 对于这种好学精神