AVR自带延时函数,_delay_ms() _delay_loop_2()

#include <avr/io.h>
#include <stdint.h>
#include <util/delay.h>
void DelayMs(uint16_t t)
{
uint16_t i;
for(i=0;i<t;i++)
{
//_delay_ms(1000);
_delay_loop_2(1000);
}
}
int main(void)
{
DDRB|=_BV(PB0);
while(1)
{
PORTB&=~_BV(PB0);
DelayMs(300);
PORTB|=_BV(PB0);
DelayMs(300);
}
}
当程序使用_delay_ms(1000)作为延时主体,IO口输出一直为高,延时主体改为 _delay_loop_2(1000);可以工作,请问这是什么原因造成的呢!

要想使_delay_ms()正常工作需要正确定义常量F_CPU为所采用的时钟频率,以Hz为单位,若没有定义则系统默认定义为# define F_CPU 1000000UL,也就是1MHz,并在编译时出现警告 warning "F_CPU not defined for <util/delay.h>",所以如果你的时钟不是1MHz时要正确定义F_CPU,再有_delay_ms()延时以毫秒为单位,你的_delay_ms(1000)延时了整整1秒,因而用在你的函数DelayMs(300)里要延时300秒,你耐心等上5分钟它会变低的。其实_delay_ms()函数内部调用了_delay_loop_2(),这个函数内部执行空循环,每个循环要四个时钟周期,忽略开始时设置寄存器所需时间,在1MHz时钟频率时_delay_loop_2(1000)延时4ms,你的DelayMs(300)将延时大约1.2秒,所以很容易看到IO口高低变换,当然如果你的时钟频率不是1MHz,那么具体时间就要具体计算了。追问

谢谢你,之前不知道,以为_delay_ms()延时也是4ms呢,所以就出现了上述状况,后来看了函数才知道,参数最大不能超过265,可是网上有的资料说什么旧版本的Winavr最大延时265ms,新版本的可以延时到大概6000ms,有这么一说么?我也找不到相关资料!

追答

是的,我装的是AVRstudio6.0,这个版本的_delay_ms()会判断是否超出延时极限(也就是_delay_loop_2(65535)),如果超出了就再定义一层循环,这样在1MHz时钟频率时最长可延时6.5535秒,也就是65535个0.1ms,_delay_ms(),是根据F_CPU进行过计算了的,只要正确定义F_CPU一般就能正确工作,而若要用_delay_loop_2()就要自己计算了。下面是AVR Studio 6.0 里_delay_ms()的定义:
void
_delay_ms(double __ms)
{
uint16_t __ticks;
double __tmp ;
#if __HAS_DELAY_CYCLES && defined(__OPTIMIZE__) && \
!defined(__DELAY_BACKWARD_COMPATIBLE__) && \
__STDC_HOSTED__
uint32_t __ticks_dc;
extern void __builtin_avr_delay_cycles(unsigned long);
__tmp = ((F_CPU) / 1e3) * __ms;
#if defined(__DELAY_ROUND_DOWN__)
__ticks_dc = (uint32_t)fabs(__tmp);
#elif defined(__DELAY_ROUND_CLOSEST__)
__ticks_dc = (uint32_t)(fabs(__tmp)+0.5);
#else
//round up by default
__ticks_dc = (uint32_t)(ceil(fabs(__tmp)));
#endif
__builtin_avr_delay_cycles(__ticks_dc);
#else
__tmp = ((F_CPU) / 4e3) * __ms;
if (__tmp 65535)
{
// __ticks = requested delay in 1/10 ms
__ticks = (uint16_t) (__ms * 10.0);
while(__ticks)
{
// wait 1/10 ms
_delay_loop_2(((F_CPU) / 4e3) / 10);
__ticks --;
}
return;
}
else
__ticks = (uint16_t)__tmp;
_delay_loop_2(__ticks);
#endif
}

温馨提示:答案为网友推荐,仅供参考
第1个回答  2012-08-19
延时的时候 尽量不要在_delay_ms里面写1000 那样就不准了 一般200比较准 用for 多加几个试试吧
第2个回答  2012-08-15
看看函数去- -,给函数呀原型- -
相似回答