对于STC51单片机来说,延时函数,想必都不陌生。而用的最多的延时基本都是通过软件方法实现的,但由于STC51不同系列的芯片所采用的指令集不同,各指令执行所用机器周期不同。例如STC12Cx的一个振荡周期=一个机器周期,相对STC89Cx的(12个振荡周期=一个机器周期)运行速度快了近10倍有余,就不能用同一个延时函数。

1. STC指令集(版本)

STC_Y1 :
STC89Cx/STC90Cx
STC89LEx/STC90LEx
STC_Y3 :
STC12Cx/STC12LEx
STC11Fx/STC11Lx/ STC10Fx/STC10Lx
STC15F104E/ STC15L104E(A版)
STC15F204EA/ STC15L204EA(A版)
STC_Y5 :
STC15Fxx/STC15Lxx
其中不包含:STC15F104E/STC15L104E (A版) 和 STC15F204EA/STC15L204EA(A版)
STC_Y6 :
STC8F/ STC8A/ STC8G/ STC8H

通过STC官方提供的 软件STC-ISP可见,不同指令集版本下同一条指令执行所用时钟周期是不同的。因此可能你编写的软件延时函数就不能通用。

2. STC-ISP 软件生成延时函数


可以看到,这种方法还是比较可靠的,也是软件延时比较精确的一种,但是呢我比较喜欢那种想延时多久,给个参数就完了的不专业方法,于是呢就在这个软件生成的基础上进行了点小操作,让它具有通用性,不管是Y1,Y3还是Y5一个函数搞定。

2. STC-Y1/ Y3/ Y5 通用软件延时

首先为了做指令集区分,delay.h写法如下:其中包括了一些常用数据类型的定义,后续为了做通用库函数开发用。

// delay.h 文件
//       根据芯片型号 选择对应指令集 用于软件延时 区分
/* ==========================================================*     STC_Y1 : STC89Cx/STC90Cx  STC89LEx/STC90LEx *    *     STC_Y3 : STC12Cx/STC12LEx STC11Fx/STC11Lx/STC10Fx/STC10Lx *                 STC15F104E/STC15L104E(A版) *             STC15F204EA/STC15L204EA(A版)*    *     STC_Y5: STC15Fxx/STC15Lxx *     不包含:STC15F104E/STC15L104E (A版) *             和 STC15F204EA/STC15L204EA(A版)* ==========================================================*/
//#define _STC_Y1
#define _STC_Y3    //测试芯片型号 : STC12C5A60S2
//#define _STC_Y5#include "intrins.h"  //包含移位运算和空指令头文件#ifndef _TYPE_H
#define _TYPE_Htypedef   signed char           s8;
typedef   unsigned char        u8;
typedef  signed   int          s16;
typedef  unsigned int          u16;
typedef  signed   long int     s32;
typedef  unsigned long int     u32;
#endif

接下来是delay.c文件的写法,这里我主要使用C语言预编译指令的方法:

/**************************************************** 文件说明:STC51单片机通用软件延时函数* 本程序适用于STC除8以外系列外的单片机* 作 者:Guard_Byte* 时 间:2022-05-08**************************************************/
#include "delay.h" #ifdef _STC_Y1
/******************************************************************* 函数名:delay_ms(unsigned int m)* 说  明: ms 延时函数初始化* 晶 振 :@11.0592MHz*****************************************************************/
void delay_ms(u16 m)
{ unsigned char i, j;for(m; m>0; m--){   i = 2;j = 199;do{while (--j);} while (--i);}
}
#endif   /*  条件 _STC_Y1  完 */#ifdef _STC_Y3
/******************************************************************* 函数名:delay_ms(unsigned int k)* 说  明: ms 延时函数初始化* 晶 振 :@11.0592MHz*****************************************************************/
void delay_ms(u16 m)
{ unsigned char i, j;for(m; m>0; m--){   _nop_(); //1usi = 11,j = 190;do   //1ms延时{while (--j);} while (--i);}
}/******************************************************************* 函数名:delay_us(unsigned int k)* 说  明:u us 延时函数初始化* 晶 振 :@11.0592MHz*****************************************************************/
void delay_us(u16 u)
{ for(u;(u-1)>0;u--){    _nop_();    //1us延时,  大约1us 由于循环赋值耗时,值越大 误差越大}
}
#endif   /*  条件 _STC_Y3 完 */#ifdef _STC_Y5
/******************************************************************* 函数名:delay_ms(unsigned int m)* 说  明: ms 延时函数初始化* 晶 振 :@11.0592MHz*****************************************************************/
void delay_ms(u16 m)
{ unsigned char i, j;for(m; m>0; m--){   _nop_();_nop_();
//      _nop_(); //考虑循环耗时i = 11;j = 190;do{while (--j);} while (--i);}
}/******************************************************************* 函数名:delay_us(unsigned int u)* 说  明:u us 延时函数初始化* 晶 振 :@11.0592MHz*****************************************************************/
void delay_us(u16 u)
{ for(u;u>0;u--){    _nop_();    //1us延时_nop_();
//  _nop_();}
}
#endif   /*  条件 _STC_Y5 完 */

总结:

这种软件延时的方法基本可以满足不同型号STC51单片机,但是由于没有经过精确计算函数调用和循环等一些指令的时间,如果延时参数过大 可能存在us到ms的误差,但是对于,对时间没有太高要求的任务,或者学习使用是没有问题的。经过简单测试,在STC89C52RC和STC12C5A60S2S上,500ms延时误差在几十微秒,还算可以接受。学习笔记 经供参考,大家有更精确的软件延时办法还望指正!

学习笔记 51单片机通用软件延时方法相关推荐

  1. 单片机学习笔记————51单片机实现用LED灯和按键来模拟工业自动化设备的运动控制

    一.使用proteus绘制简单的电路图,用于后续仿真 二.编写程序 /***************************************************************** ...

  2. 单片机学习笔记————51单片机实现带数码管显示的加法简易计算器

    一.使用proteus绘制简单的电路图,用于后续仿真 二.编写程序 /***************************************************************** ...

  3. 单片机学习笔记————51单片机实现主机的串口收发

    proteus虚拟串口的实现:https://mp.csdn.net/console/editor/html/107251649 一.使用proteus绘制简单的电路图,用于后续仿真 二.编写程序 / ...

  4. [学习笔记]51单片机

    关于51单片机入门,前提是先学一下电路,不然有的的地方不太容易理解 之前在知乎上看见一位dalao总结的单片机学习分四个层次: 第一个层次:完成单片机开发板的学习,理解单片机的工作,能够看懂单片机的程 ...

  5. 单片机学习笔记————51单片机实现带数码管显示的象棋比赛专用计时器

    一.使用proteus绘制简单的电路图,用于后续仿真 二.编写程序 /***************************************************************** ...

  6. 单片机学习笔记————51单片机实现数码管中的倒计时程序

    一.使用proteus绘制简单的电路图,用于后续仿真 二.编写程序 /***************************************************************** ...

  7. 单片机学习笔记————51单片机实现在数码管中实现iphone4S开机密码锁的程序

    一.使用proteus绘制简单的电路图,用于后续仿真 二.编写程序 /***************************************************************** ...

  8. 软件工程学习笔记——第六章 软件设计方法

    目录 第一章 概述 第二章 过程和活动 第三章 软件过程模型 第四章 问题定义和可行性研究方法 第五章 需求分析方法-1 第五章 需求分析方法-2 第六章 软件设计方法 第七章 软件实施与测试方法 第 ...

  9. 单片机学习笔记————51单片机实现矩阵键盘的组合按键触发

    一.使用proteus绘制简单的电路图,用于后续仿真 二.编写程序 /***************************************************************** ...

最新文章

  1. bzoj千题计划303:bzoj4827: [Hnoi2017]礼物
  2. UA MATH564 概率论I 离散型随机变量
  3. 打基础和俄罗斯方块的关系
  4. BUG总结——【构造函数写逻辑】引发的极大的线上问题
  5. 历届试题 错误票据(multiset)
  6. python 运行日志logging代替方案
  7. 玩转mini2440开发板之【编译烧录rootfs根文件系统全过程记录】
  8. linux 固定ip_linux固定IP
  9. 17.立体匹配——匹配两个图 Matlab实战,立体效果_3
  10. 用WAP手机远程遥控电脑1
  11. css 标签太长的时候隐藏为点点
  12. 在线JSON校验格式化工具,文本对比工具,截图notepad工具
  13. php 获取城市列表接口,省份城市区域列表
  14. 寻找春天 九宫格日记-2013.01.12
  15. select 显示”请选择“,怎样在选择之后消失的问题
  16. Maximo 人员- 应用程序导入,公共操作怎么配置,求大神指点,万分感谢
  17. Android多窗口分屏(原生方法)
  18. 登录失败:用户帐户限制。可能的原因包括不允许空密码,登录时间限制,或强制的策略限制。...
  19. VC操作INI文件 ,INI文件操作总结,如何操作INI文件,INI文件使用方法小结
  20. DO-214AC封装尺寸图

热门文章

  1. VB文本框textbox的那点事
  2. 认识一下网关,路由器,交换机,猫
  3. JavaScript的函数(function)
  4. css background-image 属性
  5. Linux下2D、3D的测试软件glxgears
  6. Mantis 安装与配置
  7. 抖音SEO优化源码,企业号搜索排名系统,技术理论分析搭建。
  8. 计算机应用技术高数学几本书,高一下学期数学学必修几 学哪几本书
  9. USB开发-USB从启动到运行
  10. mysql数据库修复_MySQL数据库修复方法(MyISAM/InnoDB)