找回密码
 立即注册
查看: 41|回复: 7

关于STC-ISP软件延时计算器生成代码的疑问

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:16
  • 最近打卡:2025-09-17 07:33:15
已绑定手机

3

主题

3

回帖

89

积分

注册会员

积分
89
发表于 前天 20:44 | 显示全部楼层 |阅读模式
按照89c52按12T来计算,以50μs为例,STC-ISP生成的ASM代码如下:
DELAY50US:            ;@12.000MHz
    NOP
    NOP
    NOP
    NOP
    PUSH    30H
    MOV        30H,#116
NEXT:
    DJNZ    30H,NEXT
    POP        30H
    RET

屏幕截图 2025-09-15 204033.png

问题是,DJNZ是双字节指令,一条指令执行的时间是2μs,运行116次,执行时间最少是232μs了,还不计算前面的NOP指令和程序跳转时间,这个延时时间比50μs大多了。请教一下大家这么理解对不对呢?

回复

使用道具 举报 送花

3

主题

1975

回帖

798

积分

等待验证会员

积分
798
发表于 前天 20:48 | 显示全部楼层
关于STC-ISP软件中延时计算器生成的代码问题,您的观察非常细致,也确实指出了一个常见的误区。我们来逐步分析这段延时子程序的执行过程,并解释为何实际延时时间与预期存在差异。

首先,我们明确几个基本前提:

1. 系统时钟频率:您提到是12000kHz(即12MHz)。
2. 单片机类型:89C52,属于标准51内核,且为12T模式(即一个机器周期为1μs)。
3. 延时目标:50μs。

一、标准51单片机指令周期说明

在12T模式下,一个机器周期为1μs。大多数单字节指令执行时间为1个机器周期(即1μs),双字节或条件跳转指令(如DJNZ)则通常为2个机器周期(即2μs)。

二、分析STC-ISP生成的延时代码

以下是您提供的代码:
  1. asm
  2. DELAY50US:            ;@12000MHz
  3.     NOP
  4.     NOP
  5.     NOP
  6.     NOP
  7.     PUSH    30H
  8.     MOV     30H,#116
  9. NEXT:
  10.     DJNZ    30H,NEXT
  11.     POP     30H
  12.     RET
复制代码

我们逐条分析其执行时间(单位:μs):

| 指令                | 字节数 | 机器周期数 | 时间(μs) |
|---------------------|--------|-------------|-----------|
| NOP                 | 1      | 1           | 1         |
| NOP                 | 1      | 1           | 1         |
| NOP                 | 1      | 1           | 1         |
| NOP                 | 1      | 1           | 1         |
| PUSH 30H            | 1      | 2           | 2         |
| MOV 30H,#116        | 2      | 1           | 1         |
| DJNZ 30H,NEXT       | 2      | 2           | 循环执行 |
| POP 30H             | 1      | 2           | 2         |
| RET                 | 1      | 2           | 2         |

三、关键部分:DJNZ循环时间估算

DJNZ指令在循环中被执行,初始值为116次。每次DJNZ执行时间为2μs。

但需要注意:第一次DJNZ执行时,寄存器值为116,减1后不为0,继续循环;直到第116次减为0时,才跳出循环。

因此,DJNZ共执行116次,总时间为:
  1. 116 × 2μs = 232μs
复制代码

加上前面的NOP、PUSH、MOV等指令,以及最后的POP和RET:
  1. NOP ×4 = 4μs  
  2. PUSH = 2μs  
  3. MOV = 1μs  
  4. POP = 2μs  
  5. RET = 2μs  
  6. 总计 = 4 + 2 + 1 + 2 + 2 = 11μs
复制代码

因此,整个延时函数的总时间约为:
  1. 232μs(循环) + 11μs(其他指令) = 243μs
复制代码

远远超过了预期的50μs!

四、结论与解释

您指出的问题是完全正确的。STC-ISP软件生成的延时代码在本例中确实存在严重误差,生成的延时远远超过设定值。这说明:

1. STC-ISP的延时计算器可能基于某种简化的模型或经验公式,在某些情况下并不准确。
2. 该延时代码适用于更慢的主频(如6MHz)或不同的T模式(如6T模式),但在12MHz 12T模式下明显不适用。
3. 延时子程序的编写必须考虑指令周期和循环次数的精确匹配,否则会产生显著误差。

五、正确延时代码的编写建议

要实现50μs的延时,在12MHz、12T模式下,每个机器周期为1μs。我们可以通过简单的循环结构实现:
  1. asm
  2. DELAY50US:
  3.     MOV     R0,#50
  4. DELAYLOOP:
  5.     DJNZ    R0,DELAYLOOP
  6.     RET
复制代码

该段代码中:
MOV R0,#50:1μs
DJNZ R0,DELAYLOOP:循环执行50次,每次2μs → 100μs
RET:2μs

总时间约为:1 + 100 + 2 = 103μs

仍略大于50μs,因为DJNZ本身为2μs。若要更精确:

可以使用嵌套循环或更小的循环次数,结合NOP微调:
  1. asm
  2. DELAY50US:
  3.     MOV     R0,#25
  4. DELAYLOOP:
  5.     DJNZ    R0,DELAYLOOP
  6.     RET
复制代码

执行时间约为:1 + 25×2 + 2 = 53μs

再通过减少NOP或调整R0初值,可进一步逼近目标。

六、总结
STC-ISP生成的延时代码在某些配置下可能不准确,需结合主频、T模式进行验证。
延时子程序的编写应基于精确的指令周期计算,尤其是DJNZ等双周期指令。
实际延时时间应通过仿真或示波器测量验证,确保满足设计要求。

如需更精确的延时控制,建议使用定时器中断方式实现,可避免因指令周期误差带来的问题。

希望以上分析能帮助您更好地理解该问题的本质。如有更多关于单片机或延时技术的疑问,欢迎继续交流。

[本文内容由国芯人工智能辅助生成,仅供参考]
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:560
  • 最近打卡:2025-09-17 00:02:42
已绑定手机

19

主题

3264

回帖

5912

积分

论坛元老

积分
5912
发表于 前天 23:13 | 显示全部楼层
这个才是89C52的50uS
截图202509152312282902.jpg
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:560
  • 最近打卡:2025-09-16 05:09:25
已绑定手机

86

主题

6122

回帖

1万

积分

超级版主

积分
11330
发表于 昨天 05:10 | 显示全部楼层
8051指令集选择不正确,89c52选择stc89
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:16
  • 最近打卡:2025-09-17 07:33:15
已绑定手机

3

主题

3

回帖

89

积分

注册会员

积分
89
发表于 昨天 08:37 | 显示全部楼层
so*** 发表于 2025-9-15 23:13
这个才是89C52的50uS

原来没选对指令集。谢谢解答。
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:523
  • 最近打卡:2025-09-16 10:02:31

33

主题

2550

回帖

5557

积分

论坛元老

积分
5557
发表于 昨天 10:10 | 显示全部楼层
你想要89C52的延时函数为何选择STC15指令集呢
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:523
  • 最近打卡:2025-09-16 10:02:31

33

主题

2550

回帖

5557

积分

论坛元老

积分
5557
发表于 昨天 10:11 | 显示全部楼层
kpf*** 发表于 2025-9-16 08:37
原来没选对指令集。谢谢解答。

那没事了
参考例程并不是对技术参 考手册的补充,而是对技术参 考手册的解释。
技术参 考手册不应该需要参考例程作为补充,而是解释成了参考例程的样子
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:16
  • 最近打卡:2025-09-17 07:33:15
已绑定手机

3

主题

3

回帖

89

积分

注册会员

积分
89
发表于 昨天 16:56 | 显示全部楼层
Debu*** 发表于 2025-9-16 05:10
8051指令集选择不正确,89c52选择stc89

我以为在ISP程序里面选好MCU型号了就行了,没仔细看还要选择指令集。建议ISP程序优化一下,延时程序的指令集能根据选定的MCU型号自动配置。
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-9-17 09:29 , Processed in 0.140968 second(s), 99 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表