微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > Avr单片机编程---延迟函数

Avr单片机编程---延迟函数

时间:11-23 来源:互联网 点击:
avr-gcc提供了两个延迟函数,可以在用户的程序中使用,前提--加入avr/delay.h这个头文件:

_delay_us(double __us)
_delay_ms(double __ms)
而这两个延迟函数在实际工作的时候,调用了另两个函数,位于delay_basic.h中:
a, _delay_loop_1(uint8_t __count)
b,_delay_loop_2(uint16_t __count)
a 函数可以看出,_count的最大值是256,b 函数中_count的最大值是65536。在delay_basic.h中有说明,也可以结合a,b两个函数的具体定义看,a 函数执行一次的时间是3个指令周期,b 执行一次的时间是4个指令周期,一个指令周期 T = 1 / F_CPU。
(测试:可以试着计算下当F_CPU取值1M时,_count取1,_delay_loop_1和_delay_loop_2分别延迟时间
是多 少,如果F_CPU取2M呢,延迟又是多少?)
*********************************************
F_CPU在avr-gcc中有定义,这个值是在编译的时候传递给编译器的,说明用户程序的晶振频率,编译器为了保证编译过程中防止因用户为定义这个 F_CPU的值,设定一个初值F_CPU=100 0000UL,即默认用户使用的是1M的晶振。当然,在实际程序设计时一定要根据实际用到的晶振设定这个值,否则,延迟肯定不准。可以在定义加载头文件前这样:如
#include
#define F_CPU 1000000UL
#include
#include
***********************************************
_delay_us(double __us), _delay_ms(double __ms)中又有这样的定义:
double __tmp = ((F_CPU) / 4e3) * __ms
__ticks = (uint16_t)__tmp;
_delay_loop_2(__ticks);
--------------------------------------------
double __tmp = ((F_CPU) / 3e6) * __us;
__ticks = (uint8_t)__tmp;
_delay_loop_1(__ticks);
---------------------------------------------
所以根据a,b两个函数中_count(实际参数)的最大值描述就应该是:
((F_CPU) / 3e6) * __us最大值是256
((F_CPU) / 4e3) * __ms的最大值是65536
即我们在自己程序中调用 _delay_us(double __us),_delay_ms(double __ms)这两个函数时参数的选择与所取的F_CPU(也就是实际用到的晶振频率)是有关系的。
当F_CPU取值为1M时,__us的最大取值是768,__ms的最大取值是65536*4
当F_CPU取值为2M时,__us的最大取值是768/2,__ms的最大取值是65536*4/2
......
当F_CPU取值为8M时,__us的最大取值是768/8,__ms的最大取值是65536*4/8
所以,延迟函数的参数取值是不能一概而论的。
//*************************************************************************************************************************
现在再来看究竟延迟了多久?
_delay_us(double __us)的延迟时间因为调用了_delay_loop_1(),而_delay_loop_1()是执行3个指令周期,所以延迟时间就是:
((F_CPU) / 3e6) * __us*3*T (T = 1 / F_CPU 单位MHz)
_delay_ms(double __ms)的延迟时间因为调用了_delay_loop_2(),而_delay_loop_2()是执行4个指令周期,所以延迟时间就是:
((F_CPU) / 4e3) * __ms*4*T (T = 1 / F_CPU 单位MHz)
可以试着计算下,当F_CPU取值为1M时,_delay_us(X)就是延迟X us,_delay_ms(X)就是延迟X ms
补充:
其实,如果自己查看新的源代码可以发现,现在的定时的时间并不像有的旧的文章上说的那样,限制在一定的范围内。因为代码更新过了,嘎嘎。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top