打印
[经验分享]

关于延时函数的总结

[复制链接]
440|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2024-12-11 08:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在总结延时函数前,有必要先说明一下:

机器周期在使用12M晶振时是1us;在使用11.0592M晶振时是1.09us。

1、1us的延时函数

想要准确延时1us,直接使用一个空指令就能实现。

2、当我们想要准确延时几十微秒以上的时间时,推荐使用软件延时。

例如以下程序:

void Delay_us(unsigned char us)
{
        while(us--);
}
这个程序的工作过程:

       1、 如果不执行while(us--); (也就是当us = 0时),这个函数一共需要14us的时间;

        2、而 while(us--); 每执行一次消耗约6us的时间。

经过示波器测量后,确定这个函数任意us值的延时都是非常准确的。

2、当我们想要准确延时1ms及以上,推荐使用定时器进行延时。

使用定时器进行延时涉及定时器的知识,网上也有很文章讲的很详细,这里就不细说。

3、最后放上我使用示波器校正后的延时程序 “Delay.c” 。

#include <reg52.h>
#include "Delay.h"

/**
* 函数名称:        Timer0_Init
*
* 功能说明:        定时器0的初始化
*
* 参数说明:        无
*
* 函数返回:        无
*/
void Timer0_Init()
{
        TMOD &= 0xF0;        // 清除定时器0工作模式配置(保留定时器1工作模式配置)
        TMOD |= 0x01;          // 配置定时器0工作模式1(16位定时器模式)
        TF0 = 0;              // 清除溢出中断标志位
        TR0 = 0;              // 停止定时器
}

/**
* 函数名称:        Delay_us(14us - 1ms)
*
* 功能说明:        1、 最低延时14us(当us=0时);
*                                2、 us加1,则延时增加6us;
*                                3、 最高延时1ms
*                                 4、 误差为0
*
* 参数说明:        us - 要延时的微秒数
*
* 函数返回:        无
*/
void Delay_us(unsigned char us)
{
        while(us--);
}

/**
* 函数名称:        Delay_ms(1ms - 1min)
*
* 功能说明:        1、 最低延时1ms(当ms=1时);
*                                2、 ms加1,则延时增加1ms;
*                                3、 最高延时1分钟
*                                4、 ms越大,误差越大. ms = 1 时误差为0,延时1分钟时误差为3%
*
* 参数说明:        ms - 要延时的毫秒数
*
* 函数返回:        无
*/
void Delay_ms(unsigned int ms)
{
        /* 循环一次则完成一次1ms的延时 */
        while(ms--)
        {
                /* 设置定时器初值 */
                /* 40是示波器修正值 */               
                TH0 = (65536-1000+40) >> 8;                          // 定时器初值高字节
                TL0 = (65536-1000+40) & 0xFF;                        // 定时器初值低字节

                /* 启动定时器 */
                TR0 = 1;

                /* 等待定时器溢出 */
                while (TF0 == 0);                 // 等待定时器溢出标志位被置位

                /* 关闭定时器 */
                TR0 = 0;
                TF0 = 0;                                 // 清除溢出标志
        }
}

在主程序对定时器0进行初始化 Timer0_Init() 后,就能直接使用Delay_ms()

对于几微秒的延时,推荐直接使用空指令就可以了

以上都是基于12M晶振下进行校准的,用于11.0592M晶振的延时误差也很小,11.0592M晶振1ms延时误差大约在0.1ms以内。

当然使用这样的延时会有程序死等的弊端,有更好的设计希望大家指导一下。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/weixin_48786435/article/details/144208524

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2022

主题

15893

帖子

13

粉丝