单片机的晶振是最原始的频率发生器,一个单片机的晶振频率是这个单片机系统里的最大频率,他的工作频率 输出频率都是以这个晶振频率为基准的,。通过倍频器、分频器分成不同的频率使用。至于你说的延时函数的话,这个要查他执行一个指令的指令周期是多少,延时函数最好用汇编编程,然后看他执行几个指令周期,这样就能精确地做延时函数了。
应该是 12MHz 吧?
单片机内部,计时的单位是《机器周期T》。
下面是每条指令执行时,所用的周期数:
MOV R1,#60 1T
F: MOV R3,#248 1T
DJNZ R3,$ 2T
DJNZ R1,F 2T
RET 2T
下面是程序循环时所用的周期数:
MOV R1,#60
F: MOV R3,#248
DJNZ R3,$ 2 248 = 496 T
DJNZ R1,F (2 + 496 + 1) 60 = 29940T
RET 2 + 29940 + 1 = 29943T
总共是: 29943T。
如果是 12MHz,时间就是:29943us。
另外,执行这个程序,还需要一条 CALL 指令,应该再加上 2T。
--怎么样实现5S的延时?
慢慢算呗。
12M晶振,1个机器周期为1us,
把它转成汇编:
LCALL DELAY
DELAY:
MOV R7,#01H
DJNZ R7,$
RET
貌似调用、赋值、减1比较、返回,这几个环节下来是得6个机器周期。
但是在t=2的时候并不是12us,应该为8us左右,因为其它环节没变,只是增加了减1比较这个环节。
用c的:
void delay(void)
{
unsigned char a,b;
for(b=80;b>0;b--)
for(a=10;a>0;a--);
}
用asm的:
DELAY:
MOV R6,#50H
DL0:
MOV R5,#0AH
DJNZ R5,$
DJNZ R6,DL0
RET
这个误差是01us,还不够精确,那就没有办法了!
221184mhz晶振用定时器误差也是01us
我的是keil软件延时
程序是
#include <reg51h>
void delay(unsigned int temp)//延时程序
{
while(--temp);
}
void main()
{
while(1)
{ P11=0;
delay();
P11=1;
}
}
/
此延时函数针对的是221148Mhz的晶振
delay(1):延时759us
delay(10):延时4666us
delay(20):延时9007us
delay(100):延时43735us
delay(200):延时87145us
/
上面是我软件的延时,你最好下载到硬件里试试,用示波器观察p11口输出的方波脉宽长度,就知道你的硬件的实际延时时间了。
你是用的uvision吧?我用的uvision4,把程序编好运行,然后进行调试(在此要设置两个断点就是一个在Delay延时函数之前,一个断点设在延时之后),然后你会在左边register栏会看见一个 sec:000014182 这个就是软件运行到断点处所用时间,然后再运行一次(这次就是运行完延时函数所用时间)。你把两次的时间做差值就是延时函数延时时间。再附图两张。
while(1) {
for(i = 400; i > 0; i--) {//500HZ 这个是怎么计算出来的
fmq = !fmq; delay(7);
}
for(i = 400; i > 0; i--) {//1000HZ 还有这个是怎么计算出来的。
fmq = !fmq; delay(10);
}
}
//----------------------
这两个频率数字,是不可能算出来的。
因为,这两个频率数字,明显是错误的。
看看前面的,延时参数是7,后面的,延时参数是10。
很明显,前面的,延时时间短,频率,就应该高于后面的。
但是,前面写的是 500Hz,低于后面 1000Hz。
这样的结果,绝对是算不出来的。
这两个数字,不知道是谁瞎写的,不用理他。
想要计算程序的执行时间,去学汇编语言,才行。
参考:
http://zhidaobaiducom/question/1859740151316185787html
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)