单片机 软件延时时间控制
单片机 软件延时时间控制
一、简述
记--通过代码方式实现软件延时(不精确延时)。
二、指令周期
单片机需要一个时钟信号送给内部各个电路,才能使它们有节拍地协同工作。时钟信号的频率是由外部震荡电路的晶振频率决定的。
外接晶振的频率 = 时钟信号的频率 = 工作频率。(如24MHz,12MHz,11.0592MHz)
震荡周期:为单片机提供时钟脉冲的振荡源的周期。
震荡周期 = 1/晶振频率 (如晶振频率是12MHz时,振荡周期 = 1/12MHz = (1/12)us)
机器周期:51系列单片机的一个机器周期由12个震荡周期组成。
机器周期 = 12 * 振荡周期
(如晶振频率是24MHz时,振荡周期 = 1/24MHz = (1/24)us,机器周期 = 12*(1/24)us = 0.5us)
(如晶振频率是12MHz时,振荡周期 = 1/12MHz = (1/12)us,机器周期 = 12*(1/12)us = 1us)
(如晶振频率是11.0592MHz时,振荡周期 = 1/12MHz = (1/11.0592)us,机器周期 = 12*(1/11.0592)us = 1.085us)
指令周期:单片机执行一条指令所用的时间。
一般来说,单片机执行1个简单的指令需要一个机器周期,执行复杂的指令需要两个机器周期。
三、软件延时
通过一个循环来实现延时
测试代码:
#include <reg51.h>void delay(void)//延时函数
{unsigned char i;for(i=0; i<100; i++);
}void main(void)
{while(1){//dosomething()delay();}
}
在Keil C51 环境下编译后,点击"调试"--"开始";在执行"视图"--"反汇编",可以看到延时函数对应的汇编代码。
其中:
CLR指令消耗1个机器周期
MOV指令消耗1个机器周期
INC指令消耗1个机器周期
CJNE指令消耗2个机器周期
根据循环条件,INC指令和CJNE指令总共要执行100次(0x64=100),共消耗机器周期(1+2)*100=300,
加上CLR指令和MOV指令,循环程序总共消耗机器周期:1+1+300=302
如果单片机的晶振频率为11.0592MHz,则机器周期 = 12*(1/11.0592)us = 1.085us。
那么for循环程序耗时为302*1.085us=327.67us。
deley()函数用时:0.06607530s-0.000422209s=0.065653091s=65.653091ms=65653.091us
(指令的执行时间不代表函数的执行时间。函数跳转需要时间,开辟函数栈、临时变量、回收栈资源等需要时间,因此c语言有内联(inline)函数,宏函数(带参宏)用来提高执行效率)。
两层循环
#include <reg51.h>void delay(void)//延时函数
{unsigned char i, j;for(i=0; i<100; i++)for(j=0; j<200; j++);
}void main(void)
{while(1){//dosomething()delay();}
}
注:对于C语言编译器,某些编译器会进行代码优化,比如循环里面什么都没做,编译器有可能将循环去掉。
软件延时不精准:因为相当于是通过控制CPU做某一些预定消耗一定时间的动作,根据CPU执行完成判断已经过去多长时间。但是CPU有可能在中途被其他进程强行占用(优先级高的进程),CPU被迫中断当前执行,优先执行优先级较高的任务,当执行完优先级较高的任务,才回来继续执行之前中断的任务,那么延时就会加长。比如想要延时1分钟,我们预定执行A动作之后,刚好耗时1分钟,那么让CPU执行这个动作就达到延时1分钟。如果当CPU执行到一半时,突然有一个紧急任务S(优先级高)发生,要求CPU立即处理,那么CPU就会中断当前任务A,优先处理紧急任务S,等待执行完毕,才回来继续执行之前被中断的任务A。那么当A任务执行完毕,我们预期是从执行开始到结束消耗时间1分钟,但是实际上已经过去不止1分钟,因为中途被中断了。所以软件延时时间越长,容易被中断,而且CPU不能长时间被一个进程独占,延时越不精准。
要实现精确的延时可使用硬件延时:使用定时器/计数器。定时器/计数器是根据时钟信号脉冲计数的,是直接跟硬件晶振相关的。
//函数名:delay_1ms(uint x)
//功能:利用定时器0精确定时1ms
//调用函数:
//输入参数:x,1ms计数
//输出参数:
//说明:延时的时间为1ms乘以xvoid delay_1ms(uint x)
{TMOD=0X01;//开定时器0,工作方式为1TR0=1;//启动定时器0;while(x--){TH0=0Xfc;//定时1ms初值的高8位装入TH0TL0=0X18;//定时1ms初值的低8位装入TL0while(!TF0);//等待,直到TF0为1TF0=0; //重置溢出位标志} TR0=0;//停止定时器0;
}
延时1s:delay_1ms(1000); //1000ms = 1s
单片机 软件延时时间控制相关推荐
- 单片机软件延时的时间计算
点亮LED以后,如果我们想实现LED间隔性的亮灭,我们又该怎么办呢?这里我们就需要使用单片机进行延时.延时的方法有两种,一个是使用软件延时,这个不精确,但能满足简单的需要:二是使用单片机内部的定时器, ...
- [STC系列单片机/51单片机]软件延时计算方法详解
选取12M晶振时,时钟周期为(1 / 12) us,且假如单片机工作在12T模式下,则一个机器周期为12 * (1 / 12) = 1 us. 为表述方便,下文均用T_M表示机器周期,观察KEIL仿真 ...
- 51单片机——软件延时实现跑马灯仿真
注:本文主要利用keil和proteus软件联合仿真51单片机进行跑马灯实例(软件延时). keil 程序 #include <REGX51.H> void delay(unsigned ...
- 89c52单片机c语言延时程序计算 脉冲,89C52单片机定时器延时时间的计算与程序解析 - STC89C52单片机定时器/计数器详解(含程序和定时器2)...
STC单片机STC89C52RC定时器延时时间的计算 延时时间要根据晶振频率计算,不同板子可能有所不同. 时钟周期: 1/时钟源,在我现在这块板子上,晶振频率是11.0592M,也就是时钟周期是 1/ ...
- STC系列单片机软件延时,ms级较精确
#include <reg51.H>#define STC_Y1 97560U // 89C/LEXX.90C/LEXX #define STC_Y3 14050U // 10F/Lxx. ...
- 8051系列单片机软件精确延时研究(二)
续前篇 8051单片机软件精确延时研究(一) 由前篇可知,在DelayX10us()函数中用for循环延时会产生10个机器周期的固定误差,其中X传值.调用函数.子函数返回共5个机器周期,这是只要调用带 ...
- 实例讲解,51单片机常用延时控制子程序
单片机中常用的延时控制方式有两种.一种是采用编程的方式达到延时的目的,另一种方法则是通过单片机中的两个定时器T0和T1进行计时达到延时的目的. 本例通过具体实例说明单片机的两种延时控制方式在实际中的应 ...
- 51单片机c语言延时计算软件,51单片机精确延时程序大集合+初值计算工具
在论坛上看到不少不错的延时程序,整理如下共同分享: 精确延时计算公式: 延时时间=[(2*第一层循环+3)*第二层循环+3]*第三层循环+5 ;延时5秒左右 DELAY5S:PUSH 04H;2个 ...
- 学习笔记 51单片机通用软件延时方法
对于STC51单片机来说,延时函数,想必都不陌生.而用的最多的延时基本都是通过软件方法实现的,但由于STC51不同系列的芯片所采用的指令集不同,各指令执行所用机器周期不同.例如STC12Cx的一个振荡 ...
最新文章
- 关于批量插入数据之我见(100万级别的数据,mysql) (转)
- YOLOv3 学习笔记:大神好贴汇总+自身经验记录
- 远程桌面提示:身份验证错误 要求的函数不受支持
- 26 CO配置-控制-产品成本控制-成本对象控制-期末结算-定义结果分析版本
- JavaScript 中 Property 和 Attribute 的区别
- JBoss的部署机制
- 【废了-准备删除02】信息收集——基于WAMP的drupal7.x管理系统
- java毕业设计电影票网上订票系统Mybatis+系统+数据库+调试部署
- C++ 逆向笔记12 call和堆栈平衡
- 使用J-Link打印日志——SEGGER Real-Time Transfer(RTT)工具的移植使用
- 硬件工程师成长之路(4)——元件焊接
- Rdd,DataFrame和DataSet的区别
- 定了!阿里日成了“中国品牌日”! 老外说,原因都在这里了
- android res文件夹下values对应最全的本地化语言
- 萧萧雨落情未绝,瑟瑟风起愁又涌
- SpringBoot启动图标修改(通俗易懂)
- 智能除味器——外壳结构部分设计(3D打印)
- CSS3 过渡特性创建信封效果的联系表单
- 语音的合成和分解 enframe和overlapadd 用法
- 企业网站建设的八大种类是什么?