• slider image 442
  • slider image 483
  • slider image 484
  • slider image 485
  • slider image 486
  • slider image 487
:::


Browsing this Thread:   1 Anonymous Users






Re: 如何寫一個 delay_us() function?
#8
版主
版主


查看用戶資訊
有些 C 的 Delay 函數是以時間為單位,如 Hi-Tech PICC,這種方式要先定義其 Oscillator Frequency 後才會準確。 C18 則是以 Instruction Cycle (Tcy) 為 Delay 單位,只要將Osc. Frequency 除以四後就可以知道Tcy 的時間。
當然Tcy 跟時間各有各的方便性,只要使用的當都是一樣的。如果要以時間為 delay 單位的話在 c18 就只有自己寫其 delay 函數了。

發表於: 2010/1/8 13:28
Twitter Facebook Google Plus Linkedin Del.icio.us Digg Reddit Mr. Wong 頂部


Re: 如何寫一個 delay_us() function?
#7
資深會員
資深會員


查看用戶資訊
依 Ryang 的建議,我參考 C:\MCC18\src\traditional\delays\d10tcyx.asm 已經改出了一個 delayus() function. 如前封信的內容。

Ryang, foxjan, thanks for your help.

C18 Library 有提供 delay functions, 例如 Delay1TCY(), Delay10TCYx(), Delay100TCYx() ...,不過這些 delay functions 都是以 instruction cycles 為單位。我有點好奇,為什麼 C18 Library 沒有提供以時間為單位的 delay functions 呢? 如果有 delay_ms(), delay_us() 這兩個 functions 的話,應該會帶給使用者很大的方便。

PS: 我在網路上查詢,發現 CCS C Compiler 好像有提供 delay_ms(), delay_us() functions.

發表於: 2010/1/8 11:48
Twitter Facebook Google Plus Linkedin Del.icio.us Digg Reddit Mr. Wong 頂部


Re: 如何寫一個 delay_us() function?
#6
資深會員
資深會員


查看用戶資訊
參照:

coopermaa 寫道:
Hi,

我在寫一支程式,想要增加兩個 delay functions: 一個用來 delay miliseconds,另一個用來 delay microsecods,延遲時間皆由傳進來的參數決定。底下是我寫出來的版本,目前遇到一個困難,delay() 誤差還算在可接受的範圍,但 delayus() 因為本身 loop 執行就要一些時間,會造成誤差,實際量測,delayus(1) = 3.58us,delayus(2) = 4.75us... 請問 delay microseconds 要怎麼寫才會比較精準呢? 我用的是 C18 and PIC18F4550。

// Delay in 1 ms (approximately) for 48 MHz Internal Clock
void delay(unsigned int ms)
{
  do {
    
Delay1KTCYx(12);
  } while(--
ms);
}

// Delay in 1 us (approximately) for 48 MHz Internal Clock
// well, it's not accurate!!
void delayus(unsigned int us)
{
  while (
us--);
}


1.請先算出1個指令時間多長(因為指令執行時間是由OSC除頻來的)

2.請在副程式段使用組語編譯,這樣要延遲幾個指令時間可以精準算出來,如果要很精準請連呼叫前後的指令時間一併計算

3.要看出TATAL 跑了那些指令 可以在BUILD之後點出VIEW的DISASSEMBLY LISTING 選項,這樣跑了那些指令 你會一目了然

4.c的好處是你前端給需求,他後面都幫妳做好,但是菜怎麼出來的,不知道,組語的壞處是一個蘿蔔一個坑,好處是做了什麼,心裡有"數"

發表於: 2010/1/8 9:58
Twitter Facebook Google Plus Linkedin Del.icio.us Digg Reddit Mr. Wong 頂部


Re: 如何寫一個 delay_us() function?
#5
資深會員
資深會員


查看用戶資訊
哈,直接拿 C:\MCC18\src\traditional\delays\d10tcyx.asm 來改,多加了幾行 NOP,然後變成一個 delayus function for 4550 (48MHz),雖然很笨,不過有效 ^o^

DELAYUSCODE CODE

delayus
    nop   
// added by me
    
nop   // added by me
    
movlw   0xff
    movf    PLUSW1
,0
    dcfsnz  WREG
,1
    
return

D10x
    nop  
// added by me
    
nop  // added by me
    
nop
    bra     
$+2
    bra     
$+2
    bra     
$+2
D10_1
    decfsz  WREG
,1
    bra     D10x
    
return

    GLOBAL  
delayus
    END

發表於: 2010/1/6 20:57
Twitter Facebook Google Plus Linkedin Del.icio.us Digg Reddit Mr. Wong 頂部


Re: 如何寫一個 delay_us() function?
#4
版主
版主


查看用戶資訊
C18 有提供一些 Delay 函數但都是用組語寫的,參考一下C:\MCC18\src\traditional\delays 裡的 Source Code。

delayus(1); // delay 1 microsecond 用 while 迴圈做,似乎太長了。可以考慮用 In-Line Assembly + C 的方式來完成。

發表於: 2010/1/6 17:28
Twitter Facebook Google Plus Linkedin Del.icio.us Digg Reddit Mr. Wong 頂部


Re: 如何寫一個 delay_us() function?
#3
資深會員
資深會員


查看用戶資訊
Hi Ryang,

Thanks for your reply.

Sorry, 可能我表達的不清楚,讓您誤會了。我並不是要測量程式執行的時間。我的疑問是要怎麼寫一個 delayus() function,可以讓我這樣使用:

delayus(1);   // delay 1 microsecond
delayus(2);   // delay 2 microseconds
delayus(500); // delay 500 microseconds

如下,我是簡單寫成一個迴圈,但是用 SIM 測量發現迴圈佔用太多指令週期,delayus() 很不準確:

// Delay in 1 us (approximately) for 48 MHz Internal Clock
// well, it's not accurate!!
void delayus(unsigned int us)
{
  while (
us--);
}


還是說得用 assembly 改寫 delayus() ?

發表於: 2010/1/6 17:02
Twitter Facebook Google Plus Linkedin Del.icio.us Digg Reddit Mr. Wong 頂部


Re: 如何寫一個 delay_us() function?
#2
版主
版主


查看用戶資訊
用 MPALB SIM 軟體模擬測量程式執行的時間最準,準到毫秒不差(理想狀態)。作法是: Debug Mode 選 MPLAB SIM 後再選 Setting 中的 OSC 設成你所使用的頻率後,用 Stopwatch 配合斷點的設定及按Mouse 右鍵選 Set Course to Here 後量一下程式的執行時間就可以知道了。

發表於: 2010/1/6 16:10
Twitter Facebook Google Plus Linkedin Del.icio.us Digg Reddit Mr. Wong 頂部


如何寫一個 delay_us() function?
#1
資深會員
資深會員


查看用戶資訊
Hi,

我在寫一支程式,想要增加兩個 delay functions: 一個用來 delay miliseconds,另一個用來 delay microsecods,延遲時間皆由傳進來的參數決定。底下是我寫出來的版本,目前遇到一個困難,delay() 誤差還算在可接受的範圍,但 delayus() 因為本身 loop 執行就要一些時間,會造成誤差,實際量測,delayus(1) = 3.58us,delayus(2) = 4.75us... 請問 delay microseconds 要怎麼寫才會比較精準呢? 我用的是 C18 and PIC18F4550。

// Delay in 1 ms (approximately) for 48 MHz Internal Clock
void delay(unsigned int ms)
{
  do {
    
Delay1KTCYx(12);
  } while(--
ms);
}

// Delay in 1 us (approximately) for 48 MHz Internal Clock
// well, it's not accurate!!
void delayus(unsigned int us)
{
  while (
us--);
}

發表於: 2010/1/6 14:40
Twitter Facebook Google Plus Linkedin Del.icio.us Digg Reddit Mr. Wong 頂部







You can view topic.
不可以 發起新主題
You cannot reply to posts.
You cannot edit your posts.
You cannot delete your posts.
You cannot add new polls.
You cannot vote in polls.
You cannot attach files to posts.
You cannot post without approval.
You cannot use topic type.
You cannot use HTML syntax.
You cannot use signature.
You cannot create PDF files.
You cannot get print page.

[進階搜尋]


:::

Microchip連結

https://www.facebook.com/microchiptechnologytaiwan/
http://www.microchip.com.tw/modules/tad_uploader/index.php?of_cat_sn=13
https://mu.microchip.com/page/tmu
http://elearning.microchip.com.tw/modules/tad_link/index.php?cate_sn=1
https://page.microchip.com/APAC-PrefCenters-TW.html
http://www.microchip.com/
http://www.microchip.com/treelink
http://www.microchipdirect.com/
http://www.microchip.com.cn/newcommunity/index.php?m=Video&a=index&id=103
http://www.microchip.com.tw/modules/tad_uploader/index.php?of_cat_sn=2
http://www.microchip.com.tw/Data_CD/eLearning/index.html
http://www.microchip.com.tw/RTC/RTC_DVD/
https://www.microchip.com/development-tools/
https://www.youtube.com/user/MicrochipTechnology
[ more... ]

教育訓練中心

!開發工具購買
辦法說明 [業界客戶] [教育單位]
----------------------------------
!校園樣品申請
辦法說明 [教師資格] [學生資格]
----------------------------------