通用办法,可以类推:
DELAY1s:MOV R5,#08H ; ∵ 1s=1000000us
MOV R6,#0A2H ; ∴ 1000000/2=500000
MOV R7,#20H ; 500000用16进制表示为: 07A120
; 所以 R5=07H+1=08H
; R6=0A1H+1=0A2H
; R7=20H
loop: DJNZ R7,$ ; 延时时间≈2×[(R5-1)×256+R6-1]×256+R7
DJNZ R6,loop ; 当R5、R6等于0,相当于256参与运算
DJNZ R5,loop ; 当R5、R6等于0,相当于256参与运算
RET
如果单纯延时,可以用实验的办法,在keilc51里面仿真
void Delay1S(char n)
{
char i,j;
n=n4;
for(;n;n--)
{
for(i=6;i;i++)
{
for(j=7;j;j++) // 一个循环约为1mS
;
}
}
}
看编译后的汇编:
C:0x0805 7D01 MOV R5,#0x06;j=1,1时钟
C:0x0807 0D INC R5;j++,1时钟
C:0x0808 ED MOV A,R5;A=R5,1时钟
C:0x0809 70FC JNZ C:0807;A=0,2时钟
循环共249次,一个循环共需4个时钟周期,加上第一个赋值语句1周期。
共997uS,加上外层循环,一次约1mS,
如果要精确的延时建议采用中断:
#include "reg51h"
//timer init
void initTimer(void)
{
TMOD=0x2;
TH0=0x6;
TL0=0x6;
}
int T250uS;
char T_mark;
//timer0/counter0 interrupt
void timer0(void) interrupt 1
{
//add your code here
T250uS++;
T_mark=0;
}
void Delay1S(char n)
{
for(;n;n--)
for(T250uS=0;T250uS<4000;)
{
T_mark=1;
while(T_mark);
}
}
//the main fun
void main(void)
{
initTimer();
TR0=1;
ET0=1;
EA=1;
while(1)
{
Delay1S(1);
}
}
如果FOSC=12MHZ单片机,那么一个机器周期为12/12M=1us
如果是汇编语言的话:
L1:MOV R7,#100
L2:MOV R6,#100
L3:MOV R5,#50
DJNZ R5,$;此句两个机器周期也就是2T
DJNZ R6,L3
DJNZ R7,L2
RET
2T50100100=1,000,000us(共一秒),这是粗略算法,有误差,但不是太大。
用定时器1的工作方式2实现延时1s 不好,方式2最大只能定时256us,中断太频繁了
主程序中:
uint a=0;
TMOD=0X20;
TH1=256-200;//定时200us
TL1=256-200;
ET1=1;
EA=1;
TR1=1;
中断程序里:
a++;
if(a ==5000)
{
a=0;
其它 *** 作
}
//----假设,系统工作于
12mhz/12t的传统51单片机下#include
<reg51h>
sbit
test
=
p1^0;
void
delay_50ms(unsigned
char
times)
{
while(times
--
)
{
th0
=
0x3c;
//----装入初值,定时器0定时50ms
tl0
=
0xb0;
tr0
=
1;
//-----启动定时器
while(!tf0);
//-----等等定时时间到达
tf0
=
0;
//-----清零定时到达标志
}
}
void
delay_1s(unsigned
char
times)
{
while(times
--
)
{
delay_50ms(20);
}
}
void
main(void)
{
tmod
=
0x01;
//----定时器0工作于方式1
while(1)
{
delay_1s(2);
test
=
~test;
}
}
void Delay1000ms() //@110592MHz
{
unsigned char i, j, k;
_nop_();
i = 8;
j = 1;
k = 243;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
//
void Delay1000ms() //@12000MHz
{
unsigned char i, j, k;
_nop_();
i = 8;
j = 154;
k = 122;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
//
建议你下载这个软件 stc89c51和at89c51内核都一样,这个软件可以计算延时还有各种例程
下面几个是单片机的延时程序(包括asm和C程序,都是我在学单片机的过程中用到的),在单片机延时程序中应考虑所使用的晶振的频率,在51系列的单片机中我们常用的是110592MHz和120000MHz的晶振,而在AVR单片机上常用的有8000MHz和4000MH的晶振所以在网上查找程序时如果涉及到精确延时则应该注意晶振的频率是多大。
软件延时:(asm)
晶振12MHZ,延时1秒
程序如下:
DELAY:MOV
72H,#100
LOOP3:MOV
71H,#100
LOOP1:MOV
70H,#47
LOOP0:DJNZ
70H,LOOP0
NOP
DJNZ
71H,LOOP1
MOV
70H,#46
LOOP2:DJNZ
70H,LOOP2
NOP
DJNZ
72H,LOOP3
MOV
70H,#48
LOOP4:DJNZ
70H,LOOP4
定时器延时:
晶振12MHZ,延时1s,定时器0工作方式为方式1
DELAY1:MOV
R7,#0AH
;;晶振12MHZ,延时05秒
AJMP
DELAY
DELAY2:MOV
R7,#14H
;;晶振12MHZ,延时1秒
DELAY:CLR
EX0
MOV
TMOD,#01H
;设置定时器的工作方式为方式1
MOV
TL0,#0B0H
;给定时器设置计数初始值
MOV
TH0,#3CH
SETB
TR0
;开启定时器
HERE:JBC
TF0,NEXT1
SJMP
HERE
NEXT1:MOV
TL0,#0B0H
MOV
TH0,#3CH
DJNZ
R7,HERE
CLR
TR0
;定时器要软件清零
SETB
EX0
RET
C语言延时程序:
10ms延时子程序(12MHZ)
void
delay10ms(void)
{
unsigned
char
i,j,k;
for(i=5;i>0;i--)
for(j=4;j>0;j--)
for(k=248;k>0;k--);
}
1s延时子程序(12MHZ)
void
delay1s(void)
{
unsigned
char
h,i,j,k;
for(h=5;h>0;h--)
for(i=4;i>0;i--)
for(j=116;j>0;j--)
for(k=214;k>0;k--);
}
200ms延时子程序(12MHZ)
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--);
}
500ms延时子程序程序:
(12MHZ)
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--);
}
下面是用了80000MHZ的晶振的几个延时程序(用定时0的工作模式1):
(1)延时09MS
void
delay_0_9ms(void)
{
TMOD=0x01;
/定时器0工作在模式1下(16位计数器)/
TH0=0xfd;
TL0=0xa8;
TR0=1;
/启动定时器/
while(TF0==0);
TR0=0;
}
(2)延时1MS
void
delay_1ms(void)
{
TMOD=0x01;
/定时器0工作在模式1下(16位计数器)/
TH0=0xfd;
TL0=0x65;
TR0=1;
/启动定时器/
while(TF0==0);
TR0=0;
}
(3)延时45ms
void
delay_4_5ms(void)
{
TMOD=0x01;
/定时器0工作在模式1下(16位计数器)/
TH0=0xf4;
TL0=0x48;
TR0=1;
/启动定时器/
while(TF0==0);
TR0=0;
}
单片机延时一秒
程序是不固定的
要根据你的晶振 计算出一次循环执行需要的时间
然后 写循环次数
一般是
void delay_one_second(void){
int i;
for(i = 0; i < TIMES; i++);
}
这样就可以了。 TIMES是要计算的。或者 根据示波器 自己尝试。
以上就是关于单片机编写一个能延时1秒的子程序全部的内容,包括:单片机编写一个能延时1秒的子程序、51单片机用汇编语言设计1S延时子程序,晶振为12MHz。 (麻烦附上详细计算过程以及详细说明,、哪位单片机高手详细的告诉我一下:单片机中的延时程序的延时时间怎样计算的比如,延迟 1S,2S等等等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)