单片机应用与项目实践(下)_第三课 延迟技术

欢迎使用Markdown编辑器写博客

产生精确的延迟是许多嵌入式系统的关键要求:

  • 硬件延迟:通过使用一个片内定时器产生精确地延迟,特别适合产生大约0.1ms或更长的延迟。
  • 软件延迟:不需要硬件资源,灵活方便,适用于产生较短的延迟(以微秒为单位)

    早期的8051定时器每12个振荡周期加1.当(16)位定时器溢出时,即从65535加1,定时器标志(TF0)将被置1。这个溢出还可以产生中断。
    硬件延迟通常按照以下形式计算:

    • 计算定时器所需的初始值
    • 将这个值加载到定时器0或定时器1中。
    • 启动定时器
    • 定时器将按照由振荡器频率确定的速度增加,而不需要软件的干预。等待定时器到达它的最大值后“翻转”
    • 定时器的翻转将改变标志变量的值,从而标志延迟的结束。
    • 对于一个运行在12MHz,12个振荡周期/指令的8051,使用16位定时器能够产生最大延迟是65ms。如果需要更长的延迟,可以重复这个过程。
      对于早期的12MHz的8051,理论上最小的时间增量是1微秒(即振荡器频率的1/12)。然而延迟往往小于调用延迟函数、设置,以及启动定时器的时间。比如如果定时器采用中断方式,则10微秒到了之后,进入中断服务程序,而进入中断服务程序的时间本身就有几微秒。同时其他单条语句的执行时间也是微秒级别。
      一般说来,小于10微秒的延迟最好由软件来实现。

调用延迟函数以及为定时器人工重装初始计数值需要时间。如果没有仔细地将这些因素考虑在内,就无法产生精确的时间延迟。例如:当试图通过调用20次50ms的延迟来产生1s的延迟时,需要特别关注这种误差,因为将不可能做到精确。不要试图使用硬件延迟来实现实时时钟。
一般来说,串口波特率的产生通常采用定时器T1。

//定义用于1ms延迟的定时器0/定时器1的重装值,已考虑到函数调用等等开销而做出调整
#define PRELOAD01 (65536-OSC_FREQ/(OSC_PER_INST *1063))
#define PRELOAD01H (PRELOAD01 / 256)
#define PRELOAD01L (PRELOAD01 % 256)

//大约延迟N毫秒
void Hardware_Delay_T0(const tWord N)
{
    tWord i;
    TMOD &= 0XF0;  //清除所有有关T0的位(T1不变)
    TMOD |= OXO1;   //设置所需的T0的位(T1不变)
    ET0 = 0;        //不使用中断

    //每个循环的延迟值“大约”是1ms.
    for ( i = 0; i< N; i++)
    {
        TH0 = PRELOAD01H ;
        Tl0 = PRELOAD01L ;
        TF0 = 0;          //清除溢出标志
        TR0 = 1;
        while ( TF0 == 0); //循环直到定时器0溢出(TF0 = 1)
        TRO = 0;
    }

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值