设单片机晶振频率为12MHZ,试编写一延时1s的子程序

设单片机晶振频率为12MHZ,试编写一延时1s的子程序,第1张

//----假设,系统工作于

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;

}

}

晶振频率分之1,就是时钟周期时间。一个_nop_();相当于1us;51单片机中一个机器周期等于12个时钟周期。延迟1秒就是1000000个_nop_。

void

Delay1000ms()

//@110592MHz

{

unsigned

char

i,

j,

k;

_nop_();

i

=

8;

j

=

1;

k

=

243;

do

{

do

{

while

(--k);

}

while

(--j);

}

while

(--i);

}

举一个例子来说明吧比如你要编一个延时50毫秒的子程序,那么步骤如下:

1、查看一下你的硬件环境,比如晶振大小,CPU型号,不用CPU指令的机器周期是不一样的。

2、计算延时需要的机器周期。比如采用12M晶振,CPU采用通用8051,那么一个机器周期为1US,50毫秒为501000=50000US,需要的机器周期=50000/1=50000。

3、试编程,如下:

程序代码 指令时间 总共时间

DELAY50MS: ;2 2

MOV R7,#A ;1 1

DELAY1:

MOV R6,#B ;1 1A

DJNZ R6,$ ;2 2BA

DJNZ R7,DELAY1 ;2 2A

RET ;2 2

所以总时间=2+1+A+2AB+2A+2=5+3A+2AB

4、凑数求A、B

根据2、3得到如下式子:

50000=5+3A+2AB

可以有很多种结果,不过最好是以A尽可能小,B尽可能大为原则,当然不能大于255

我现在凑出A=110,B=225;那么总延时时间=5+3110+2110225=49835。还差165US

5、补齐不够时间

再加一个小循环就OK了,呵呵如下:

MOV R6,#C

DJNZ R6,$

会算了吧,2C+1=165;所以C=82。

现在完整的延时程序出来了,如下:

DELAY50MS: ;2 2

MOV R7,#110 ;1 1

DELAY1:

MOV R6,#225 ;1 1110

DJNZ R6,$ ;2 2225110

DJNZ R7,DELAY1 ;2 2110

MOV R6,#82 ;1 1

DJNZ R6,$ ;2 282

RET ;2 2

很圆满:总的时间50000微妙,也就是50毫秒。这种方式编程,在该硬件环境下可以保证最大误差为1微妙。

不管晶振频率是多少,一次就延时一秒是不可能的。

当晶振频率是12 M时,最大的延时是65536毫秒。通常可以设置定时50毫秒,并设置为中断方式,这样,每次当定时到就中断一次,再对中断计数,中断计数20次就是一秒了。

一般单片机在c语言中很难得到精确的延时,所以一般对时间要求高的都用计时器中断来做了。如果时间要求不严格可以用for循环来做,你可以实际测试一下,把时间延时到大概一秒左右,然后烧进单片机里运行,比如一个灯亮灯灭的程序,看着灯计数,同时用秒表计时,几个几十次后取平均值就能知道大概时间了。

我再帮你补一课,看了你的标题,我写了一个用定时器0来控制一个LED灯第隔1秒钟亮灭一次的程序,希望对你有用,另外我也写了一个你说的那个程序,一起发上来吧

这个是用定时器0控制一个灯的亮和灭

#include<reg52h>

#define uchar unsigned char

#define uint unsigned int

//

uchar num;

bit tt;

sbit d=P1^0;

/主程序入口/

void main()

{

TMOD=0x01;

TH0=(65535-50000)/256;

TL0=(65535-50000)%256;

TCON=0x10;

EA=1;

ET0=1;

tt=255;

while(1)

{

if(num==20)

{

tt=!tt;

d=tt;

num=0;

}

}

}

void timer() interrupt 1

{

TH0=(65535-50000)/256;

TL0=(65535-50000)%256;

num++;

}

这个程序是逐个点亮的(思路:由256逐减1,值由LED灯显示)

#include<reg52h>

#define uchar unsigned char

#define uint unsigned int

//

uchar num,tt;

//bit tt;

sbit d=P1^0;

/主程序入口/

void main()

{

TMOD=0x01;

TH0=(65535-50000)/256;

TL0=(65535-50000)%256;

TCON=0x10;

EA=1;

ET0=1;

tt=255;

while(1)

{

if(num==20)

{

tt--;

P1=tt;

num=0;

}

}

}

void timer() interrupt 1

{

TH0=(65535-50000)/256;

TL0=(65535-50000)%256;

num++;

}

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内核都一样,这个软件可以计算延时还有各种例程

以上就是关于设单片机晶振频率为12MHZ,试编写一延时1s的子程序全部的内容,包括:设单片机晶振频率为12MHZ,试编写一延时1s的子程序、知道单片机的晶振,怎么计算它延迟一秒的程序、单片机延时时间程序怎么编程等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9613204.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-30
下一篇 2023-04-30

发表评论

登录后才能评论

评论列表(0条)

保存