![]() |
發布時間: 2022-12-19 10:28
正文摘要:需要做一個一秒鐘的倒計時功能,可以設一個1ms定時器,循環1000次,也可以設一個50ms定時器,循環20次。請問哪種時間比較準確?兩種方法系統開銷有差別嗎?(因為還有很多其他功能,循環次數多會影響其他功能運行嗎 ... |
新鄉家電維修 發表于 2023-1-21 13:19 定時器0軟件重裝控制電機調速,定時器1軟件重裝控制液體體積倒數,定時器3自動重裝掃描ec11,按鍵和產生500ms和1秒時基信號。3個定時器全用完了。 |
使用定時器,自動重裝模式不會引入誤差,時間精度跟晶振一致,你用一個0.01ppm的恒溫晶振,年誤差不超過0.3秒,我就做有這么一個。 |
新鄉家電維修 發表于 2023-1-21 13:19 確定了,定時器最后用的是2ms時長。中斷里3個標志位,1個2ms掃描EC11,1個500ms閃動數碼管,1個1s給倒計時。 |
定時器中斷定1秒必須設為自動重裝初值模式,手動重裝誤差大,有多個中斷應設為高優先級。 |
你要是會點單片機知識就不會問了,延時是最基層的入門程序。你不會告訴你也不會用 |
單從對別的函數的影響來考慮的話,當然是中斷的次數越少越好。 |
通常都是有誤差的,可以在循環里放一個IO口的Toggle 語句,然后用示波器看端口輸出方波波長,然后調整語句就能準確了 |
188610329 發表于 2022-12-20 14:14 謝謝前輩指導!我試一下。 |
ningsy 發表于 2022-12-20 10:59 STC8G 的 定時器2 有 8位預分頻(TM2PS) 寄存器,你可以直接 64分頻后,直接得到1秒的 定時時間。以你現有的例子為例: void Timer2Init(void) //1秒@11.0592MHz { AUXR &= 0xFB; //定時器時鐘12T模式 P_SW2 |= 0x80; TM2PS = 63; //64分頻 T2L = 0xC0; //設置定時初始值 65536-1440 T2H = 0xC7; //設置定時初始值 AUXR |= 0x10; //定時器2開始計時 } |
看你對準的要求怎樣 |
跟你循環多少次其實沒多大關系,準不準看晶振,一般外部晶振可以達到0.001的誤差,內部晶振1%-3%的誤差。想要看看精確度,最好看看芯片手冊 |
定時器工作于自動重裝方式,1ms或50ms,精度一樣,取決于晶振的精度。 |
188610329 發表于 2022-12-20 10:22 現在用的是STC8G1K08(兼容STC8H1K08),定時器2,50ms 12T自動重載,STC-ISP定時器計算器的代碼。用山寨邏輯分析儀測試1S方波脈寬,每次測還不一樣,有時候準的很,多數時候要慢零點幾毫秒。可能IRC頻率自動調整誤差也有影響。 您說的“分頻計數器”是什么呢?我這個項目代碼空間快不夠了,還想用USB來升級,未來準備改成STC8H8K64U,能直接產生1秒時基嗎? void Timer2Init(void) //50毫秒@11.0592MHz { AUXR &= 0xFB; //定時器時鐘12T模式 T2L = 0x00; //設置定時初始值 T2H = 0x4C; //設置定時初始值 AUXR |= 0x10; //定時器2開始計時 } |
如果,一上來就是奔著1秒去的,如果用的是沒有重載功能89c51這種片子,則兩種都不好。 應該按,第一次跑余,后面都跑滿65536來設計。 如是帶自動重載的定時器,則50ms較好。如果是帶分頻計數器這種,應直接定1秒。總之應根據使用的單片機來做合理設置。 |
其它功能盡量不要寫到中斷程序里,不然會有誤差 |
準確與否,看給定時器的值準不準,比如65536-11059200/12*50/1000=19456,這樣定時50ms,結果是個整數。如果定時1ms,那么在計算11059200/12*1/1000=921.6,會有小數,這樣就會有精度損失。 |
設一個單片機工作于12M晶體震蕩器,它的時鐘周期是1/12(微秒)。它的一個機器周期是12*(1/12)也就是1微秒。所以設置1s定時,無論怎么設置定時器、怎么循環,理論上運行的機器周期是一樣的,即總循環次數是一樣的。 |
定時器誤差受程序其他部分影響不小,合理的程序才能保證秒鐘的準確. |