8051系列单片机软件精确延时研究(一)

发布者:Radiant777最新更新时间:2024-07-23 来源: cnblogs关键字:8051系列  单片机  软件精确延时 手机看文章 扫描二维码
随时随地手机看文章

前言

  最近自学STC公司的8051系列单片机,编程中如流水灯等非精确延时多用软件延时实现,写了几个类似DelayX10us(unsigned char x)的函数方便调用,函数内部的语句多是用STC官方延时程序再自己套一个for或者do..while循环改造而成,像这样:


//非精确延时10*Xus

//@12.000MHz 12T模式

void DelayX10us(unsigned char x)        

{

    unsigned char i;

    for (; x > 0; x--)

    {

        _nop_();

        i = 2;

        while (--i);

    }

}


  由于不懂汇编,所以对代码的实际延时时间一直没有深究,每次都是凭感觉摸索个大概。今天突然心血来潮在keil仿真中执行了一下以上代码,观察了一下延时时间,得到结果如下:

X延时目标(us)实际延时(us)误差
11024140%
1010015050%
1001000141041%

 

 

 

  




  OMG,100us误差达到50%,延时1000us误差也有41%,这还真是“非(常的)精确”啊。

  突然觉得有必要研究一下汇编代码,搞懂这个延时是怎么误差这么大的。学习嘛,就不该留盲点,也正好借此机会了解一下汇编语言,对理解单片机底层应该有一定帮助。如果编程人员对自己写的代码底层如何实现一清二楚,那溢出、内存泄漏什么的bug就绝不会存在了。当然,要达到这个理想情况是很难的,只能朝着这个方向多努力了。

  写了一段代码做研究用,如下:


#include

#include


void DelayX10us(unsigned char x);

void main()

{

    DelayX10us(1);

    DelayX10us(10);

    DelayX10us(100);

    while (1);

}


//@12.000MHz 12T

void DelayX10us(unsigned char x)

{

    unsigned char i;

    for (; x > 0; x--)

    {

        _nop_();

        i = 2;

        while (--i);

    }

}


反汇编代码

  顺便说一下,软件环境:Keil uvison 4。

  上述代码编译完后,点击'Start Debug'开始调试,Disassembly窗口中就显示出了相应的反汇编代码,还显示了C语言与汇编代码的对应关系,比在Linux环境下调试方便多了。

main()函数:

DelayX10us()函数

 

  查芯片手册中指令系统部分内容可知,上述代码中LCALL、SJMP、JC、DJNZ、RET这几个指令是2机器周期指令,其余是1机器周期指令。现在开始来计算延时时间:

  x=1: 


main()中for循环返回总  计
机器周期   1+2(1+1+1+2   +1+1+2*2   +1+2)*1 +1+1+1+2 2  24

 

 

  说明:1、main()中传值和跳转两个操作周期为1+2。

       2、0x0016  SUBB A,0x00 为执行借位减法,可以简单理解为将A-0x00-Cy(进位借位标识,也就是上一句中的C)的结果装入A,并判断如果够减(结果>=0),Cy=0(未产生借位);如果不够减(结果<0),Cy=1(产生借位)。所以当A>=1时,都够减,Cy=0,下一句JC不会跳转,直到A=0不够减时才跳转。(A就是X的值)

     3、for循环中,第一次从0x0014到0x0020执行完,周期数为1+1+1+2   +1+1+2*2   +1+2,此时R7寄存器中存储的x值为0;此时已跳转到0x0014继续执行,直到0x0018,跳转到0x0022,周期数为1+1+1+2。返回main()函数又花两个周期。所以main()中'DelayX10us(1);'共耗费24个,12M/12T模式下即为24us。

  同理,x=10:


main()中for循环返回总  计
机器周期   1+2(1+1+1+2   +1+1+2*2   +1+2)*10 +1+1+1+2 2  150

 

 

  x=100时同理1+2  +(1+1+1+2+1+1+2*2+1+2)*100  +1+1+1+2  +2 = 1410

小结

    综上可看出,单纯的在官方延时函数基础上套for循环而得到的延时相当不精确。分析误差原因可知,main()中的3个周期、子函数返回的2个周期、for循环末尾的(1+1+1+2)个周期,这10个机器周期是固定误差值,最关键的在于涂黄部分共14个周期,超出了预期的10us倍增的延时。把这部分稍微改一下,使括号内涂黄部分变为10个机器周期,这样子就能使所有的x倍延时的误差值都为固定误差10us了。更改后的代码如下:


//非精确延时10*X us,固定误差10us

//@12.000MHz 12T模式

void DelayX10us(unsigned char x)        

{

    unsigned char i;

    for (; x > 0; x--)

    {

        _nop_();

        _nop_();

    }

}


  更改后的延时机器周期数=1+2  +(1+1+1+2  +1+1 +1+2)*X  +1+1+1+2  +2 = 10*X+10。X在1~255取值范围内,误差均为固定10us。

 

PS:本文所有延时都是在12MHz晶振、12T模式下计算,1个机器周期=1us。

   反汇编代码为Keil软件内代码优化等级level 8下编译后的反汇编。不同优化等级编译的代码反汇编后有稍许差别,再次不做论述。


关键字:8051系列  单片机  软件精确延时 引用地址:8051系列单片机软件精确延时研究(一)

上一篇:8051系列单片机软件精确延时研究(二)
下一篇:4个74HC595级联控制16x16点阵横向滚动带仿真(二)

推荐阅读最新更新时间:2026-03-20 12:29

8051系列单片机软件精确延时研究(一)
前言   最近自学STC公司的8051系列单片机,编程中如流水灯等非精确延时多用软件延时实现,写了几个类似DelayX10us(unsigned char x)的函数方便调用,函数内部的语句多是用STC官方延时程序再自己套一个for或者do..while循环改造而成,像这样: //非精确延时10*Xus //@12.000MHz 12T模式 void DelayX10us(unsigned char x) { unsigned char i; for (; x 0; x--) { _nop_(); i = 2; while (--i); } }   由于不懂汇编,所以对代码
[单片机]
<font color='red'>8051</font><font color='red'>系列</font><font color='red'>单片机</font><font color='red'>软件</font><font color='red'>精确</font><font color='red'>延时</font>研究(一)
通过单片机软件实现精确延时
  在很多情况下,定时器/计数器经常被用作其他用途或者无法实现时,只能用软件方法延时,比如,延时超过定时器定时范围的最大值。下面我们来分析一下通过软件实现的延时。      1.较短时间的精确延时      在汇编语言里,我们可以用NOP(空操作指令)来实现,一条NOP指令占用一个机器周期,比如我们用12MHz晶振,执行一条NOP指令,它就可以延时lμs,精确度可以达到1μ。使用也比较方便,我们可以在需要延时的程序中直接加上NOP指令即可实现延时。      同样,我们可以在C51中通过使用带一NOP-()语句的函数实现,_NOP-()就相当于汇编中的NOP指令,我们可以定义一系列不同的延时函数,比如Delayl0μs   D
[单片机]
通过<font color='red'>单片机</font><font color='red'>软件</font>实现<font color='red'>精确</font><font color='red'>延时</font>
利用Keil u3调试,精确实现软件延时
用定时器延时,有时候显得有点麻烦,我们不如考虑软件精确延时,软件延时无非就是利用for或while多重循环。以前用到延时函数时,都是从网上下载别人写好的延时子程序。延时5ms,400ms,1s, ,这些延时函数的函数名中都清清楚楚地标明了延时的时间,可我一直不知道这些函数是如何编写的,确切地说,是如果根据延时时间来确定循环次数的。如果是纳秒级的延时,可以通过示波器来观察波形,或者反汇编一下,计算一下指令执行时间,但如果延时时间相对较长,示波器便无能为力了。这几天好好看了一下Keil调试,发现Keil的功能实在是太强大了。利用Keil uVersion的调试就可以写出精确的软件延时程序。以下是我的简单小结,文中所有程序都是在Xtal=
[单片机]
基于C8051F2xx系列MCU芯片实现锅炉水处理控制装置的设计
自然水中通常含有钙镁等离子,俗称硬水。在锅炉用水中需要去除水中的钙镁离子而形成软水以防止锅炉结垢。在生产中锅炉水的软化处理是一项重要的安全指标,所以,对于锅炉水处理的技术要求愈来愈高。单片机以其较高的灵活性和稳定性广泛应用在自动控制领域。本文所设计的锅炉水处理控制装置,由高低水位控制进水阀开关,选用单片机为核心,C语言编程实现循环时间电路控制。该装置已成功应用于成都富华水处理公司。 1 软水生产工艺过程及对自控系统的要求 1.1 生产工艺过程 软化水设备的工作原理是基于阳离子交换原理。水由交换柱上流下,与交换树脂中的盐离子充分接触达到把原水中的杂质、易结垢的重金属阳离子去除掉。其生产工艺大致分为下列几步:①条件满足后运行;②松
[单片机]
基于C<font color='red'>8051</font>F2xx<font color='red'>系列</font><font color='red'>MCU</font>芯片实现锅炉水处理控制装置的设计
基于8051增强型单片机的RJM8L系列超低功耗MCU介绍
对于一些采用电池供电的产品需要长达数年不换电池情况下能连续工作,系统低功耗设计就尤为重要。MCU微控制器的低功耗设计决定系统的成败关键。MCU微控制器的低功耗技术涉及到软件、系统和底层的硬件工艺等。对于应用来说,在空闲的时候,可以将其时钟关闭以节省动态功耗,或小部分电路以低速低功耗的方式运行,SRAM的读写动态功耗相当可观,因此应该尽量减少读写SRAM。 瑞纳捷针对低功耗应用推出了RJM8L151S和RJM8L003系列产品,已大量应用到各领域,如:烟雾报警器,LoRa模组,智能门锁,灯控设备,GPS定位器,安防探测器,电子烟等应用领域。 RJM8L151S和RJM8L003系列产品是基于8051增强型单片机,工作电压2.
[单片机]
基于<font color='red'>8051</font>增强型<font color='red'>单片机</font>的RJM8L<font color='red'>系列</font>超低功耗<font color='red'>MCU</font>介绍
8051内核锦锐MCU开发指南:CA51F3系列
一、锦锐MCU简介 公司官网:深圳市锦锐科技有限公司 http://www.cachip.com.cn 主要产品:   8 bit Flash单片机系列    * CA51F0系列(AD + PWM类型)    * CA51F2系列(LCD + 触摸类型)    * CA51F3系列(AD + 触摸类型)    * CA51F4系列(LCD驱动升压类型)    * CA51F5系列(PWM + 触摸类型)   收音机系列    * 手调收音芯片    * 手调数显立体声收音芯片    * PLL电调收音芯片    * PLL电调收音RDS芯片    * WB灾难预警收音芯片   DAB接收模组系列    * C912 DAB接收模
[单片机]
<font color='red'>8051</font>内核锦锐<font color='red'>MCU</font>开发指南:CA51F3<font color='red'>系列</font>
HOLTEK推出HT85F2280/70/60 8051 A/D Flash Type MCU系列
Holtek推出全新的8051 A/D Flash Type MCU的HT85F2280、HT85F2270、HT85F2260系列,全系列宽工作电压范围2.2V~5.5V,符合工业等级-40℃ ~ 85℃工作温度与高抗噪声之性能要求,是一系列混合信号高性能MCU,使用1T Pipeline架构8051 CPU,做为高速数据处理引擎,内建高速12-bit ADC及可程序增益放大器(PGA),为嵌入式系统提供一个SOC应用平台。 HT85F2280、HT85F2270、HT85F2260 8051 A/D Flash Type MCU系列Program Memory为16Kx8 ~ 64Kx8、SRAM由1280 ~ 2304
[单片机]
基于C8051F系列单片机的标签打印机接口设计
摘要:为满足与日俱增的嵌入式系统的打印需求,设计了一种以片上系统型C8051F系列单片机为主机控制器的标签打印机接口模块。详细阐述了单片机与打印机之间的串行接口设计方法和斑马公司标签打印机专用的EPL2打印描述语言的使用,在掌握EPL2语言的基础上,利用KeilC编程工具进行驱动程序的编写,并给出了相应的驱动程序,实现了C8051F020单片机通过RS 232接口对一种标签打印机的控制。 关键词:C8051F020;标签打印机;串行接口;EPL2 0 引言 随着信息化技术的高速发展,各行业对于数据打印的需求日益增加。为了能够更加直观的浏览数据,微型标签打印机在智能仪器仪表、电子收款机、计价器等系统中几乎成为标准配置。本课题来
[工业控制]
基于C<font color='red'>8051</font>F<font color='red'>系列</font><font color='red'>单片机</font>的标签打印机接口设计
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved