0
收藏
微博
微信
复制链接

8051没有延迟函数?工程师都用这些土办法!

2025-06-16 10:05
92

如果你刚接触嵌入式开发,可能会对8051单片机束手无策,因为它的标准库好像没有延迟函数,所以如何用最基础的指令“炼”出精准延时?本文将提供三种方案,以供参考。

1.png

1、空循环法

void delay_ms(unsigned int ms) {

    unsigned int i, j;

    for(i=0; i

        for(j=0; j<123; j++); // 12MHz晶振下约1ms

核心逻辑:通过双重循环消耗CPU周期,循环次数需根据晶振频率手动校准。

致命缺陷:编译器优化会“吃掉”空循环,需加volatile关键字或关闭优化。

2、定时器中断

配置步骤

初始化Timer0(模式1,16位自动重装):

TMOD |= 0x01; // Timer0模式1

TH0 = 0xFC;   // 1ms@12MHz(计算:65536-1000=64536=FC18H)

TL0 = 0x18;

ET0 = 1;      // 允许Timer0中断

EA = 1;       // 开总中断

TR0 = 1;      // 启动定时器

中断服务函数:

volatile unsigned int ms_count = 0;

void timer0_isr() interrupt 1 {

    TH0 = 0xFC; TL0 = 0x18; // 重装初值

    ms_count++;

}

调用延时:

void delay_ms(unsigned int ms) {

    ms_count = 0;

    while(ms_count < ms);

}

优势:不受编译器优化影响,延时精度达微秒级。

3、汇编指令级优化

DELAY_MS:

    MOV R6, #250     ; 外层循环次数

DELAY_LOOP:

    MOV R7, #250     ; 内层循环次数

    DJNZ R7, $       ; 消耗1个机器周期

    DJNZ R6, DELAY_LOOP

    RET             ; 12MHz下约1ms

适用场景:对代码体积敏感的极端环境(如8051小容量型号)。

4、如何选择?

简单场景(如LED闪烁) → 空循环法(代码最简)。

多任务系统(如UART通信) → 定时器中断(不阻塞主程序)。

代码体积优先(如OTP芯片) → 汇编优化(牺牲可读性换空间)。


本文凡亿教育原创文章,转载请注明来源!

登录后查看更多
0
评论 0
收藏
侵权举报
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表凡亿课堂立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。

热门评论0

相关文章

电路之家

专注电子、科技分享,对电子领域深入剖解

开班信息