新唐單片機如何生成精確延遲
最近在搞新唐單片機,所以記錄下這部分內(nèi)容。
之前的相關(guān)文章
假如使用者想要產(chǎn)生精確的延遲時間,建議使用 __nop() 函數(shù)來組合達成。__nop() 函數(shù)能夠產(chǎn)生 1 個精確的 CPU 頻率周期延遲時間。然而,由于 flash 的速度低于 CPU 的頻率速度,在 CPU 內(nèi)部有快取優(yōu)化的技術(shù),編譯程序也會自動針對程序做優(yōu)化,造成__nop() 函數(shù)組合出來的時間會與預(yù)期的時間不同。因此,建議將程序代碼放置于 SRAM 中執(zhí)行,以避免優(yōu)化造成的非預(yù)期延遲時間問題。
?
以產(chǎn)生 2 us 的延遲時間為例:
(1) CPU 頻率= 32MHz => 1 CPU 頻率周期花費 1/32000000 sec = 31.25 ns
(2) 2 us 延遲時間 = 2000 ns / 31.25 ns = 64 次 CPU 頻率周期
?
1. 于KEIL的項目中加入一個新的.c文件
2. 將文件位置指定至SRAM


3. 設(shè)定 Linker

4. 編寫延遲程序代碼
?
由于執(zhí)行一次 for 循環(huán)需要花費 5 個 CPU 頻率周期的時間,因此可以使用以下的方式達到 2 us 的時間延遲
?
(1) 執(zhí)行一次 for 循環(huán)需要 5 個 CPU 頻率周期
(2) 執(zhí)行一次 __NOP() 指令需要 1 個 CPU 頻率周期
(3) 64 個 CPU 頻率周期 = 8 ( 5 ( for 循環(huán) ) + 3 * 1 ( __NOP() ) )
?
void?Delay_Test_Function(void)
{
????for(i?=?0;?i?<8;?i?++)/?*延遲2微秒。*?/
????{
????????__NOP();
????????__NOP();
????????__NOP();
????}
}
?
5. 測試
使用者可以利用下列程序代碼進行延遲時間的測試,透過示波器量測 I/O toggle 的時間,以觀察延遲函數(shù)是否精準。由于 CPU 需要下指令讓 I/O 轉(zhuǎn)態(tài),因此觀察到的時間中需要增加轉(zhuǎn)態(tài)的指令時間 (PA0 = 0)。
?
執(zhí)行一次 PA = 0 需花費 11 CPU 指令周期,這意味著 I/O 會持續(xù) (64+11) * 31.25 ns = 2343.75 ns 的時間才進行轉(zhuǎn)態(tài)。
?
void?Delay_Test_Function(void)
{
????uint32_t?i,DelayCNTofCPUClock?=?8;
????PA0?=?1;
????for(i?=?0;?i?2微秒。*?/
????{
????????__NOP();
????????__NOP();
????????__NOP();
????}
????PA0?=?0;
}
?


