Re: [問題] 89S51 使用 C51 計時問題

看板ASM作者 (800IM)時間10年前 (2014/06/08 05:55), 10年前編輯推噓0(000)
留言0則, 0人參與, 最新討論串3/3 (看更多)
※ 引述《a45601236qq (Ming)》之銘言: : C_CPP 板問 51 相關問題的人好像比較少,所以就來這邊借問了... : 今天試著做一下模擬 ms 計算的(高階語言 sleep 都喜歡以 1ms * n 為單位) : 試著計時 60 秒後,發現每分鐘都會誤差五秒鐘(感覺有點大) 60秒誤差一秒都嫌太大 : 想請大家幫忙看一下是否有問題... : 感謝<_ _) : #include <AT89X51.h> : int Timer1Ms = 0; //1ms * n : int Timer1Value = 0; 時脈沒寫, 那我就假設最一般的case, 輸入給timer的週期 = 1us : void main() : { : TMOD = 0x10; //7-2 tmod : TL0 = ( 8192 - 5000 ) % 32; : TH0 = ( 8192 - 5000 ) / 32; : TL1 = ( 65536 - 1000 ) % 256; : TH1 = ( 65536 - 1000 ) / 256; 這裡看起來是因為要以 ms 為單位, 需要計數超過 256 所以用 mode1, 但是中斷要去 reload 就影響計時準確度, 我的作法是改用 mode2, 數到 200個pulse*1us=200us, 在中斷累積50次overflow時, 秒數++ : Timer1Value = 60000; : Timer1Ms = Timer1Value; : //TR0 = 1; : TR1 = 1; : EA = 1; ET0 = 1; ET1 = 1; //6-3 IE : while (1) ; : } : void timer1_isr() interrupt 3 : { : TL1 = ( 65536 - 1000 ) % 256; : TH1 = ( 65536 - 1000 ) / 256; 如果這邊硬是要用mode1, 那也有一些作法可以提高計時準確性 1. 在 main 就先算出 TH1 TL1 的常數值(也許compiler已經幫你做) 2. reload 前先TR1=0,reload後TR1=1, 因為只要 TR1==1 的情況下 reload 過程中 Timer1 依然在計數, TH1 TL1 依然在累加,沒停過 : Timer1Ms -= 1; 3.如果 main 沒有在跑 UART 或 LCD 什麼的跑得夠快的話, 以下這幾行可以留到main去做 : if (Timer1Ms == 0) : { : Timer1Ms = Timer1Value; : P1_2 = ~(P1_2); : } : } -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.122.165.185 ※ 文章網址: http://www.ptt.cc/bbs/ASM/M.1402178106.A.FE0.html ※ 編輯: deo2000 (140.122.165.185), 06/08/2014 05:57:39
文章代碼(AID): #1Jauew_W (ASM)
文章代碼(AID): #1Jauew_W (ASM)