avr-gcc中關(guān)于delay延時函數(shù)的應(yīng)用
#i nclude
就可以使用了。這個頭文件定義了兩個級別的延時函數(shù)分別是:
; 在51中我們的延時函數(shù)都是自己編寫的void _delay_us (double __us) ; //微秒級
void _delay_ms (double __ms); //毫秒級
void _delay_ms (double __ms);
sp;
不過不可以高興的太早,因?yàn)橐谀愕腶vr-gcc中正確使用它們是有條件的,下面我將慢慢道來。
這個參數(shù)和 Makefile 中的 F_CPU 值有關(guān),Makefile 所定義的的F_CPU 變量的值會傳遞給編譯器。你如果用AVR_studio 4.1X來編輯和調(diào)試,用內(nèi)嵌AVR-GCC的進(jìn)行編譯,并且讓AVR_studio 幫你自動生成Makefile 的話,那你可以在:
,無論是在匯編中還是在C言語中。雖然有模寫下你的F_CPU的值,F(xiàn)_CPU這個值表示你的AVR單片機(jī)的工作頻率。單位是 Hz ,不是 MHZ,不要寫錯。如 7.3728M 則 F_CPU = 7372800 。
你會發(fā)現(xiàn)在"delay.h" 頭文件中有這個樣的一個定義如下:
#ifndef F_CPU; 在51中我們的延時函數(shù)都是自己編寫的
# warning "F_CPU not defined for"
# define F_CPU 1000000UL // 1MHz
#endif
板,有時還是有點(diǎn)煩。呵呵。不過在應(yīng)用av# warning "F_CPU not defined for
# define F_CPU 1000000UL
#endif
這是為了在你沒有定義F_CPU這個變量(包括空),或是AVR_studio Frequency沒有給值的時候,提供一個默認(rèn)的 1MHz頻率值。讓編譯器編譯時不至于出錯。
sp;
下面是這兩個函數(shù)的實(shí)體:
void _delay_us(double __us) // 微秒
{; 在51中我們的延時函數(shù)都是自己編寫的
uint8_t __ticks;
double __tmp = ((F_CPU) / 3e6) * __us; // 3e6 是因?yàn)檎{(diào)用的_delay_loop_1()是三條指令的
if (__tmp < 1.0) &nb
__ticks = 1;
else if (__tmp > 255)
__ticks = 0;; 在51中我們的延時函數(shù)都是自己編寫的
else
__ticks = (uint8_t)__tmp;
_delay_loop_1(__ticks);,無論是在匯編中還是在C言語中。雖然有模
}
{; 在51中我們的延時函數(shù)都是自己編寫的
uint8_t __ticks;
double __tmp = ((F_CPU) / 3e6) * __us;
if (__tmp < 1.0)
else if (__tmp > 255)
else
_delay_loop_1(__ticks);,無論是在匯編中還是在C言語中。雖然有模
}
void _delay_ms(double __ms)
{
uint16_t __ticks;
double __tmp = ((F_CPU) / 4e3) * __ms; // 4e3 是因?yàn)檎{(diào)用的_delay_loop_2()是四條指令的
if (__tmp < 1.0)
else if (__tmp > 65535)
else; 在51中我們的延時函數(shù)都是自己編寫的
_delay_loop_2(__ticks);
}
你會發(fā)現(xiàn)他們都分別調(diào)用了 _delay_loop_1(); 和_delay_loop_2(); 這兩個函數(shù)
而這兩個函數(shù)又如下所示:
void _delay_loop_1(uint8_t __count)板,有時還是有點(diǎn)煩。呵呵。不過在應(yīng)用av
{
__asm__ volatile (
"1: dec %0" "",無論是在匯編中還是在C言語中。雖然有模
"brne 1b"
: "=r" (__count)
: "0" (__count)sp;
);
}
{
__asm__ volatile (
);
}
void _delay_loop_2(uint16_t __count),無論是在匯編中還是在C言語中。雖然有模
{
__asm__ volatile (
"1: sbiw %0,1" "" &nb
"brne 1b"
: "=w" (__count)
: "0" (__count)sp;
);
}
{
__asm__ volatile (
);
}
板,有時還是有點(diǎn)煩。呵呵。不過在應(yīng)用av
這兩個函數(shù)都是avr-gcc 的 inline匯編格式寫的,具體的語法規(guī)則我就不多說了??梢詤⒖糰vr-libc。不過這兩個函數(shù)很簡單,很容易明白。一個是字節(jié)遞減,一個是字遞減。如果你認(rèn)真看上面幾個函數(shù),你就會發(fā)現(xiàn)要正確使用它們是有如下條件的:
sp;
對于第4條范圍,來個例子:
sp;
只有具備了上面的條件你才可以正確使用延時函數(shù) _delay_us () 和 _delay_ms () 。對于第三個條件,為什么要選用常量,還有第二個條件為什么要打開優(yōu)化選項(xiàng)。這是為了讓編譯器在編譯的時候就把延時的值計算好,而不是把它編譯到程序中,在運(yùn)行時才進(jìn)行計算,那樣的話,一是會增加代碼的長度,還會使你的延時程序的延時時間加長,或是變得不可預(yù)料。產(chǎn)生時序的錯誤。
發(fā)現(xiàn)一寫就寫了兩個多小時,看起來不長。看來說出來很容易,寫下來還是要費(fèi)點(diǎn)工夫的,希望對你的有所幫助。呵呵。分享快樂,共同進(jìn)步。
評論