找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

stc8h单片机的延时为什么不准?

查看数: 1342 | 评论数: 18 | 收藏 0
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2025-4-21 17:39

正文摘要:

使用的是stc8h8k64u单片机,需要延时3秒,代码由stc-isp生成,延时程序名Delay3000ms(), 在keil调试,显示的却是54秒,(见图)。 程序下载运行,实测是4.5秒,相差太大了。 为什么keil调试显示是54?我 ...

回复

ID:595237 发表于 2025-4-25 12:02
晶振11.0592MHz请参考,自己调试一下

#include <intrins.h>

void Delay3000ms() {
    unsigned int i, j;
   
    for (i = 0; i < 628; i++) {       // 外层循环628次
        for (j = 0; j < 0x2A4; j++) { // 内层循环0x2A4(十进制676)次
            _nop_();                  // 每个空指令占用1个时钟周期
        }
    }
}




// 或使用更精确的定时器方法(推荐)
void Delay3000ms() {
    TMOD &= 0xF0;    // 设置定时器模式:T1为16位定时器模式
    TMOD |= 0x10;
    TH1 = 0xDC;      // 初始化定时值(11.0592MHz下,定时50ms)
    TL1 = 0x00;
   
    ET1 = 0;         // 禁用定时器中断
    TR1 = 1;         // 启动定时器
   
    for (unsigned int count = 0; count < 60; count++) { // 60*50ms=3000ms
        while (!TF1);  // 等待定时器溢出
        TF1 = 0;       // 清除溢出标志
        TH1 = 0xDC;    // 重载初值
        TL1 = 0x00;
    }
   
    TR1 = 0;         // 停止定时器
}

晶振12MHz

void Delay3000ms() //@12.000MHz
{
    unsigned char i, j, k;
   
    i = 224;
    do {
        j = 200;
        do {
            k = 200;
            do {
                // 空循环,由k--操作实现
            } while (--k);
        } while (--j);
    } while (--i);
}
ID:108361 发表于 2025-4-25 10:07
ziyueboy 发表于 2025-4-24 22:35
程序中不要用delay1ms(XXX),初始化可以用倒无所谓!要么定时器开滴答做系统时间分片基准,要么定时器中做 ...

还在用89C52芯片的人,还谈啥非阻塞啊,RTOS啊
ID:292876 发表于 2025-4-24 22:35
程序中不要用delay1ms(XXX),初始化可以用倒无所谓!要么定时器开滴答做系统时间分片基准,要么定时器中做个时间基准。多任务分时执行时候,或RTOS时候,用delay1ms(XXX)都会出很多莫名其妙的问题,特别模拟SPI,I2C等通讯,要做好delay1ms(XXX)规划,能用硬SPI,I2C等外设,最好不要用模拟,出问题不好找出问题点啦!除非你能把握每一处细节,做到入微,那么用倒无所谓。目前MCU项目都做多任务的,delay1ms(XXX)能不用尽量别用,养好习惯
ID:1042619 发表于 2025-4-24 14:20
89系列太古老了,建议直接用Ai8051U,USB 型 1T 8051,支持32位和8位指令集, RMB2.3,支持硬件USB下载 硬件USB仿真
管脚兼容天王级别的:  89C52RC,  12C5A60S2
要兼容 8位8051指令集,  可以用 Keil C51/IAR/SDCC 编译器
===就相当于更强大的 8H8K64U
要兼容 32位8051指令集,可以用 Keil C251 编译器,双核兼容设计
===就相当于更强大的 32G12K128, 32G8K64
34K SRAM(2K edata, 32K xdata), 64K Flash
TFPU@120MHz, 硬件浮点/硬件三角函数 运算器
DMA支持PWM, DMA支持外设直接到外设, P2P
120MHz-PWM支持硬件移相,16位PWM; 真12位ADC
USB, 4组串口,12位ADC, 轨到轨比较器
QSPI, SPI, I2S, I2C,  TFT-i8080/M6800 接口
PDIP40,LQFP44,LQFP44




ID:1042619 发表于 2025-4-24 14:17
必须直接设置3000ms,不能1ms 3000次,否则会累积3000个误差


8b0381a8b59509b5b4f04d4351c8576.jpg (62.39 KB, 下载次数: 0)

8b0381a8b59509b5b4f04d4351c8576.jpg
ID:134430 发表于 2025-4-23 17:43
谢谢大家!继续学习。
ID:1057978 发表于 2025-4-23 10:01
你还是用stc89吧,老老实实呆在舒适区,8h太新了,不适合你
ID:401564 发表于 2025-4-23 09:19
wh8010jky 发表于 2025-4-22 17:04
首先感谢大家的回复指点!

我又进行了测试,情况如下:

为什么对仿真这么执着呢?
程序最终是要用来运行的,不是用来仿真的
设置一个u8全局变量,开启一个定时器中断,在中断对这个变量进行++运算,然后在所有函数中都可以通过读取这个变量来进行延时之类的时间操作
不推荐用上古时期的8051了,功能少,烧录不方便,片上资源少,运行速度慢,价格又高,资料也少,出了问题找不到相关资料,这都完美的避开了STC的所有优点
ID:1034262 发表于 2025-4-22 21:13
软仿真吧?那是12T模式的老51的时间。STC51大部分指令都1T的了。
ID:879348 发表于 2025-4-22 13:27
ms级以上延时,开一个定时器才能准确,因为不同编译会产生不同效果,改一点代码又会改变
ID:230500 发表于 2025-4-22 08:11
阻塞延时我很少用, 一般只用几个nop 延时;正常使用都是用定时器,   所以你这个情况没有试过也没有碰到过,   但是分析一下 主要是 编译器不能识别是1T还是12T, 默认都是以12T在模拟运行, 所以54/12=4.5秒 就是正常的; 另外4.5秒与软件设置的3秒有误差, 这个可能就是软件延时本身的误差, 或者程序中还有其他的地方影响到了延时; 比如定时器等等。  可以试试注释掉其他的所有函数,主程序就只写个延时点灯的测试下。
ID:654797 发表于 2025-4-22 07:19
指命的延时都不一样
ID:1133081 发表于 2025-4-21 20:49

ID:584814 发表于 2025-4-21 19:55
降低stc8h的速度至stc89c52一样,这时你会发现又比较准了。
还有个办法就是外接晶振,加用示波器一类的辅助调节。
ID:1085441 发表于 2025-4-21 18:13
现在单片机都是1T的,还有中断等影响,我一般都是用示波器实测调整。
ID:401564 发表于 2025-4-21 18:09
超过1mS的延时,正常来说都是要用定时器或者PCA计数器来延时的,而不是让程序死等,虽然说你程序可能 很简单,不需要什么效率,但是,一个良好的编程习惯还是要有的
Keil是传统8051指令,跟STC的指令是不同的,除非你用硬件在线仿真
ID:468878 发表于 2025-4-21 18:07
用STC的ISP软件直接生成延时试试。STC是有1T的模式,也有12T模式,会影响延时。Atmel的都是12T的。

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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