Transport Delay

Transport Delay
Transport Delay

传输延迟Transport Delay

(此模块可以将一个函数延迟,在时轴上相当于将此一函数整体地向右平移)

按给定的时间量输入延迟

文库

连续

描述

传输延迟模块以一个指定的时间量延迟输入信号。你可以使用这个模块来模拟一个时间延迟。输入到这个

模块的信号应该是一个连续的信号。

在仿真开始时,这个模块输出初始输出参数,直到仿真时间超过延时时间参数。然后,在模块开始产生延

迟的输入。在仿真过程中,模块存储输入点和模拟时间在缓冲器中。你可以通过设置初始缓冲区大小参数

来指定此大小。

当在某一时刻你希望的输出不对应于所存储的输入值的时,该模块利用线性插值在其中插入点。当延迟时

间小于步长时,则模块从最后的输出点外推,它可以产生不准确的结果。因为该模块不能直接馈通,所以

不能使用当前的输入来计算输出值。例如,考虑一个步长大小1的固定步长仿真和当前时间在t = 5。如果

延迟是0.5,模块必须产生一个点在t = 4.5。因为最近存储的时间值是在t = 4时,该模块执行前向外推。

传输延迟块不能插值离散信号。相反,该模块返回离散值在要求的时间。

此块不同于单位延迟块,从而延缓并保持样品的输出只命中。

技巧避免使用linmod来线性化包含传输延迟块模型。欲了解更多信息,请参阅线性化模型在Simulink中?文档。数据类型支持

传输延迟模块能够接受和输出double型数据。

欲了解更多信息,请参见通过Simulink中支持的数据类型的Simulink的文档中。

参数和对话框

延时时间

指定仿真时间量来延时输入信号在传播到输出之前。

设置

默认值:1

该值必须为正数。

命令行信息

见模块特定参数的命令行信息。

初始输出

指定的模块产生的输出,直到仿真时间第一次超过该时间延迟的输入。

设置

默认值:0

该模块的初始输出不能是inf或NAN的。

命令行信息

见块特定参数的命令行信息。

最初的缓冲区大小

定义初始内存分配为存储输入点数目。

设置

默认值:1024

?如果输入点的数量超过了初始的缓冲区大小,模块分配附加的存储器。

?模拟结束后,一个消息显示总缓冲区大小需要。

技巧

?因为分配内存减慢仿真,如果模拟速度是一个问题,应谨慎选择这个值,。?长时间的延迟,这个模块可以使用大量的内存,特别是量纲的输入。

命令行信息

见块特定参数的命令行信息。

使用固定的缓冲区大小

指定使用一个固定大小的缓冲区,从以前的时间步中保存输入的数据。

设置

默认值:off

on

该模块使用一个固定大小的缓冲区。

off

该块不使用固定大小的缓冲区。

初始缓冲区大小参数指定的缓冲区的大小。如果缓冲区已满,新的数据替换已经在缓冲区中的数据。

Simulink软件使用线性外推法估算那些不在缓冲区中的输出值。

注意:如果你有一个Simulink的编译器?注册码,ERT或GRT代码生成使用一个固定大小的缓冲区,即使你不选择此复选框。

技巧

?如果输入的数据是线性的,选中此复选框可以节省内存。

?如果输入的数据是非线性的,请不要选择此复选框。这样做可能会产生不准确的结果。

命令行信息

见块特定参数的命令行信息。

输入的线性化过程中直接馈通

导致该模块输出其输入在线性化过程中和装饰,这设置模块模式为直接馈通。

设置

默认值:off

on

允许输入的直接反馈。

off

禁止输入的直接反馈。

温馨提示

?当您使用功能,选中此复选框会导致状态的顺序的改变在模型linmod,dlinmod,或trim。要提取的新状态排序:

1. 编译模型使用下面的命令,其中模型的名称是Simulink模型。

[sizes,x0,x_str]=model([],[],[],'lincompile');

2. 终止编译使用下面的命令。

model([],[],[],'term');

?输出参数x_str,这是在Simulink模型的状态的单元阵列,包含新状态排序。当你传递状态的向量作为输入linmod,dlinmod,或trim,状态向量必须使用这个新的顺序。

命令行信息

见块特定参数的命令行信息。

帕德顺序(线性)

设置Pade近似为线性化程序的顺序。

设置

默认值:0

?缺省值是0,这导致单位增益没有动态状态。

?设置顺序为正整数n增加n状态到你的模型,但结果在运输延误的更准确的线性模型。

命令行信息

见块特定参数的命令行信息。

特性

另请参阅可变延时

STM32延时函数

#include #include "delay.h" ////////////////////////////////////////////////////////////////////////////////// //使用SysTick的普通计数模式对延迟进行管理 //包括delay_us,delay_ms //***************************************************************************** *** //V1.2修改说明 //修正了中断中调用出现死循环的错误 //防止延时不准确,采用do while结构! ////////////////////////////////////////////////////////////////////////////////// static u8 fac_us=0;//us延时倍乘数 static u16 fac_ms=0;//ms延时倍乘数 //初始化延迟函数 //SYSTICK的时钟固定为HCLK时钟的1/8 //SYSCLK:系统时钟 void delay_init(u8 SYSCLK) { SysTick->CTRL&=0xfffffffb;//bit2清空,选择外部时钟HCLK/8 fac_us=SYSCLK/8; fac_ms=(u16)fac_us*1000; } //延时nms //注意nms的范围 //SysTick->LOAD为24位寄存器,所以,最大延时为: //nms<=0xffffff*8*1000/SYSCLK //SYSCLK单位为Hz,nms单位为ms //对72M条件下,nms<=1864 void delay_ms(u16 nms) { u32 temp; SysTick->LOAD=(u32)nms*fac_ms;//时间加载(SysTick->LOAD为24bit) SysTick->VAL =0x00; //清空计数器 SysTick->CTRL=0x01 ; //开始倒数 do { temp=SysTick->CTRL; } while(temp&0x01&&!(temp&(1<<16)));//等待时间到达 SysTick->CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器 } //延时nus //nus为要延时的us数.

delay延时教程

delay延时教程(用的是12MHz晶振的MCS-51) 一、 1)NOP指令为单周期指令 2)DJNZ指令为双周期指令 3)mov指令为单周期指令 4)子程序调用(即LCALL指令)为双周期指令 5)ret为双周期指令 states是指令周期数, sec是时间,=指令周期×states,设置好晶振频率就是准确的了 调试>设置/取消断点”设置或移除断点,也可以用鼠标在该行双击实现同样的功能 二、编程最好: 1.尽量使用unsigned型的数据结构。 2.尽量使用char型,实在不够用再用int,然后才是long。 3.如果有可能,不要用浮点型。 4.使用简洁的代码,因为按照经验,简洁的C代码往往可以生成简洁的目标代码(虽说不是在所有的情况下都成立)。 5.在do…while,while语句中,循环体内变量也采用减减方法。 三、编辑注意: 1、在C51中进行精确的延时子程序设计时,尽量不要或少在延时子程序中定义局部变量,所有的延时子程序中变量通过有参函数传递。 2、在延时子程序设计时,采用do…while,结构做循环体要比for结构做循环体好。 3、在延时子程序设计时,要进行循环体嵌套时,采用先内循环,再减减比先减减,再内循环要好。 四、a:delaytime为us级 直接调用库函数: #include// 声明了void _nop_(void); _nop_(); // 产生一条NOP指令 作用:对于延时很短的,要求在us级的,采用“_nop_”函数,这个函数相当汇编NOP指令,延时几微秒。 eg:可以在C文件中通过使用带_NOP_( )语句的函数实现,定义一系列不同的延时函数,如Delay10us( )、Delay25us( )、Delay40us( )等存放在一个自定义的C 文件中,需要时在主程序中直接调用。如延时10 μs的延时函数可编写如下: void Delay10us( ) { _NOP_( ); _NOP_( );

空函数(延时)

nop函数可以用来延时,请问1个NOP延时多少时间,怎么计算? 附一段说明: void _nop( void ); A NOP instruction is generated, before and behind the nop instruction the peephole is flushed. Code generation for _nop() is exactly the same as the following inline assembly. #pragma asm nop ; inline nop instruction #pragma endasm Returns nothing. value = P0; /* read from port P0 */ MOV R12,P0 _nop(); /* delay for one cycle */ NOP P1 = value; /* write to port P1 */ MOV P1,R12 单片机c语言中nop函数的使用方法和延时计算默认分类2010-08-28 15:39:40 阅读41 评论0 字号:大中小订阅. 标准的C语言中没有空语句。但在单片机的C语言编程中,经常需要用几个空指令产生短延时的效果。 这在汇编语言中很容易实现,写几个nop就行了。 在keil C51中,直接调用库函数: #include // 声明了void _nop_(void); _nop_(); // 产生一条NOP指令 作用:对于延时很短的,要求在us级的,采用“_nop_”函数,这个函数相当汇编NOP 指令,延时几微秒。 NOP指令为单周期指令,可由晶振频率算出延时时间,对于12M晶振,延时1uS。 对于延时比较长的,要求在大于10us,采用C51中的循环语句来实现。 在选择C51中循环语句时,要注意以下几个问题 第一、定义的C51中循环变量,尽量采用无符号字符型变量。 第二、在FOR循环语句中,尽量采用变量减减来做循环。 第三、在do…while,while语句中,循环体内变量也采用减减方法。 这因为在C51编译器中,对不同的循环方法,采用不同的指令来完成的。

CVAVR 软件中启动delay库,调用delay_ms()函数,自动带了喂狗程序

CV A VR 软件中启动delay.h库,调用delay_ms()函数,自动带了喂狗程序 近期在学习中发现个问题,CV A VR 中启动delay.h库,调用delay_ms()函数延时,系统怎么都不复位重启,即使打开看门狗熔丝位,看门狗也不会重启,找了很久原因,发现是调用调用系统自身带的delay_ms()函数引起的,换成自己的简单延时函数,问题就解决,看门狗可以正常工作,后面附带我自己写的简单延时函数。 后来查找问题,发现系统中的delay_ms()函数自带了喂狗程序,所以不会自动的重启,请大家放心使用,用延时函数看门狗不溢出是正常的。后面附带软件编辑后生产的汇编程序,一看就知道确实带了喂狗。 今天写出来供大家注意,不要犯我同样的问题。 /***************************************************** This program was produced by the CodeWizardA VR V1.25.9 Standard Chip type : A Tmega8L Program type : Application Clock frequency : 1.000000 MHz Memory model : Small External SRAM size : 0 Data Stack size : 256 *****************************************************/ #include #include // Declare your global variables here void main(void) { // Declare your local variables here // Input/Output Ports initialization // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTB=0x00; DDRB=0x00; // Port C initialization // Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTC=0x00; DDRC=0x00; // Port D initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T

c语言delay的用法

c语言delay的用法 另外在特殊情况下,计时器甚至已经全部用于其他方面的定时处理,此时就只能使用软件定时了。 下面就和大家分享下c语言delay的用法1 C语言程序延时Keil C51的编程语言常用的有2种:一种是汇编语言;另一种是C 语言。 用汇编语言写单片机程序时,精确时间延时是相对容易解决的。 比如,用的是晶振频率为12 MHz的AT89C51,打算延时20 μs,51单片机的指令周期是晶振频率的1/12,即一个机器周期为1 μs;“MOV R0,#X需要2个机器周期,DJNZ也需要2个机器周期,单循环延时时间t=2X+3(X为装入寄存器R0的时间常数)[2]。 这样,存入R0里的数初始化为8即可,其精度可以达到1 μs。 用这种方法,可以非常方便地实现512 μs以下时间的延时。 如果需要更长时间,可以使用两层或更多层的嵌套,当然其精度误差会随着嵌套层的增加而成倍增加。 虽然汇编语言的机器代码生成效率很高,但可读性却并不强,复杂一点的程序就更难读懂;而C语言在大多数情况下,其机器代码生成效率和汇编语言相当,但可读性和可移植性却远远超过汇编语言,且C 语言还可以嵌入汇编程序来解决高时效性的代码编写问题。 就开发周期而言,中大型软件的编写使用C 语言的开发周期通常要比汇编语言短很多,因此研究C语言程序的精确延时性能具有重要的意义。

C程序中可使用不同类型的变量来进行延时设计。 经实验测试,使用unsigned char类型具有比unsigned int更优化的代码,在使用时应该使用unsigned char作为延时变量。 经过测试,第1次执行到断点处的时间为457 μs,再次执行到该处的时间为531 μs,第3次执行到断点处的时间为605 μs,10次while 循环的时间为74 μs,整个测试结果如图2所示。 图2 使用i--方式测试仿真结果图通过对汇编代码分析,时间延迟 t=7X+4(其中X为i的取值)。 测试表明,for循环方式虽然生成的代码与用while语句不大一样,但是这两种方法的效率几乎相同。 C语言中的自减方式有两种,前面都使用的是i--的方式,能不能使用--i方式来获得不同的效果呢?将前面的主函数保持不变,delay1函数修改为下面的方式:void delay1(unsigned char i) {while(--i);}同样进行反汇编,得到如下结果:C:0x00E3DFFEDJNZR7,C:00E3C:0x00E522RET比较发现,--i的汇编代码效率明显高于i--方式。 由于只有1条语句DJNZ,执行只需要2个时钟周期,1个时钟周期按1 μs计算,其延时精度为2 μs;另外,RET需要2个时钟周期,能够达到汇编语言代码的效率。 按前面的测试条件进行测试,第1次执行到断点处的时间为437 μs,再次执行到该处的时间为465 μs,第3次执行到断点处的时间为493 μs,10次while循环的时间为28 μs,整个测试结果如图3所示。

delay

1.毫秒级的延时 延时1ms; void delay_1ms(void){ unsigned int i; for(i=1;i<(unsigned int)(xtal*143-2);i++); } 在上式中,xtal为晶振频率,单位为MHz. AVR 延时程序 当晶振频率为8M时,延时函数软件仿真的结果为1000.25μs.当晶振频率为4M 时,延时函数软件仿真结果为999.5μs. AVR 延时程序 如果需要准确的1ms延时时间,则本计算公式只供参考,应通过软件仿真后,再确定循环的次数及循环初值,并且循环中还必须关闭全局中断,防止中断影响延时函数的延时时间。 下面的函数可以获得1ms的整数倍的延时时间: void delay(unsigned int n) {unsigned int i; for(i=0;i delay_1ms(); }如果需要准确的延时时间,则本计算公式只供参考,应通过软件仿真后,再确定循环的次数及循环初值. AVR 延时程序 2.微秒延时 晶振4M,编辑器ICCAVR,芯片mega16 //最大延时时间131.072ms void delay(unsigned int i) //延时时间T=2*(i+1)us其中1= { while(--i);}

晶振频率为8MHz时1μs延时函数:AVR 延时程序 void delay_1us(void){ asm("nop");} 当然也可以使用宏定义来实现1μs延时: #define delay_1us(); asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");as m("nop") 如果小于1μs的延时,只有使用宏定义实现,当然,也可以直接插入在线汇编 asm("nop"); 语句实现延时。 在程序中需要微秒级的延时时,可以用以下函数实现。AVR 延时程序 void delay_us(unsigned int n) { unsigned int i; for(i=0;i delay_1us(); } 说明:如果需要准确的延时时间,则还必须关中断,并通过软件仿真后,再确定循环的次数及循环初值. 强调:在实际应用中一般不直接使用软件进行长时间的延时,AVR 延时程序,因为MCU一直停留延时函数中(称为阻断),不能再干其它的事睛(除了中断外),只有非常简单的应用或者简单的演示时才能使用延时函数实现长时间延时。实际应用中,对长时间(较简单任务一般指几十毫秒以上,对于复杂的应用,一般指几毫秒以上)的延时,应采用非阻断式的延时方式,或者使用定时器中断来完成延时。

延时计算公式_各种编译延时小函数

C程序中可使用不同类型的变量来进行延时设计。经实验测试,使用unsigned char类型具有比unsigned int更优化的代码,在使用时应该使用unsigned char作为延时变量。以某晶振为12MHz 的单片机为例,晶振为12MHz即一个机器周期为1us。 一. 500ms延时子程序 void delay500ms(void) { unsigned char i,j,k; for(i=15;i>0;i--) for(j=202;j>0;j--) for(k=81;k>0;k--); } 计算分析: 程序共有三层循环 一层循环n:R5*2 = 81*2 = 162us DJNZ 2us 二层循环m:R6*(n+3) = 202*165 = 33330us DJNZ 2us + R5赋值 1us = 3us 三层循环: R7*(m+3) = 15*33333 = 499995us DJNZ 2us + R6赋值 1us = 3us 循环外: 5us 子程序调用 2us + 子程序返回 2us + R7赋值 1us = 5us 总时间 = 三层循环 + 循环外 = 499995+5 = 500000us =500ms 计算公式:延时时间=[(2*R5+3)*R6+3]*R7+5 延时时间={[(2*第一层循环+3)*第二层循环+3]*第三层循环+3}*第四层循环+5 二. 200ms延时子程序 void delay200ms(void) { unsigned char i,j,k; for(i=5;i>0;i--) for(j=132;j>0;j--) for(k=150;k>0;k--); }

单片机编写延时函数的简单方法

编写延时函数的简单方法Post By:2010-6-21 0:26:01 在本站51hei-5板子上做315兆无线解码和红外解码试验的时候,延时函数的精度很重要,要做到相当精确才可以成功,所以大家一定要掌握. 这也是大家最常在QQ里问我的一个问题,如果从keil里看了c语言的反汇编代码然后根据晶振和指令计算延时的时间这样虽然非常的准确但是相当的麻烦而且容易搞错,我这里介绍一个最简单的方法.可以验证你的延时函数 这里用一个例程详细介绍一下。 过程参考如下: 在编译器下建立一个新项目,也可以利用已有项目。此过程中需要注意,单片机晶振的选择,因为for 循环里指令的执行时间和晶振有直接关系,本例中晶振使用11.0592M。 此主题相关图片如下:20090oc1.jpg 编写一段关于延时的函数,主要利用for循环,代码如下: void delay_ms(unsigned int ms) { unsigned int i; unsigned char j; for(i=0;i

for(j=0;j<102;j++); } } 其中ms是输入参数,如果输入1,就是要求程序延时1ms。 j变量是调整程序运行的时间参数。调整j的数值,使1次循环的时间在1ms。 将此程序编译通过,然后利用软件仿真,调整时间。 此主题相关图片如下:20090oc2.jpg 下面这个sec就是程序运行到现在的这一行所用的时间。 此主题相关图片如下:20090oc3.jpg

两次时间差就是延时函数使用的时间,如果与1ms相差比较多,用户可以调整j参数的值,使延时时间尽量接近1ms。如增大j的值for(j=0;j<105;j++); 此方法得出延时函数,在晶振不同的情况下,延时时间会不准。软件调试结果,这个程序的延时时间为:1.01779ms,一般的单片机系统中都可以应用。 下面来说说汇编的传统计算方法: 指令周期、机器周期与时钟周期 指令周期:CPU执行一条指令所需要的时间称为指令周期,它是以机器周期为单位的,指令不同,所需的机器周期也不同。 时钟周期:也称为振荡周期,一个时钟周期=晶振的倒数。 MCS-51单片机的一个机器周期=6个状态周期=12个时钟周期。 MCS-单片机的指令有单字节、双字节和三字节的,它们的指令周期不尽相同,一个单周期指令包含一个机器周期,即12个时钟周期,所以一条单周期指令被执行所占时间为12*(1/12000000)=1us。 了解了上面这些我们来看一个例子 ;============延时1秒子程序======================== DELAY_1S: MOV R4,#10 ;延时子程序,12M晶振延时1.002035秒 L3: MOV R2 ,#200 ;1指令周期 L1: MOV R3 ,#249 ;1指令周期 L2: DJNZ R3 ,L2 ;2指令周期 DJNZ R2 ,L1 ;2指令周期 DJNZ R4 ,L3 ;2指令周期 RET ;2指令周期 ;循环体延时时间: [(249*2+1+2)*200+1+2]*10*12/12000000=1.002030s

各种延时函数

void delay(uint z){ uint x,y; for(x=100;x>0;x--) for(y=z;y>0;y--); } void delay02s(void) //延时0.2秒子程序 { unsigned char i,j,k; //定义3个无符号字符型数据。 for(i=20;i>0;i--) //作循环延时 for(j=20;j>0;j--) for(k=248;k>0;k--); } void delay10ms() { for(a=100;a>0;a--) for(b=225;b>0;b--); } void delay(unsigned char i) { for(j=i;j>0;j--) for(k=125;k>0;k--); } void Delay_xMs(unsigned int x) { unsigned int i,j; for( i =0;i < x;i++ ) { for( j =0;j<3;j++ ); } } void delay(uint count) //delay { uint i; while(count) {

i=200; while(i>0) i--; count--; } } void delay(uint x) { uint a,b; for(a=x;a>0;a--) for(b=10;b>0;b--); } void delay(int ms) { while(ms--) { uchar i; for(i=0;i<250;i++) { _nop_(); _nop_(); _nop_(); _nop_(); } } } void delay(uint z) { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); }

C++中的延时函数

1.推荐用Sleep(); 1.推荐用Sleep(); MS VC++可以用MFC的Sleep函数,参数是毫秒。 包含在头文件里 /*#include #include using namespace std; void main() { Sleep(1000);//延时1秒 cout<<"adsd"< void delay(int sec) { time_t start_time, cur_time; // 变量声明 time(&start_time); do { time(&cur_time); } while((cur_time - start_time) < sec ); } 然后就可以直接调用了 如: #include #include void delay(int sec)

{ time_t start_time, cur_time; // 变量声明 time(&start_time); do { time(&cur_time); } while((cur_time - start_time) < sec ); } void main() { cout<<"a"<

STM32延时函数

STM32延时函数 void delay_init(u8 SYSCLK) { SysTick->;CTRL&=0xfffffffb; fac_us=SYSCLK/8; fac_ms=(u16)fac_us*1000; } Systick 主要的作用就是拿来计时,其原理和应用简述 一下就是这样的:通过配置寄存器 SysTick->;CTRL来 设定Systick的计时频率并Enable使Systick开始计数,这里的 SysTick->;CTRL&=0xfffffffb应该很好理解, 把第2位设定为0,查找应用手册可以知道这是把 Systick的计时频率设定为CPU主频(SYSCLK)的1/8。 假定我们板子默认的晶振频率是8Mhz,默认CPU工作频 率(SYSCLK)是9倍频,即72M,那Systick的频率就是 72/8=9Mhz。 知道了Systick的频率,下一步就是确定倒时计数器的 数值,即SysTick->; LOAD这个寄存器的配置。上面已经知道了,Systick的工作频率F=9Mhz=SYSCLK/8,即每秒钟计数器自减900万次,也就是说,SYSCLK/8次的自减 耗时1秒,那么(8/SYSCLK)/1000,000次自减就耗时1

微秒了,这也就是fac_us的值了。那么上面函数中的 fac_us为什么是SYSCLK/8呢?这里先搞清楚一点,函数中SYSCLK的单位是Mhz,所以SYSCLK的值是72(这个以Mhz为单位应该是STM32基础库里面做过宏定义的),否则也不可能用一个8位整形去表示一个7200万的数值;而我们这里计算的SYSCLK是以Hz为单位的,即 72Mhz/1000,000=72,所以这个SYSCLK/8是对的。 你可能还没搞清楚 fac_us到底是干嘛的。很简单, fac_us就是要写入SysTick->; LOAD寄存器的值,Systick的工作原理是这个寄存器的值在Systick被Enable之后就开始以设定的工作频率自减,减到0的时 候就发出中断,实现定时。所以,写入fac_us到 SysTick->; LOAD寄存器,就是要Systick在自减了 fac_us次以后发出中断,自减fac_us所耗的时间已经说了,1微秒。 下面的fac_ms应该很好理解了,就是1毫秒的计数次数,刚好是1微妙的1000倍,注意9×1000超出了8 位整形的表示范围,所以要用(u16)先把fac_us转成16 位变量,以保证计算的正确。 具体的应用函数是用来做延时,如下: void delay_us(u32 nus) {

延时函数

延时函数 1、void delay(void) //两个void意思分别为无需返回值,没有参数传递 { unsigned int i; //定义无符号整数,最大取值范围65535 for(i=0;i<20000;i++) //做20000次空循环 ; //什么也不做,等待一个机器周期 } 2、void delay(void) { unsigned char i,j; for(i=0;i<250;i++) for(j=0;j<250;j++) ; } 3、void int_delay(void) //延时一段较长的时间 { unsigned int m; //定义无符号整形变量,双字节数据,值域为0~65535 for(m=0;m<36000;m++) ; //空操作 } 4、void char_delay(void) //延时一段较短的时间 { unsigned char i,j; //定义无符号字符型变量,单字节数据,值域0~255 for(i=0;i<200;i++) for(j=0;j<180;j++) ; //空操作 } //* for(a=2;a>0;a--) // 2微秒,执行2次(a+2)是4微秒; for(b=142;b>0;b--) // 2微秒,执行142次,for(a=2;a>0;a--)是4微秒,即2*(142*4);for(c=1;c>0;c--) // 2微秒, 执行1次,即2*(142*4)=1136微秒; b=125,1000/8=125,再减去其它调用时间,应该b取值不大于125。 追问: 这些时间是怎么得出来的? 追答: 51单片机执行一条指令一般是1---3微秒(12MHz),执行一条减一-判断-跳转指令,就是2

延时程序计算公式

CV A VR中提供了2个延时函数: The functions are: void delay_us(unsigned int n) generates a delay of n mseconds. n must be a constant expression. void delay_ms(unsigned int n) generates a delay of n milliseconds. This function automatically resets the watchdog timer every 1ms by generating the wdr instruction. 其中delay_us(unsigned int n)要求n是常数,因为us要准确,使用变量的话会大大影响精度。1us执行的指令不多。 在C程序中调用delay_us()后,你可以看生成的ASM代码,它不是使用CALL,而是用的宏,嵌入了一段代码。当你系统时钟为1M时,调用delay_us(1)还会编译出错,因为嵌入的一段代码,已经超过了1us! 而delay_ms(unsigned int n)中的N就可以是变量,它生成的汇编是采用CALL调用函数,两者不同。另外,在delay_ms()中还清WDT(就是你使用了WDT,也能使用该函数)。作为通用的delay_ms(),代码当然多了点。 以上可以查看CV A VR编译后产生的LST文件。 1。没有好的汇编基础,和对A VR的彻底透彻的掌握,一般人写不出比它还要优化的通用代码。 2。我已经说过多少遍了。在实际的系统中尽量不要使用软件延时,浪费资源不说,系统很难做到并行处理。因此对于10us以下的延时,考虑直接嵌入汇编的_nop_指令。10-100us可以适当考虑使用delay_us(),而大于100us的延时,应该采用定时器中断了。 /******************************************************************/ A VR单片机的指令,从执行每条指令的时钟数分:单时钟指令、双时钟指令、三时钟指令、四时钟指令4种,A VR单片机在外接8MHZ晶振时, 单时钟指令: ADC为例,每us(微秒)可以执行8条,即每条指令用时0.125us。 双时钟指令: rjmp为例:每us(微秒)可以执行4条,即每条指令用时0.25us。 三时钟指令: rcall为例:每us(微秒)可以执行8/3条,即每条指令用时0.375us。 四时钟指令: ret为例:每us(微秒)可以执行2条,即每条指令用时0.5us /****************************************************************************** 8M 延时计算公式 = 6.25+(n-1)*0.75 us 7.3728M 延时计算公式 = 6.78+(n-1)*0.81 us 或者 6.51+(n-1)*0.82 us 4M 延时计算公式 = 12.5+(n-1)*1.5 us 3.6864M 延时计算公式 = 13.56+(n-1)*1.63 us

各种延时程序及其讲解

/********************************************************************* ** ** 创建人:Fly ** 创建日期:2010.07.18 ** ** 实现功能:精确定时 ** 描述:几种方法实现精确定时 ** 1.中断InitTime0(); ** 2.合理运用_nop_(); Delay_10us();Delay_1s(); ** 3.循环控制void delay_50ms(unsigned int i) ** ** 适用机型:AT89S52 ** ********************************************************************/ #include #include unsigned char count = 0x00; long i; /********************************************************************* ** ** 实现功能:定时10us ** 描述:_nop_();空操作为1us ** ********************************************************************/ void Delay_10us() { _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); } /********************************************************************* ** ** 实现功能:定时1s ** 描述:用Delay_10us()来实现; 经过计算可得为3E01次 ** ********************************************************************/ void Delay_1s() { for(i=0x00; i<0x3E01; i++) //经过计算可得为3E01次

keilc的延时函数实例,delay函数

#define uchar unsigned char #define uint unsigned int void delay8us(uchar num) {uchar i,j; for(j=0;j

} void delay500ms(uchar num) {uchar i,j; for(j=0;j

解析GUI_Delay函数

解析GUI_Delay()函数 使用GUI_Delay()函数时,对于其延时时间不确定,明明设置为最小值1,延时时间仍旧太长,不能达到需求。遂决定研究明白其实现机理。 uC/OS-II使用OSTimeDly()函数实现延时,其单位是OS_TICKS,即延时多少个系统节拍。GUI使用GUI_Delay()函数延时,同时也实现显示刷新;基于同一个平台,估计也会调用OSTimeDly()函数以实现基本的延时功能。 下面分析GUI_Delay()函数功能 void GUI_Delay(int Period) { int EndTime = GUI_GetTime()+Period; int tRem; /* remaining Time */ GUI_ASSERT_NO_LOCK(); while (tRem = EndTime- GUI_GetTime(), tRem>0) { GUI_Exec(); GUI_X_Delay((tRem >5) ? 5 : tRem); } } 首先EndTime变量获得延时结束时间; 使用一个while循环,在结束时间之前循环调用GUI_Exec()函数和GUI_X_Delay()函数; 前者是GUI的刷新函数,保证在延时过程中不会停止GUI任务处理。后者就是我们要分析的延时函数GUI_X_Delay了。 参数用三目变量,每次送给延时的参数最大是5; 跟踪GUI_X_Delay()函数,在GUI_X_uCOS.C文件中实现。 void GUI_X_Delay (int period) { INT32U ticks; ticks = (period * 1000) / OS_TICKS_PER_SEC; OSTimeDly((INT16U)ticks); } 可以看到,在GUI_X_Delay()函数中调用了系统延时函数OSTimeDly(),就像前面我们说过的,OSTimeDly()函数的延时时间是系统节拍,如果要改变GUI_Delay()函数的延时时间,就需要从此着手。 再看看延时时间的取值:OS_TICKS_PER_SEC在OS_CFG.H中设置为100,即每秒产生100个系统节拍。ticks变量在这里被扩展了10倍。即GUI_Delay()函数传递一个延时参数1,而实际的延时时间就是10个节拍即100毫秒。在这个延时时间之内,调用GUI_Delay ()函数的任务就不能执行,使得响应速度慢。为保持源程序的风格一致,这里改period 的倍数为100,使GUI_Delay()函数的延时时间和OSTimeDly()函数时间单位一致,提高了响应速度增强其易用性。

AVR 中 delay 函数的调用注意事项!delay_ns delay_ms

早就知道AVR的编译器有自带的延时子函数(或者说是头文件),但一直没时间一探究竟,今天终于揭开了其内幕。 AVR编译器众多,可谓是百家齐鸣,本人独尊WinAVR. 说明:编译器版本WinAVR-20080610 先说winAVR的_Delay.h_肯定是在Include文件夹下了,进去一看果然有,可打开一看,其曰:“This file has been moved to ." 在util文件夹中找到delay头文件如下: -------------------------------------------------------------------------------------------------------------------------------------------- void _delay_us(double __us) { uint8_t __ticks; double __tmp = ((F_CPU) / 3e6) * __us; //3e6=3000000 if (__tmp< 1.0) __ticks = 1; else if (__tmp> 255) { _delay_ms(__us / 1000.0); return;

} else __ticks = (uint8_t)__tmp; _delay_loop_1(__ticks); } ----------------------------------------------------------------------------------------------------------------------------------------------- _delay_ms(double __ms) { uint16_t __ticks; double __tmp = ((F_CPU) / 4e3) * __ms; if (__tmp< 1.0) __ticks = 1; else if (__tmp> 65535) { // __ticks = requested delay in 1/10 ms __ticks = (uint16_t) (__ms * 10.0); while(__ticks) { // wait 1/10 ms

单片机c语言中nop函数的使用方法和延时计算

标准的C语言中没有空语句。但在单片机的C语言编程中,经常需要用几个空指令产生短延时的效果。 这在汇编语言中很容易实现,写几个nop就行了。 在keil C51中,直接调用库函数: #include // 声明了void _nop_(void); _nop_(); // 产生一条NOP指令 作用:对于延时很短的,要求在us级的,采用“_nop_”函数,这个函数相当汇编NOP 指令,延时几微秒。 NOP指令为单周期指令,可由晶振频率算出延时时间,对于12M晶振,延时1uS。 对于延时比较长的,要求在大于10us,采用C51中的循环语句来实现。 在选择C51中循环语句时,要注意以下几个问题 第一、定义的C51中循环变量,尽量采用无符号字符型变量。 第二、在FOR循环语句中,尽量采用变量减减来做循环。 第三、在do…while,while语句中,循环体内变量也采用减减方法。 这因为在C51编译器中,对不同的循环方法,采用不同的指令来完成的。 下面举例说明: unsigned char I; for(i=0;i<255;i++); unsigned char I; for(i=255;i>0;i--); 其中,第二个循环语句C51编译后,就用DJNZ指令来完成,相当于如下指令: MOV09H,#0FFH LOOP:DJNZ09H,LOOP 指令相当简洁,也很好计算精确的延时时间。 同样对do…while,while循环语句中,也是如此 例: unsigned char n; n=255; do{n--} while(n); 或 n=255; while(n) {n--}; 这两个循环语句经过C51编译之后,形成DJNZ来完成的方法,

相关主题
相关文档
最新文档