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

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

3天内不再提示

干货 | 关于单片机上for循环中运用ACC的隐蔽错误

2oON_changxuemc 来源:YXQ 2019-06-20 10:47 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

先上代码:第一个为错误代码,第二个为正确代码。这是用来向ds1302芯片写入命令或数据的函数。实现把8位的数据dat一位一位地写入ds1302的io口。其中ACC0为ACC的第0位。

认真对比这两个代码,可能会觉得没区别,而且这两个代码都可以通过编译(加上reg52.h和一些宏定义)。我也是一直认为for()这里边没有错误,结果。。。试着修改时钟信号,增加延时之类的,调了好久还是错,严重打击我的自信心。这两个代码的区别就只有for(i=0;i<8;i++)和for(i=8;i>0;i--)了。学过c语言的人都知道,这两个句子都是实现一个8次的循环,功能一模一样。怎么会因为这个句子的区别就导致单片机控制的错误呢?神奇!

接着我试着把错误程序中的ACC改为51芯片的寄存器B,烧录进单片机,程序运行成功,跟“for(i=8;i>0;i--),ACC版”一样,lcd在很嚣张地显示着正确的时间( for(i=0;i<8;i++),ACC版lcd的时间显示为0)。附:

这样就知道原因了,使用for(i=0;i<8;i++)的运算中可能有累加器ACC参与了,导致修改了ACC的值,使写入的命令出现错误。但为什么for(i=8;i>0;i--)就没有ACC的参与呢?一个大大的问号。基于我调试了一个星期的程序,皆因为这一个神奇的错误,我实在不甘心,决定研究到底。于是,分别查看了这三个程序代码keil4 编译后得到的 汇编代码。(学过汇编就是爽啊,哈)

对比后,可以发现,出错的原因是for(i=0;i<8;i++)ACC版中,用ACC接收了实参(存储的为要写入的指令),然后在 for 循环前要给变量 “ i " 赋值时,要用到ACC清零,再把ACC中的零赋给 R7 ("i"的值存储在R7)。这样的话,原来存储在ACC中的写入指令就被清零,自然会导致控制出现错误,最终没法读取ds1302芯片的时间,故显示为零。

而在for(i=8;i>0;i--)ACC版中,也用ACC接收了实参的值,但在 for 循环前,给变量“ i ” 赋值时,赋值为8,不需要用到ACC,所以ACC一直是存储着实参中的指令,没有被清零,所以能够顺利地向ds1302发送指令,从而能够读取到时间。

总结:

因为用for(i=0;i0;i--)类的指令多了 CLR A 和 INC R7 两条指令,CJNE 指令又比较DJNZ指令多了一个字节的程序代码存储空间,在频率为12M的51单片机上体现为执行同样功能的程序,要多用2us,代码空间花多一字节。所以前者是毫无优势的,以后应养成用

for(i=n;i>0;i--)的习惯。

请不要反驳我用了这么长的时间去研究,只能使单片机执行快2us,而说我钻牛角尖,只是因为,这个错误导致我整个程序无法正常运行,这不是一件小事。

至于为什么要用到累加器ACC来接收实参,是因为后面的程序要把一个8位的实参一位一位地输出到一个io口,自定义一个变量的话,按位寻址好像比较麻烦,要经过一系列 位运算 ,或者用bit定义8个位(有好的方法请告诉我,哈),而且我写不出来。而用ACC的话,可以很轻易地操作ACC的任意一位,如ACC0,ACC7。在网上查了一下,好像还有一种方法是定义 一种叫 位域 的东东,我看的c语言的书都没介绍,所以还不是很了解。

/************************************************************/

刚刚想了一下,不用ACC 的方法,作一个位运算dat &0x01,修改如下:

想到了这个方法后,觉得自己好白痴,以后都不用ACC了。

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

    关注

    6074

    文章

    45352

    浏览量

    664112
  • ACC
    ACC
    +关注

    关注

    1

    文章

    60

    浏览量

    23505

原文标题:关于单片机上for循环中运用ACC的隐蔽错误

文章出处:【微信号:changxuemcu,微信公众号:畅学单片机】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    电机控制是不是就绑死在单片机上

    电机控制这个行当,说来说去总绕不开单片机,许多人一干就是十几年,调来调去都是那几个芯片,看波形、改参数、写驱动,日子好像就这么定下来了。你说绑死在单片机上了吗?表面上确实是,毕竟现在的电机控制器
    的头像 发表于 12-10 10:50 306次阅读
    电机控制是不是就绑死在<b class='flag-5'>单片机上</b>了

    单片机程序的执行

    。 但是单片机上只有几K的RAM,而flash一般有几十K甚至1M,这个时候指令和数据都在内存中吗(这里指的内存仅指RAM,因为PC上我们常说的内存就是DDR RAM memory,先入为主以至于认为
    发表于 12-04 06:20

    单片机系统硬件的调试方法

    单片机的系统硬件调试,需要从硬件的静态调试和动态调试两个角度人手: 单片机系统硬件的静态调试 1、逻辑故障的排除在制板设计和加工的过程中.由于工艺性的错误.单片机容易出现错线、开路和
    发表于 12-03 06:10

    第1章 如何学习单片机

      在错误的道路上日夜兼程,最终也无法成功,方法和思路绝对是最重要的。本章节讲到的学习单片机的方法,都是作者学习单片机的无数经验和教训总结出来的瑰宝。通过作者前面的披荆斩棘,开辟了道路,可以告诉读者
    的头像 发表于 10-10 10:32 251次阅读

    人工智能行业如何使用for循环语句进行循环

    人工智能行业可以使用以下是关于for循环在不同编程语言中的基本用法说明: Python中的for循环: 主要用于遍历序列(列表、元组、字符串等) 典型结构:for item in sequence
    的头像 发表于 09-10 12:55 406次阅读

    在消费者循环中如何分离数据采集任务和响应用户操作任务

    有没有大佬告诉我为什么这里消费者循环中要按下保存按钮(进入采集中的状态)之后我的波形图表才会出现图案啊 明明这个在条件结构以外![[大哭]] 另外不进入采集中状态 队列的数量也为0
    发表于 08-12 12:18

    怎么测单片机系统频率

    单片机系统频率是指单片机工作时的时钟频率,它直接影响单片机的运行速度和处理能力,准确测量系统频率对单片机应用开发、程序调试和性能优化具有重要意义。测量
    的头像 发表于 07-25 11:39 497次阅读

    STM32单片机片上数字滤波器操作文档 快速入门数字滤波器在单片机上的实现

    这个文档,是为了帮助大家快速入门数字滤波器在单片机上的实现。
    的头像 发表于 06-23 16:53 1354次阅读
    STM32<b class='flag-5'>单片机</b>片上数字滤波器操作文档 快速入门数字滤波器在<b class='flag-5'>单片机上</b>的实现

    单片机实例项目:485与CAN总线运用实例

    单片机实例项目:485与CAN总线运用实例,推荐下载!
    发表于 06-03 20:48

    51+单片机TCP-IP+协议栈ZLIP源码

    概述 单片机上网技术,是当前的一个热门技术。单片机上网技术中的一个重要部分是在单片上实现 TCP/IP 协议栈。现在可获得的 TCP/IP 源代码一般并不为 51 单片机设计,而 51
    发表于 04-22 15:11

    单片机方面的大佬吗?有几个单片机方面的问题需要请教一下

    如题,有单片机方面的内容需要请教一下 (先叠个甲)纯小白 我需要一个单片机控制模块,我现在的想法是:在一个单片机上,我要让他控制一个传感器和一个步进电机(运动系统,运动距离为13.5cm),同时
    发表于 03-29 18:35

    技术干货驿站 ▏深入理解C语言:嵌套循环循环控制的底层原理

    多重循环,还是控制循环的执行流程,掌握这些知识都将为你的编程之路打下坚实的基础。嵌套循环在C语言中,循环语句可以嵌套使用,即在一个循环中再使
    的头像 发表于 02-21 18:26 1061次阅读
    技术<b class='flag-5'>干货</b>驿站  ▏深入理解C语言:嵌套<b class='flag-5'>循环</b>与<b class='flag-5'>循环</b>控制的底层原理

    单片机控制ADS7953读取每个通道电压,返回值异常的原因?

    单片机IO模拟SCK, MOSI, MISO 控制ADS7953,在电路中没有使用到ADS7953的四个GPIO口,程序在16次的for循环中实现16次SCK脉冲,同时控制MOSI,并读取
    发表于 01-23 06:34

    单片机Debug工具性能对比 单片机调试常用命令

    单片机(Microcontroller Unit, MCU)调试是嵌入式开发中的一个重要环节,它帮助开发者发现和修复代码中的错误,优化程序性能。不同的单片机和开发环境可能使用不同的调试工具和命令
    的头像 发表于 12-19 09:56 2191次阅读

    单片机Debug与仿真区别

    单片机的开发是一个复杂的过程,涉及到硬件设计、软件开发和测试等多个环节。为了确保单片机能够按照预期工作,开发者需要使用Debug和仿真技术来检测和修正代码中的错误。 Debug(调试) Debug
    的头像 发表于 12-19 09:47 1432次阅读