单片机C语言延时分析

1.例1,12MHz晶振调试

以下两个图片是无参数的delay函数,内部用的是for循环来delay。

LCALL 2个周期

MOV A到RX 1个周期

CLR  1个周期

INC  1个周期

CJNE 2个周期

RET  2个周期

LCALL+RET+CLR+MOV+110*(INC+CJNE)=2+2+1+1+110*(1+2)=336us  按110来算就是约等于110*3个周期,因为循环语句就两条共3个周期。




892.734-892.398ms=336us




例2:12MHz晶振调试,传参数,for循环只有1层,且是char类型。

MOV 1个周期

LCALL 2个周期

CLR 1个周期

SUBB 1个周期

JNC 2个周期

INC  1个周期

SMJP 2个周期

RET 2个周期

MOV+LCALL+CLR+MOV+123*(MOV+CLR+SUBB+JNC+INC+SJMP)-INC-SJMP+RET=1+2+1+1+124*(1+1+1+2+1+2)-1-2+2=996us



893.394ms-892.398ms=996us




结论,传参数类型的delay,占用更多指令,所以延迟更大。另外还和晶振大小有关,所以需要精确的延时时,需要单独测试for循环的延时,才能拿来使用。


在51单片机中使用C语言编写延时函数可以通过不同的方式实现。 ### 精确延时函数 有一种能精确计数延时值且精确达到1us的函数,所用CPU为STC12C5412系列12倍速的单片机,修改参数值后其它系列单片机也通用。不过引用中未给出具体代码,可根据精确延时的思路编写示例代码如下: ```c #include <reg51.h> // 精确延时1us函数 void delay_1us() { _nop_(); // 执行一个空操作,延时1个机器周期 } // 精确延时n us函数 void delay_nus(unsigned int n) { while(n--) { delay_1us(); } } ``` ### 普通延时函数 C语言定义延时函数主要通过无意义指令的执行来达到延时的目的,可使用不同类型的变量来进行延时设计,经实验测试,使用unsigned char类型具有比unsigned int更优化的代码,示例代码如下: ```c // 延时函数 void delay(unsigned char t) { while(t--); } ``` ### 定时器延时函数 对于需要较长时间且相对精确的延时,可以使用定时器。例如要实现0.2s延时,可设50ms中断一次,定时初值TH0 = 0x3c、TL0 = 0xb0,中断4次即为0.2s,示例代码如下: ```c #include <reg51.h> unsigned char count = 0; // 定时器0中断服务函数 void timer0_isr() interrupt 1 { TH0 = 0x3c; TL0 = 0xb0; count++; } // 延时0.2s函数 void delay_0_2s() { TMOD |= 0x01; // 设置定时器0为模式1 TH0 = 0x3c; TL0 = 0xb0; ET0 = 1; // 使能定时器0中断 EA = 1; // 全局中断使能 TR0 = 1; // 启动定时器0 while(count < 4); // 等待4次中断,即0.2s count = 0; TR0 = 0; // 停止定时器0 } ``` ### 延时子程序设计注意事项 在C51中进行精确的延时子程序设计时,有一些注意事项: 1. 尽量不要或少在延时子程序中定义局部变量,所有的延时子程序中变量通过有参函数传递。 2. 采用do…while结构做循环体要比for结构做循环体好。 3. 要进行循环体嵌套时,采用先内循环,再减减比先减减,再内循环要好[^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值