久一网络科技

久一网络科技是您快速建站的首选,我们提供快速高效的服务:快速建站,服务器运维,整站建设,网络编程,网络安全等。持久的品质保证,始终如一的服务理念,久一网络科技-----您身边的网络专家。 如有需求,请联系:tech@jooyee.net

在WinAVR中,有一个delay.h文件,里面包含了_delay_us和_delay_ms两个函数,分别可以延时微秒和毫秒时间。看下面一个例子:


#include <avr/io.h>
#include <util/delay.h>

unsigned char t = 10;

int main()
{
while(1)
{
_delay_ms(10);
}

return 0;
}

编译后,程序空间占用为:

AVR Memory Usage
----------------
Device: atmega168

Program: 180 bytes (1.1% Full)
(.text + .data + .bootloader)

Data: 2 bytes (0.2% Full)
(.data + .bss + .noinit)


Build succeeded with 0 Warnings...


如果将上面程序稍作修改:


#include <avr/io.h>
#include <util/delay.h>

unsigned char t = 10;

int main()
{
while(1)
{
_delay_ms(t);
}

return 0;
}


Device: atmega168

Program: 3844 bytes (23.5% Full)
(.text + .data + .bootloader)

Data: 266 bytes (26.0% Full)
(.data + .bss + .noinit)

Build succeeded with 0 Warnings...

发现RAM和ROM的占用突然就急剧增加了。这是为什么呢?从程序直接看,没有什么问题。打开delay.h文件,我们发现有一段说明:

In order for these functions to work as intended, compiler optimizations must be enabled, and the delay time must be an expression that is a known constant at compile-time. If these requirements are not met, the resulting delay will be much longer (and basically unpredictable), and applications that otherwise do not use floating-point calculations will experience severe code bloat by the floating-point library routines linked into the application.

上面这段话说明delay函数需要使用常数作为延时的参数,否则延时的结果可能会很长(不可预知),同时会因为链接了浮点库到程序,所以程序大小会急剧膨胀。


参考文献:
http://blog.ednchina.com/shaoziyang/139750/message.aspx
继续阅读...

在WINAVR中,可以自己编写延时程序,也可以直接调用WINAVR自带的delay函数。

在调用WINAVR自带的delay函数时,有时我们想延时1秒钟时,直接写_delay_ms(1000);

可是,最后结果却不对,延时不到1秒,为什么呢?下面就来解释一下这个现象:

delay.h文件位于X:\WinAVR\avr\include\avr中。

delay.h中有两个函数--------_delay_ms(double __ms)和_delay_us(double __us),分别延时__ms*F_CPU毫秒、__us*F_CPU微秒,(单片机晶振是F_CPU MHZ)两函数的原型分别如下:

1、_delay_us(double __us)

static __inline__ void
_delay_us(double __us)
{
uint8_t __ticks;
double __tmp = ((F_CPU) / 3e6) * __us;
if (__tmp < 1.0)
__ticks = 1;
else if (__tmp > 255)
__ticks = 0; /* i.e. 256 */
else
__ticks = (uint8_t)__tmp;
_delay_loop_1(__ticks);
}

其中,该函数延时的最大时间是768/F_CPU微秒。

2、_delay_ms(double __ms)

static __inline__ void
_delay_ms(double __ms)
{
uint16_t __ticks;
double __tmp = ((F_CPU) / 4e3) * __ms;
if (__tmp < 1.0)
__ticks = 1;
else if (__tmp > 65535)
__ticks = 0; /* i.e. 65536 */
else
__ticks = (uint16_t)__tmp;
_delay_loop_2(__ticks);
}

其中,该函数延时的最大时间是262.14/F_CPU毫秒。

现在明白上面为什么不行了吧!

具体函数代码,大家可以直接到delay.h里看看。还有,以后大家在写程序时,用到编译软件自带的函数时,都可以直接到源文件里看看,以后自己也学着写一些供调用的函数或头文件,这对提高编程水平很有帮助的!


参考文献:
http://www.avrtool.com/avr/gccavr/200808/1312.html
继续阅读...

GCC中delay_ms,delay_us延时函数在不同工作频(常用)下的最大值如下:
_delay_ms(double __ms)
The maximal possible delay is 262.14 ms / F_CPU in MHz.
工作频率 最大延时值(ms)
20M 13ms
16M 16ms
12M 21ms
11.0592M 23ms
8M 32ms
7.3728M 35ms
4M 65ms
2M 131ms
1M 262ms
_delay_us(double __us)
The maximal possible delay is 768 us / F_CPU in MHz.
工作频率 最大延时值(us)
20M 38us
16M 48us
12M 64us
11.0592M 69us
8M 96us
7.3728M 104us
4M 192us
2M 384us
1M 768us

转自OURAVR论坛:

http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=936084&bbs_page_no=1&bbs_id=1000
继续阅读...

关注者

热门帖子

网页浏览总次数