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点阵横向滚动带仿真(二)

推荐阅读最新更新时间:2024-11-06 11:13

AVR单片机的端口位操作方法解析
一、常规方法 AVR单片机的各类教材或编程应用参考资料,对介绍的端口位操作方法不外乎宏定义及整体和某个常量相或、相与来实现某一单个位状态的改变。如: PORT&=-(1《1);等价于:PORTB&=oxfd;作用是PB1清零而其余位不变。与之类似的还有: PORTBl=(1《4);PB4置位,其余位不变。 PORTB=(k《4);PB4翻转,其余位不变。 上述方法,无论是常量值参与还是移位操作,用起来总嫌麻烦,不够直观,且具体常量值还需人工推算,易出错。移位操作生成的目标代码偏大,在大量运用时,占用系统内存或flash空间,执行效率低。 以实际运用效果来看,宏定义比较好。也偏好运用宏定义。C编译器在编译之前会事先进行宏替换
[单片机]
AVR<font color='red'>单片机</font>的端口位操作方法解析
基于MCU的汽车方向盘按键控制器系统设计
随着汽车在人们日常生活中的普及以及汽车电子在汽车应用领域价值不断地扩大,越来越多的舒适性能和“智能”应用被集成进车身电子的领域。飞思卡尔最新的汽车级8位微控制器MC9S08SC4 便是本文所要介绍的主角,该款微控制器是业界使用广泛的飞思卡尔HCS08系列汽车级微控制器家族最新的成员,以其低成本、小封装但同时兼具高性能、高可靠性的特点,适用于众多汽车电子应用领域,例如:简单的灯光控制、按键控制、HVAC、LIN通信控制器、车内后视镜调光以及简单的继电器和马达控制。如果你正在为你的应用物色一颗高性能、低成本的汽车级微控制器,但又为电子模块成本和PCB面积的限制而苦恼,相信MC9S08SC4正是你要找的这颗芯片。 MC9S08SC4的片
[嵌入式]
STM32单片机芯片介绍
无论做什么芯片的开发,都需要看芯片手册及其附带的资料。针对STM32单片机,我们能够借鉴的手册有《Cortex-M3权威指南(中文)》《STM32中文参考手册》(通常都是英文的,我们再翻译,这也是懂一些基础英语的重要性),此外,还有官方的《ST MCU选型手册》《STM32F103RC_Datasheet》。 其实除了ST意法半导体公司出厂的芯片,还有许多像NXP出品的32位芯片,也并不是只有简简单单的STM32F103RC系列的芯片,还有F2、F4系列等等。 上图就是官方提供的选型图片,相信看完就大概知道自己根据功能选什么系列的芯片了。正是由于芯片的多样性,业内使用ST意法半导体制作的芯片的公司还是处于多数的。 那么ST
[单片机]
STM32<font color='red'>单片机</font>芯片介绍
51单片机定时器/计数器的结构以及原理介绍
定时器/计数器简称定时器,其作用主要包括产生各种时标间隔、记录外部事件的数量等,是微机中最常用、最基本的部件之一。803l单片机有2个16位的定时器/计数器:定时器0(T0)和定时器1(T1)。 T0由2个定时寄存器TH0和TL0构成,T1则由TH1和TL1构成,它们都分别映射在特殊功能寄存器中,从而可以通过对特殊功能寄存器中这些寄存器的读写来实现对这两个定时器的操作。作定时器时,每一个机器周期定时寄存器自动加l,所以定时器也可看作是计量机器周期的计数器。由于每个机器周期为12个时钟振荡周期,所以定时的分辨率是时钟振荡频率的1/12。作计数器时,只要在单片机外部引脚T0(或T1)有从1到0电平的负跳变,计数器就自动加1。计数的
[单片机]
51<font color='red'>单片机</font>定时器/计数器的结构以及原理介绍
HOLTEK推出HT56RU25 e-Banking智能卡读卡器MCU
Holtek推出e-Banking智能卡读卡器MCU -- HT56RU25,继HT56RB27、HT56RB688 USB接口单片机之后,推出全新UART接口单片机。HT56RU25内建ISO7816-3接口,并整合DC/DC与LDO至单片机内,同时支持1.8V/ 3V/ 5V三种卡片电压规格,ISO7816-3可符合国际EMV 4.3与中国PBOC 3.0 Contact Level 1规范认证,可应用于各种智能卡读卡器产品。其内建的高精准度32.768kHz LXT振荡器,LXT工作时MCU低待机电流,更适合电池产品的应用。 HT56RU25的特点在于工业规格(-40~85℃)、工作电压2.2V ~ 5.5V、具有1
[单片机]
基于MSP430单片机和nRF905的无线通信系统
随着信息技术的不断发展,人们对通信技术的需求越来越强,摆脱有线网络的束缚实现无线通信始终是大家关心的问题,当今无线通信研究越来越热,应用非常广泛,使人与人之间的通信更加方便快捷,更具有市场发展前景。本文以Nordic公司的nRF905作为通讯的核心,设计了无线通信系统。 系统设计 无线通信系统,由两个部分组成:发送终端,接收终端。数据的发送和接收显示是借助于串口来实现的,通过PC机串口给发送终端送数据,然后发送终端通过nRF905把数据发送出去;接收终端通过nRF905接收数据,然后把接收到的数据通过串口传给PC机。系统框图如图1所示。 无线系统的硬软件设计 系统的硬件设计 本系统采用的射频收发器为Nordic VL
[模拟电子]
基于MSP430<font color='red'>单片机</font>和nRF905的无线通信系统
单片机C语言程序设计:100 000s 以内的计时程序
/* 名称:100 000s 以内的计时程序 说明:在 6 只数码管上完成 0~99 999.9s。 */ #include reg51.h #include intrins.h #define uchar unsigned char #define uint unsigned int //段码 uchar code DSY_CODE ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //6 只数码管上显示的数字 uchar Digits_of_6DSY ={0,0,0,0,0,0}; uchar Count; sbit Dot=P0^7; //
[单片机]
<font color='red'>单片机</font>C语言程序设计:100 000s 以内的计时程序
单片机在变频调速系统中的应用
1 引 言   随着大功率开关器件制造技术和计算机技术的迅猛发展,变频调速以其自身功能完善、性能可靠、节能显著等优点,已广泛应用于工农业生产和生活等领域。目前,高性能变频调速系统的研究和开发已引起各国专家的高度重视。   城市供气系统的负载现在主要是风机,而风机类负载适于变频调速,并且节能显著,因此,变频调速在城市供气系统中推广非常快。但对较复杂的系统,变频调速设计很难取得最佳的效果。本文正是针对这一问题,结合本地气站的变频调速技术改造而进行的研究。该系统以M68HC908J12单片机为核心,实现了变频器与多风机的有机配合,抗干扰能力强,节能效率高,供气质量好,并降低了成本。实验证明具有很高的推广价值。 2 M68HC908J12单
[单片机]
<font color='red'>单片机</font>在变频调速系统中的应用
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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