怎么用C语言做单片机的精确延时【c语言延时函数单片机 单片机c语言延迟函数】在单片机应用中c语言延时函数单片机 , 经常会遇到需要短时间延时的情况,一般都是几十到几百μs,并且需要很高的精度(比如用单片机驱动DS18B20时 , 误差容许的范围在十几μs以内 , 不然很容易出错);而某些情况下延时时间较长,用计时器往往有点小题大做 。另外在特殊情况下,计时器甚至已经全部用于其c语言延时函数单片机他方面的定时处理,此时就只能使用软件定时了[1] 。
1C语言程序延时
Keil C51的编程语言常用的有2种c语言延时函数单片机: 一种是汇编语言;另一种是C 语言 。用汇编语言写单片机程序时,精确时间延时是相对容易解决的 。比如,用的是晶振频率为12 MHz的AT89C51,打算延时20 μs , 51单片机的指令周期是晶振频率的1/12,即一个机器周期为1 μs;“MOV R0,#X”需要2个机器周期,DJNZ也需要2个机器周期 , 单循环延时时间t=2X 3(X为装入寄存器R0的时间常数)[2] 。这样,存入R0里的数初始化为8即可,其精度可以达到1 μs 。用这种方法,可以非常方便地实现512 μs以下时间的延时 。如果需要更长时间,可以使用两层或更多层的嵌套,当然其精度误差会随着嵌套层的增加而成倍增加 。
虽然汇编语言的机器代码生成效率很高,但可读性却并不强,复杂一点的程序就更难读懂;而C语言在大多数情况下,其机器代码生成效率和汇编语言相当,但可读性和可移植性却远远超过汇编语言,且C 语言还可以嵌入汇编程序来解决高时效性的代码编写问题 。就开发周期而言,中大型软件的编写使用C 语言的开发周期通常要比汇编语言短很多,因此研究C语言程序的精确延时性能具有重要的意义 。
C程序中可使用不同类型的变量来进行延时设计 。经实验测试,使用unsigned char类型具有比unsigned int更优化的代码,在使用时应该使用unsigned char作为延时变量 。
2单层循环延时精度分析
下面是进行μs级延时的while程序代码 。
延时函数:
void delay1(unsigned char i) {
while(i );}
主函数:
void main() {
while(1) {
delay1(i);
}
}
使用Keil C51的反汇编功能,延时函数的汇编代码如下:
C:0x00E6AE07MOVR6,0x07
C:0x00E81FDECR7
C:0x00E9EEMOVA,R6
C:0x00EA70FAJNZC:00E6
C:0x00EC22RET
图1断点设置位置图
通过对i赋值为10,在主程序中图1所示的位置设置断点 。经过测试,第1次执行到断点处的时间为457 μs,再次执行到该处的时间为531 μs,第3次执行到断点处的时间为605 μs,10次while循环的时间为74 μs,整个测试结果如图2所示 。
图2使用i--方式测试仿真结果图
通过对汇编代码分析,时间延迟t=7X 4(其中X为i的取值) 。测试表明,for循环方式虽然生成的代码与用while语句不大一样,但是这两种方法的效率几乎相同 。C语言中的自减方式有两种,前面都使用的是i--的方式 , 能不能使用--i方式来获得不同的效果呢?将前面的主函数保持不变,delay1函数修改为下面的方式:
void delay1(unsigned char i) {
while(--i);}
同样进行反汇编 , 得到如下结果:
C:0x00E3DFFEDJNZR7,
C:00E3C:0x00E522RET
比较发现,--i的汇编代码效率明显高于i--方式 。由于只有1条语句DJNZ,执行只需要2个时钟周期,1个时钟周期按1 μs计算,其延时精度为2 μs;另外 , RET需要2个时钟周期,能够达到汇编语言代码的效率 。按前面的测试条件进行测试,第1次执行到断点处的时间为437 μs,再次执行到该处的时间为465 μs,第3次执行到断点处的时间为493 μs,10次while循环的时间为28 μs,整个测试结果如图3所示 。
图3使用--i方式测试仿真结果图
调整i的取值,i取8时延时时间为24 μs,i取9时延时时间为26 μs 。通过分析得出 , 10次循环为28 μs是由于外层循环造成的 , 其精度可以达到2 μs 。在设计时应该考虑参数传递和RET语句执行所需要的时间周期 。实验分析发现 , for语句使用--i方式,同样能够达到与汇编代码相同的精度 。i取不同值时延时仿真结果如图4所示 。
图4i取不同值时延时仿真结果图
3多重嵌套下的C程序延时
在某些情况下,延时较长,仅使用单层循环方式是不能完成的 。此时,只能使用多层循环方式,那么多重循环条件下,C程序的精度如何呢?下面是一个使用for语句实现1 s延时的函数 。
延时函数
void delay1s(void) {
for(k=100;k0;k--) //定时1 s
for(i=20;i0;i--)
for(j=248;j0;j--);
}
主函数调用延时函数代码段:
while(1){
delay1s();
scond =1;
}
为了直接衡量这段代码的效果,利用Keil C找出这段代码产生的汇编代码:
C:0x00B37002JNZ
C:00B7C:0x00B5150CDEC0x0C
C:0x00B7E50DMOVA,0x0D
C:0x00B9450CORLA,0x0C
C:0x00BB70DEJNZC:009B
C:0x00BDE50BMOVA,0x0B
C:0x00BF150BDEC0x0B
C:0x00C17002JNZC:00C5
C:0x00C3150ADEC0x0A
C:0x00C5E50BMOVA,0x0B
C:0x00C7450AORLA,0x0A
C:0x00C970CAJNZC:0095
C:0x00CB22RET
分析汇编代码,其他汇编代码使用的不是DJNZ跳转方式,而是DEC和JNZ语句来实现循环判断 。1条JNZ指令要花费2个时钟周期 , 3条指令就需要6个机器周期 , MOV指令和DEC指令各需要1小时钟周期 , 1个时钟周期按1 μs算,其精度最多达到8 μs,最后加上一条LCALL和一条RET语句,所以整个延时精度较差[4] 。
利用Keil C的测试工具,在一处设置一个断点 。第1次执行到中断处的时间为0.000 513 s,第2次执行到中断处的时间为1.000 922 s,时间延迟为1.000 409 s,测试结果如图5所示 。对于上面的3种循环嵌套,循环次数为100×20×248=496 000,每次循环的时间约为2 μs 。
图5三重嵌套循环1 s实现时间测试结果
为获取与汇编语言延时的差距,同样进行1 s的延时,程序代码段如下:
LCALL DELY1S
INC Second
DELY1S:MOV R5,#100
D2:MOV R6,#20
D1:MOV R7,#248
DJNZ R7,$
DJNZ R6,D1
DJNZ R5,D2
RET
通过Keil C51测试,其实际延迟时间为0.997 943 s 。虽然C语言实现延时方式的汇编代码复杂度增加,但是与汇编语言实现的方式性能差距并不大 。
4总结
汇编语言在实时性方面具有较大的优越性,虽然使用Keil C51可以在C语言程序中嵌入汇编代码,但是复杂度明显提高 。实验证明,只要合理地运用C语言 , 在延时编程方面就可以达到与汇编语言相近的精度 。为了获得精确的时间延迟,可通过Keil C工具的仿真功能,调整延迟量,从而得到较理想的结果 。
51单片机C语言中delay函数是怎么定义和使用的delay函数是一般自己定义c语言延时函数单片机的一个延时函数 。
c语言定义延时函数主要通过无意义指令c语言延时函数单片机的执行来达到延时的目的 。下面给出一个经典的延时函数 。
// 定义一个延时xms毫秒的延时函数
void delay(unsigned int xms)// xms代表需要延时的毫秒数
{
unsigned int x,y;
for(x=xms;x0;x--)
for(y=110;y0;y--);
}
单片机C语言编程关于延时函数单片机的C语言关于延时函数主要有两种
一种是用for循环 , 通过单片机执行空指令达到延时的目的
如:
for(i=0;i100;i)
{
;
}
这个简单的语句会执行100次空指令
每一次指令的时间可以大概确定
因此这个是最简单的延时函数
第二种是通过定时器的方式来实现
定时器是通过对单片机的晶振进行计数
然后在定时器中断服务函数里面实现定时时间的计算及设置
51单片机的定时器0中断服务函数为
void
time0()
interrupt
1
{
...
}
单片机c语言编程怎么去延时?在单片机的C语言编程中,可以使用循环结构来实现延时操作 。具体而言,可以使用一个for循环来实现一段时间的延时 。
以下是一个简单的延时函数的示例代码:
void delay_ms(unsigned int ms)
{
unsigned int i,j;
for(i=0;ims;i)
for(j=0;j1000;j);
}
上述代码定义了一个名为delay_ms的函数,该函数的参数为一个无符号整数ms,表示需要延时的时间(单位为毫秒) 。在函数内部,使用了两个嵌套的for循环来实现延时操作 。外层循环控制需要延时的毫秒数,内层循环则执行1000次,以模拟一个较为精确的延时 。在实际使用时,可以根据需要调整内层循环的执行次数 , 以达到较为精确的延时效果 。
需要注意的是,延时函数的实现可能会受到单片机的工作频率、编译器优化等因素的影响,因此在实际使用时,需要进行一定的测试和调整 , 以确保延时效果符合要求 。
51单片机用c语言怎么写延时函数?延时时间的计算与单片机的晶振频率有关 。若晶振频率为12Mhzc语言延时函数单片机,那么单片机每震动一次所需要的时间是1/12M s 。那么再来看看单片机执行一次自减所需要的振动次数是96次,假如我们对时间要求不是特别精确的话 , 可以约等于100来计算 。现在通过上面两个数据可以得出:单片机每执行一次自减所需要的时间是1/12M *100(s),即1/120000 s,逆向计算一下 , 每1ms需要自减多少次c语言延时函数单片机?120次对吧 。所以一个简单的延时功能就诞生了,我们只需要自减120次,就可以延时1ms,如果我们要延时50ms呢 , 那就自减50*120=6000次 。那么在程序上如何表达呢?我们可以用两套for循环
void delay(int i){
int x,y;
for(x=i;x0;x--){
for(y=120;y0;y--)
}
}
参数 i 代表该函数延时多少ms
51单片机C语言程序中延时函数delay的原理是什么?原理:只是执行一些所谓的“无实际意义的指令”c语言延时函数单片机,如缩放或执行一个int自加c语言延时函数单片机,简单地说,就像高中数学中的“乘法原理”一样,很容易迅速增加上面提到的“无意义指令”的数量
关于大小的值:如果是在C语言中 , 该值不仅与水晶振动、单片机本身的速度 , 但也与C的编译器,所以,虽然这个值可以精确计算,但大多数情况下,程序员是经验值 。
当然,如果c语言延时函数单片机你在汇编中编程,情况就不同了,因为每条指令使用一定数量的机器周期,你当然可以根据所有指令使用的总时间来计算特定延迟的总时间 。
扩展资料:
定义延迟XMS毫秒的延迟函数
Voiddelay(unsignedintXMS)//XMS表示需要延迟的毫秒数
{
无符号intx,yc语言延时函数单片机;
For(x=XMS;X0;X-)
For(y=110;Y”0;Y-);
}
使用:
VoidDelay10us(ucharMs)
{
Uchar数据我;
(;女士“0;------Ms)
对于(I = 26)我 0;我-);
}
I=[(延迟值-1.75)*12/ms-15]/4
c语言延时函数单片机的介绍就聊到这里吧,感谢你花时间阅读本站内容 , 更多关于单片机c语言延迟函数、c语言延时函数单片机的信息别忘了在本站进行查找喔 。
推荐阅读
- 关于js前几个字符的信息
- js如何获取dom内容,js中如何获取所有div节点
- 有什么好玩解密冒险的游戏,好玩的冒险解密手游
- 自省go语言 啥是自省
- 拍摄花朵用什么设备好呢,拍摄花朵图片
- jquery怎么添加到div,jquery给div添加内容
- win7安装xp虚拟机安装教程,windows7安装虚拟机教程
- java代码优化相关的书 java性能优化书籍推荐
- 快递显卡变板砖怎么办,快递把显卡弄坏了怎么办