//----假设,系统工作于
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的子程序、知道单片机的晶振,怎么计算它延迟一秒的程序、单片机延时时间程序怎么编程等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)