51单片机延时函数的问题。晶振是12MHz..需要延时1秒
机器周期为1um.而1秒=10^6um。但是为什么感觉设计出来的程序延迟是10秒的呢delay(){inti,s;for(i=1000;i>0;i--){for(s=10...
机器周期为1um.而1秒=10^6um。但是为什么感觉设计出来的程序延迟是10秒的呢
delay()
{
int i,s;
for(i=1000;i>0;i--)
{
for(s=1000;s>0;s--)
{
_nop_();
}
}
} 展开
delay()
{
int i,s;
for(i=1000;i>0;i--)
{
for(s=1000;s>0;s--)
{
_nop_();
}
}
} 展开
5个回答
展开全部
很简单, for循环也是需要时间的.
当你使用仿真的时候,通常可以在编译器里面查看这段代码的汇编指令.
你可以看书它的用到了多少个汇编指令, 然后在你的芯片手册上查询,每一个汇编指令执行需要多少个最小指令周期. 最小指令周期才是你说的1um, 全部加起来, 你就知道你这句话用掉了多少个最小指令.
很明显 远远超过了1个最小指令.9秒的的误差算少的了...
所以说,假如你要做1s的延迟, 最好使用内部时钟中断来做,直接在程序内部delay延时的话,占用系统资源还算不准...
具体解释下上图, 为了拿这5分还真不容易...
首先, 进入函数就需要5个汇编指令, 这些指令主要是入栈,备份指针的操作, 不同的编译器指令不同,但都差不多.... 当然 这5个指令是进入函数只跑一次, 占用时间不多, 消耗时间最多的是你for循环内部的指令, 一个for循环需要8条汇编指令才能实现, 而每个汇编指令通常都需要消耗1-2个最小指令循环,具体那个指令消耗几个循环我懒的查手册, 不同的芯片不一样, 你自己看看你用的芯片手册把....
以上... 应该清楚了把.. 不明白追问, 我要是再次无聊的话, 会修改回答.
展开全部
6: delay()
7: {
8: int i,s;
9: for(i=1000;i>0;i--)
C:0x002D 7FE8 MOV R7,#0xE8
C:0x002F 7E03 MOV R6,#0x03
10: {
11: for(s=1000;s>0;s--)
C:0x0031 7DE8 MOV R5,#0xE8
C:0x0033 7C03 MOV R4,#0x03
12: {
13: _nop_();
C:0x0035 00 NOP
14: }
C:0x0036 ED MOV A,R5
C:0x0037 1D DEC R5
C:0x0038 7001 JNZ C:003B
C:0x003A 1C DEC R4
C:0x003B ED MOV A,R5
C:0x003C 4C ORL A,R4
C:0x003D 70F6 JNZ C:0035
15: }
C:0x003F EF MOV A,R7
C:0x0040 1F DEC R7
C:0x0041 7001 JNZ C:0044
C:0x0043 1E DEC R6
C:0x0044 EF MOV A,R7
C:0x0045 4E ORL A,R6
C:0x0046 70E9 JNZ C:0031
16: }
C:0x0048 22 RET
这是反汇编出来的程序,和想象的不一样吧;c语言和汇编大概是4:1的密度。
7: {
8: int i,s;
9: for(i=1000;i>0;i--)
C:0x002D 7FE8 MOV R7,#0xE8
C:0x002F 7E03 MOV R6,#0x03
10: {
11: for(s=1000;s>0;s--)
C:0x0031 7DE8 MOV R5,#0xE8
C:0x0033 7C03 MOV R4,#0x03
12: {
13: _nop_();
C:0x0035 00 NOP
14: }
C:0x0036 ED MOV A,R5
C:0x0037 1D DEC R5
C:0x0038 7001 JNZ C:003B
C:0x003A 1C DEC R4
C:0x003B ED MOV A,R5
C:0x003C 4C ORL A,R4
C:0x003D 70F6 JNZ C:0035
15: }
C:0x003F EF MOV A,R7
C:0x0040 1F DEC R7
C:0x0041 7001 JNZ C:0044
C:0x0043 1E DEC R6
C:0x0044 EF MOV A,R7
C:0x0045 4E ORL A,R6
C:0x0046 70E9 JNZ C:0031
16: }
C:0x0048 22 RET
这是反汇编出来的程序,和想象的不一样吧;c语言和汇编大概是4:1的密度。
追问
sorry啊。。。我还没学汇编。。。直接学的C51.。。。
追答
还是看看汇编吧。不学汇编就别想学好的单片机
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
6:
delay()
7:
{
8:
int
i,s;
9:
for(i=1000;i>0;i--)
C:0x002D
7FE8
MOV
R7,#0xE8
C:0x002F
7E03
MOV
R6,#0x03
10:
{
11:
for(s=1000;s>0;s--)
C:0x0031
7DE8
MOV
R5,#0xE8
C:0x0033
7C03
MOV
R4,#0x03
12:
{
13:
_nop_();
C:0x0035
00
NOP
14:
}
C:0x0036
ED
MOV
A,R5
C:0x0037
1D
DEC
R5
C:0x0038
7001
JNZ
C:003B
C:0x003A
1C
DEC
R4
C:0x003B
ED
MOV
A,R5
C:0x003C
4C
ORL
A,R4
C:0x003D
70F6
JNZ
C:0035
15:
}
C:0x003F
EF
MOV
A,R7
C:0x0040
1F
DEC
R7
C:0x0041
7001
JNZ
C:0044
C:0x0043
1E
DEC
R6
C:0x0044
EF
MOV
A,R7
C:0x0045
4E
ORL
A,R6
C:0x0046
70E9
JNZ
C:0031
16:
}
C:0x0048
22
RET
这是反汇编出来的程序,和想象的不一样吧;c语言和汇编大概是4:1的密度。
delay()
7:
{
8:
int
i,s;
9:
for(i=1000;i>0;i--)
C:0x002D
7FE8
MOV
R7,#0xE8
C:0x002F
7E03
MOV
R6,#0x03
10:
{
11:
for(s=1000;s>0;s--)
C:0x0031
7DE8
MOV
R5,#0xE8
C:0x0033
7C03
MOV
R4,#0x03
12:
{
13:
_nop_();
C:0x0035
00
NOP
14:
}
C:0x0036
ED
MOV
A,R5
C:0x0037
1D
DEC
R5
C:0x0038
7001
JNZ
C:003B
C:0x003A
1C
DEC
R4
C:0x003B
ED
MOV
A,R5
C:0x003C
4C
ORL
A,R4
C:0x003D
70F6
JNZ
C:0035
15:
}
C:0x003F
EF
MOV
A,R7
C:0x0040
1F
DEC
R7
C:0x0041
7001
JNZ
C:0044
C:0x0043
1E
DEC
R6
C:0x0044
EF
MOV
A,R7
C:0x0045
4E
ORL
A,R6
C:0x0046
70E9
JNZ
C:0031
16:
}
C:0x0048
22
RET
这是反汇编出来的程序,和想象的不一样吧;c语言和汇编大概是4:1的密度。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
/*---------------------------------
|函数名称:毫秒级延时函数。
|说 明:晶振12Mhz
|延时时间:1.01Ms
|调试说明:对于j我原定义成char型,怎么调试结果都不对,仿真发现只能延时30几US。
| 改成int型OK。
-----------------------------------*/
void Delay_Xms(unsigned int Time)
{
unsigned int i = 0;
unsigned int j = 0;
for (i = Time;i > 0;i--)
{
for (j = 123;j > 0;j--);
}
}
|函数名称:毫秒级延时函数。
|说 明:晶振12Mhz
|延时时间:1.01Ms
|调试说明:对于j我原定义成char型,怎么调试结果都不对,仿真发现只能延时30几US。
| 改成int型OK。
-----------------------------------*/
void Delay_Xms(unsigned int Time)
{
unsigned int i = 0;
unsigned int j = 0;
for (i = Time;i > 0;i--)
{
for (j = 123;j > 0;j--);
}
}
追问
我的是int 啊。。。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
for(s=1000;s>0;s--)这句也占时间的,
追问
可是误差不会多出9秒啊。
追答
void delay_main(uint z)//-----------------主延时函数1毫秒
{
uint x,y;
for(x=z;x>0;x--)
for(y=100;y>0;y--);
}
void delay_main(1000)即为1秒,
建议可以用t0计时器中断来检句测每条语句时间,最好在PROTEUS上仿真看看
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询