Re: 時鐘問題
|
||||
---|---|---|---|---|
初級會員
|
版主的這個方法粉好,我用 PIC16F877A 的試了一次,用 SIM
TEST , 哇 ! 真準 GREAT!
發表於: 2005/12/8 23:57
|
|||
|
Re: 時鐘問題
|
||||
---|---|---|---|---|
資深會員
|
;4MHZ TMR1預除1
;使用預除2/4/8 有可能產生 1/62500~2/62500的誤差 16~32PPM INT_TMR1: BCF PIR1,TMR1IF MOVLW 0XDC ADDWF TMR1L,F MOVLW 0X0B SKPNC MOVLW 0X0C ADDWF TMR1H,F ;62500CYCLE 中斷一次 ;中斷16次即一秒
發表於: 2004/8/19 11:10
|
|||
|
Re: 時鐘問題
|
||||
---|---|---|---|---|
版主
|
就我所知,一般crystal的精度大約是50ppm。也就是說,程式寫得正確的話,一天誤差最多86400 * 50 /1000000 秒 ~ 4.32秒。
注意一點,就我的經驗,發現,crystal外殼要接地,否則,用手摸一下,頻率就跑掉了。 最近幾天,回問題時都快下班了,所以,偷懶了一些。希望順水推舟,讓提問題者自行找出解答。一定收穫、體認更大。 過兩天比較有空。 再提示: 仔細看一下timer 1的用法,也許要注意pre-scaller。
發表於: 2004/8/18 18:35
|
|||
|
Re: 時鐘問題
|
||||
---|---|---|---|---|
中級會員
|
謝謝大家的指導!
因我程式的時鐘是必須長年累月的計時而定時去驅動系統定時使用故精度要求較高因我crystal 是電子街買的故精度不知!如各位所言我將再行測試!
發表於: 2004/8/18 17:28
|
|||
|
Re: 時鐘問題
|
||||
---|---|---|---|---|
高級會員
|
哇靠...一分鐘?
這應該是軟體的問題吧!!! 我想應該仔細的研究一下C COMPILER到底組譯出何種組合語言一般而言如果用組合語言來寫必須計算指令週期在取OFFSET量 我寫的程式是一個電毯的案子我沒有特別去設定震盪器頻率都是使用4mhz石英震盪計時三天才差個幾秒客人就在那裡幹敲了 他們還拿CASIO碼表做驗證哩 我勸你這一段time counter最好用組合語言 然後注意你的其他interrupt盡量只設旗標就好,處理程序在MAIN LOOP做,因為你想如果timer interrupt又來一個int0或者其他的interrupt將time interrupt mark那又差了好幾的us甚至ms一個小時下來喔喔就有一分鐘了
發表於: 2004/8/18 17:12
|
|||
|
Re: 時鐘問題
|
||||
---|---|---|---|---|
高級會員
|
哇靠...一分鐘?
這應該是軟體的問題吧!!! 我想應該仔細的研究一下C COMPILER到底組譯出何種組合語言一般而言如果用組合語言來寫必須計算指令週期在取OFFSET量 我寫的程式是一個電毯的案子我沒有特別去設定震盪器頻率都是使用4mhz石英震盪計時三天才差個幾秒客人就在那裡幹敲了 他們還拿CASIO碼表做驗證哩 我勸你這一段time counter最好用組合語言 然後注意你的其他interrupt盡量只設旗標就好,處理程序在MAIN LOOP做,因為你想如果timer interrupt又來一個int0或者其他的interrupt將time interrupt mark那又差了好幾的us甚至ms一個小時下來喔喔就有一分鐘了
發表於: 2004/8/18 17:10
|
|||
|
Re: 時鐘問題
|
||||
---|---|---|---|---|
資深會員
|
哇勒勒~~
還3個提示呢 呵呵 minusone 板主 你偵探學員Q看粉多喔
發表於: 2004/8/18 11:52
|
|||
|
Re: 時鐘問題
|
||||
---|---|---|---|---|
版主
|
還有一個問題? 你說用4MHz (16F877用20MHZ)確定振盪頻率是否在20PPM誤差以內呢? 計時的部分是用軟體計數(那問題就大了)還是用硬體的計時器計數呢?
如果是用軟體計數方式,保證你會被其它的硬體中斷程式打亂時間保證不準的啦!
發表於: 2004/8/18 9:51
|
|||
|
Re: 時鐘問題
|
||||
---|---|---|---|---|
版主
|
既然使用PIC18F452那就簡單了,這裡有一個馬兒會跑又不太需要吃草的方法大家討論一下:
1. PIC18F452主振盪器使用 RC Mode (4-8MHz隨你便),Timer1接一個32.768KHz的Crystal; 利用 Timer1 的中斷來做為 Real Time Clock的來源。這樣程式就可以跑高速,又可以精確計時。 不過這種方式也會有些許誤差(中斷發生時至載入新的Timer1計數值的時間差) ; 但如果用Timer2的auto reload功能誤差就會非常非常低。 #define Timer_Count 32768 //************************************************ //* Function: InitializeTimer1 * //************************************************ void InitializeTMR1(void) { T1CON=0b10001111; // Initialize Timer1 for using External 32.768KHz IPR1bits.TMR1IP=0; // Set Timer1 for Low Priority Interrupt PIR1bits.TMR1IF=0; // Clear Interrupt flag of Timer 1 TMR1H = (0xFFFF-Timer_Count)/256; TMR1L = (0xFFFF-Timer_Count)%256; // Set for 1 Second Interrupt Time PIE1bits.TMR1IE=1; // Enable Timer1 Interrupt } //************************************************ //* Function: isr_low_direct * //* - Direct execution to the actual * //* low-priority interrupt code. * //************************************************ #pragma code isrlowcode = 0x0018 void isr_low_direct(void) { _asm //begin in-line assembly goto isr_low //go to isr_high function _endasm //end in-line assembly } #pragma code //************************************************ //* Function: isr_low(void) * //* - Timer 1 Interrupt for the 1 Second Delay * //* for send the ON BUS polling * //************************************************ #pragma interruptlow isr_low void isr_low(void) { if (PIR1bits.TMR1IF) { TMR1H = (0xFFFF-Timer_Count)/256; TMR1L = (0xFFFF-Timer_Count)%256; // Reload 1 Second value to Timer1 PIR1bits.TMR1IF=0; // Clear interrupt flag of Timer 1 : : } }
發表於: 2004/8/18 9:41
|
|||
|