举一个例子来说明吧.比如你要编一个延时50毫秒的子程序,那么步骤如下:
1、查看一下你的硬件环境,比如晶振大小,CPU型号,不用CPU指令的机器周期是不一样的。
2、计算延时需要的机器周期。比如采用12M晶振,CPU采用通用8051,那么一个机器周期为1US,50毫秒为50*1000=50000US,需要的机器周期=50000/1=50000。
3、试编程,如下:
程序代码 指令时间 总共时间
DELAY50MS: ;2 2
MOV R7,#A ;1 1
DELAY1:
MOV R6,#B ;1 1*A
DJNZ R6,$ ;2 2*B*A
DJNZ R7,DELAY1 ;2 2*A
RET ;2 2
所以总时间=2+1+A+2*A*B+2*A+2=5+3A+2AB
4、凑数求A、B
根据2、3得到如下式子:
50000=5+3A+2AB
可以有很多种结果,不过最好是以A尽可能小,B尽可能大为原则,当然不能大于255.
我现在凑出A=110,B=225;那么总延时时间=5+3*110+2*110*225=49835。还差165US
5、补齐不够时间
再加一个小循环就OK了,呵呵如下:
MOV R6,#C
DJNZ R6,$
会算了吧,2*C+1=165;所以C=82。
现在完整的延时程序出来了,如下:
DELAY50MS: ;2 2
MOV R7,#110 ;1 1
DELAY1:
MOV R6,#225 ;1 1*110
DJNZ R6,$ ;2 2*225*110
DJNZ R7,DELAY1 ;2 2*110
MOV R6,#82 ;1 1
DJNZ R6,$ ;2 2*82
RET ;2 2
很圆满:总的时间50000微妙,也就是50毫秒。这种方式编程,在该硬件环境下可以保证最大误差为1微妙。
‘贰’ 51单片机C语言程序中延时函数delay的原理是什么
原理:只是执行一些所谓的“无实际意义的指令”,如缩放或执行一个int自加,简单地说,就像高中数学中的“乘法原理”一样,很容易迅速增加上面提到的“无意义指令”的数量
关于大小的值:如果是在C语言中,该值不仅与水晶振动、单片机本身的速度,但也与C的编译器,所以,虽然这个值可以精确计算,但大多数情况下,程序员是经验值。
当然,如果你在汇编中编程,情况就不同了,因为每条指令使用一定数量的机器周期,你当然可以根据所有指令使用的总时间来计算特定延迟的总时间。
(2)单片机延时程序扩展阅读:
定义延迟XMS毫秒的延迟函数
Voiddelay(unsignedintXMS)//XMS表示需要延迟的毫秒数
{
无符号intx,y;
For(x=XMS;X0;X-)
For(y=110;Y”0;Y-);
}
使用:
VoidDelay10us(ucharMs)
{
Uchar数据我;
(;女士“0;------Ms)
对于(I = 26)我> 0;我-);
}
I=[(延迟值-1.75)*12/ms-15]/4
‘叁’ 编写一个延时10秒的程序单片机
如果是精确的话,需要用定时器,不是太精确的话,软件延时就可以。
假如12M晶振
void delay10s()
{
int i,j;
for(i=0;i<10000;i++)
for(j=0;j<120;j++);
}
void delay10s()
{
unsigned char i;
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TR0=1;
i=200;
while(i--)
{
while(TF0==0);
TF0=0;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
}
}
‘肆’ C51单片机延时程序,需要不精确延时2小时,请问大神怎么写延时代码,谢谢!
可以有很多办法,一是调整参数,使其延时5分钟或6分钟,循环24次或20次。二是将延时函数的形参改为长整型(32位)延时时间扩大65536倍。三是使用定时器,每次定时50mS,累计144000次,便是2小时,使用定时器(中断)的好处是在延时期间还可以干许多事情,例如显示剩余时间,检测设备工作状态或者调整延时时间等,而你的纯软件延时期间想干其它事情比较困难。
‘伍’ 51单片机中延时程序
1. sleep()是以毫秒计算的,延时5秒是sleep(5*1000);,延时5分是sleep(5*1000*60);
2.包含的头文件看你用的什么编辑软件。
3.我用的VC++是用包含在#include<windows.h>头文件中。
#include<stdio.h>#include<windows.h>//Sleep()的头文件 main() { int i;
int n=10;for(i=1;i<=n;i++) {printf("%d",i);Sleep(5*1000*60);} //
这里修改延时时间,
有些人说是用#include<dos.h>做头文件你自己试下吧。
还用Sleep的S是大写的,不是小写的。
‘陆’ 单片机5段延时程序
ORG
0000H
CONT:
MOV
R2,#04H
MOV
A,
#0FEH
NEXT:
MOV
P1,
A
ACALL
DELAY
RL
A
DJNZ
R2,
NEXT
MOV
R2,
#04H
NEXT1:
MOV
P1,
A
RR
A
ACALL
DELAY
DJNZ
R2,
NEXT1
SJMP
CONT
DELAY:
MOV
R3,
#14H
MOV
TMOD,
#10H
MOV
TH1,
#3CH
MOV
TL1,
#0B0H
SETB
TR1
LP1:
JBC
TF1,LP2
SJMP
LP1
LP2:
MOV
TH1,
#3CH
MOV
TL1,
#0B0H
DJNZ
R3,
LP1
RET
END
;很简单的,你的程式把0和O搞错了,然后修改一下R2就可以了,此程式我已经运行过。
‘柒’ 单片机延时程序C语言
都有关系,用uchar也能起作用,但是不明显,你就觉得有问题,原因应该是这样的,char型是8位的,就算是无符号的字符型,最大也是255,也就是说你给的值再大就会溢出,没什么用了,比如你给一个256,溢出了,这时候Z的值应该是0,但是这个程序是没错的,你给0和255延时还是不同的,,当然你现在应该明白为什么整型就可以了,因为无符号的int是32位的,而这个数最大值到底有多大,你自己算一下,所以你给的数基本不会溢出,延时明显,字符型主要是用来写字符的,算数的话你还是别用这个类型,各有各的用途
‘捌’ 关于单片机延时程序
void timer0_zd() interrupt 1 //定时器0,定时中断子程序
{
TL0 = 0x00; // 设置定时器初值
TH0 = 0x4C; // 设置定时器初值
a++; //开关按下延时,延时到之后,电磁阀开始动作。
if(a==20) //延时20*50毫秒 = 1秒
{
flag0=1;
}
}
很明显进入中断,a == 20的时候flag0标志置位,aut1 = 0;如果你a不清零的话,a++一直加加到溢出,所以出错,如果你清零了,中断进入一次a+1 到20请aut1就会一直输出
‘玖’ 帮忙写个简单的51单片机延时程序
用定时器做延时比较好实现。
#include<reg51.h>
#defineucharunsignedchar
sbitk=P1^0;
sbitled=P1^1;
ucharcnt,sec;
voidt0isr()interrupt1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
cnt++;
if(cnt>=20)
{
cnt=0;
sec++;
}
}
voidmain()
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TR0=1;
ET0=1;
EA=1;
while(1)
{
if(k==0)
{
cnt=0;
sec=0;
while(k==0)
{
if(sec>=3&&sec<=8)led=0;
elseled=1;
}
}
led=1;
}
}
‘拾’ 单片机延时程序
2*2*(0x7d)*10*100=500000 算的方法很多,但是相差都不大 这是我的算法。。。
如果你的晶振是12M的 那么就大概是0.5秒 如是6M的就是1秒啦
DL1:MOV R2.#10 想是3秒把10改为60 ............30