16F685無法校準TMR1問題(續)
|
||||
---|---|---|---|---|
資深會員
|
這是接續之前一篇關於無法校準的問題,只是似乎被視為討論已完,所以還是再開另一篇來問。
前情提要,如要修正TMR1計時偏差問題,除了不能直接覆寫TMR1H和TMR1L,還要先將TMR1關掉才可以進行TMR1計數器修改的程序,並加上TMR1關掉期間所帶來的額外延遲的補正部分,即每隔一定數量的中斷後,當額外的延遲累積到大約30.5us後(32768Hz振盪一次計數的時間),會在TMR1L額外加1以補回時差,然後新的問題來了。 我分別在一個20MHz和三個8MHz的程式上跑,連續跑24小時後收集結果。結果出來是20MHz的比對照時間快了2秒,而8MHz的三個分別慢了15、19和20秒。 本來一直想不到原因為何,直到看到datasheet上這個(請看附圖)。 因為有其他Timer的中斷的關係,所以ISR抓到TMR1中斷的時機並不是每次都一樣。按照圖片,如果TMR1重新啟動後,T1CKI是在HIGH的時候,那麼最快可以在15.25us後TMR1會增加一次;但如果T1CKI是在LOW的時候,那麼最差情況是要在45.75us後TMR1才會加一次。我相信就是這部分的誤差造成這個難以修正的延遲。而且從8MHz的程式的結果看,應該是大部分情況下TMR1重啟時T1CKI都是在LOW,只是踩在LOW的時機都不一樣。 然後,T1CKI腳位的狀態是無法讀取的(總是讀為0),即是不能夠透過讀取腳位來判斷。 PIC16F631/677/685/687/689/690第84頁、第6.4節: 參照: TRISA5 and TRISA4 bits are set when the Timer1 oscillator is enabled. RA5 and RA4 bits are read as '0' and TRISA5 and TRISA4 bits read as '1'. 我想了一個方法就是在啟動TMR1前先取得TMR1L的值在暫存,在啟動TMR1後等候30.5us,以TMR1L在這段時間後的值是否不同了來判斷是否需要額外計時補正,這不一定準但至少不會比現在的情況差。可是這樣特意等候30.5us好像很蠢也沒必要,要是有其他高頻率中斷這無疑是一個大妨礙,但已經想不到其他可以用來判斷的方法。
發表於: 2023/4/19 19:53
|
|||
|
Re: 16F685一直無法校準TMR1
|
||||
---|---|---|---|---|
資深會員
|
來點更新,因為問題似乎沒解決到...
不知道是否我整合的方式有什麼不對,不過我是按照你所提議的方式寫進去。 參照: 如果你要中斷特定時間, 我用的TMR1中斷頻率是16Hz,prescaler是1:1,在所有要做這修補的程式也是用這個頻率。 因為編譯器的一些問題所以有一部分要用C來寫,例如將數值加到當前的TMR1H和TMR1L的部分,用Assembly寫進去它在執行時會寫入0而不是需要的數值,程式的watchdog抓到它跑0.5Hz。用C寫這組指令它就會正常跑16Hz。 TMR1使用低功率外振時是每1/32768(0.000030517578125)秒,又或是大約30.5us就計數一次,這沒錯吧? 透過Debugger模擬新的程式碼在TMR1停止後到TMR1啟動時一共跑了13個指令的時間,所以另外按照不同系統執行速度按時補一次TMR1L的計數(incf TMR1L,1)的指令,20MHz的每13次中斷(2.6us x 13 = 33.8us)就補一次,而8MHz的是每5次中斷(6.5us x 5 = 32.5us)就補一次,以補償每次TMR1停止期間所累積的時差。補時的判斷式佔4個指令時間,已經計算進去上述的指令時間內。 我加設了T1LMKC這個變數,當中Bit 7是用來判斷是否要補時。每次發生中斷後T1LMKC就減1,直到向下溢位到255。
PIR1.TMR1IF=0;
變數T1LVAL在測試的所有情況時數值都是0,所以在TMR1L加T1LVAL後數值基本上不會有不同。但使用incf指令時有一個顧慮,就是它不影響STATUS.C,要是TMR1L在執行incf前已經是255(C的狀態是0),那麼這個溢位就不會被偵測到。 我在幾個不同的程式上跑,一個跑20MHz外置XTAL,三個跑8MHz(一個XTAL、兩個內置),跑一天後收集結果。 結果出來,20MHz的比對照時間快了2秒,8MHz的則全部都比對照的慢了15-20秒。如果以上面計算累積的延遲時差,理應全部都會比對照的慢,但20MHz的為什麼會越跑越快? 問題好像變得複雜了,但無法知道原因...
發表於: 2023/4/17 20:19
|
|||
|
Re: 16F685一直無法校準TMR1
|
||||
---|---|---|---|---|
資深會員
|
感謝你的建議,我會研究如何整合進去。
題外話 我使用的編譯器在產生hex檔時也會產生asm,所以有時會查看asm檔來計算某些特定的部分所需要的執行時間,以便改良源始碼。而且在撰寫程式時因為C本身有些限制,寫入某些指令是必須使用asm語法(編譯器支援的)。 最常用的例如CLRWDT和reset,這些在C沒有對應關鍵字,使用時就要這樣寫:
PIR1.TMR2IF=0; //C語言指令
如果是需要算準執行時間的部分,我就會以asm撰寫那些地方。
發表於: 2023/4/6 23:08
|
|||
|
Re: 16F685一直無法校準TMR1
|
||||
---|---|---|---|---|
資深會員
|
參照:
除非你都有沒其它『中斷源』了 你的意思是當有其他中斷來源時,即例如TMR0,在TMR0的中斷部分還在處理的時候,TMR1發生中斷但未能處理,到要處理TMR1的時候TMR1H和TMR1L已經跑了一段時間,重設它們造成額外延遲從而導致不準確的問題。我這樣的理解對不對? 那麼要如何改寫TMR1的中斷處理式來提升準確度?還望指教。
發表於: 2023/4/5 12:27
|
|||
|
Re: 16F685一直無法校準TMR1
|
||||
---|---|---|---|---|
資深會員
|
參照:
所以,真的很不準?還是你程式有bug而不自知? 同一組程式架構用在系統使用外振的MCU上,就沒有受溫度影響。 不過我還是仍在找問題在哪就是了。 參照: 就我的經驗,程式去修改 TMR1H,TMR1L ,不讓系統自己跳,有很大的機率會讓時間錯亂~~ 程式組只修改TMR1H和TMR1L的重設值,是另外使用兩個變數(T1HVAL和T1LVAL)進行,在每次TMR1發生中斷後,才會對TMR1H和TMR1L進行一次修改。
if(PIR1.TMR1IF){
發表於: 2023/3/31 18:39
|
|||
|
Re: 16F685一直無法校準TMR1
|
||||
---|---|---|---|---|
資深會員
|
TMR1已經是用外振,而且設定不會跟系統內振同步,也就是TMR1是完全跟據外振來發生中斷。
但為什麼還是會被系統內振影響到? 是否真的只有系統用外振(TMR1就要強制改內振)才可解決問題?
發表於: 2023/3/27 23:42
|
|||
|
16F685一直無法校準TMR1
|
||||
---|---|---|---|---|
資深會員
|
此問題圍繞去年8月我在另一篇貼文提到的16F685程式,其中TMR1的部分。
TMR1使用32768Hz外振來計時,因此系統只能用8MHz內振,然後就是問題所在了,就是程式翻新完成後的半年間,其計時一直無法校準。 我使用一個自己撰寫針對TMR1計時校準的程式組,以256秒為一個完整週期,校準方式為使用兩組8位元變數,各為計數器和校準值。 假設TMR1頻率是16Hz,那麼 TMR1H重設值=248 TMR1L重設值=0 1. CKBCLK以秒為單位由0跑到255再回到0,即每256秒等於一個週期 2. CKPCLK以TMR1發生中斷為單位,以16Hz就是由0跑到15再回到0,1秒等於一個週期 3. CKBCPR和CKPCPR用以設定校準的時間框架,可以在執行時手動調整 4. 布林變數TNBE用以設定調整方向,設為1的時候就是跑慢點,設為0的時候就是跑快點,在一般情況下,TNBE都是設為0 5. 當CKPCLK由最大值回到0,CKBCLK就加1。 執行方式請參看附件圖片。 TMR1已設定為不會跟系統同步(T1CON = 0x0F)。 問題就是,實作跑的時候仍然受到溫度所導致的系統內振執行速度變化所影響。在系統和TMR1都用外置振盪的話則不會有這個問題。 具體一點說,在同一個CKBCPR的設定值下,用網絡計時做對照,在12月和1月的時候,系統跑一天就比對照的明顯的慢;但到3月天氣回暖後,只消半天就的跑得快過對照。所以過了半年都無法校準。 程式中斷式內還有以500Hz跑的TMR0和2.2kHz跑的TMR2,它們不會在中途暫停的。 其實我是否應該將RA4和RA5改接系統外置振盪,TMR1就改內置? 如果不變更硬件,我還有什麼方法可以解決這個問題?
發表於: 2023/3/23 19:20
|
|||
|
Re: 16F685斷電EEPROM內容就毀損
|
||||
---|---|---|---|---|
資深會員
|
電源是取用電腦USB 3.0插槽。
電路有使用100uF電容器並聯連接,這會不會有影響? 同一個電路但在MCU進入sleep狀態時,一樣的斷電方式,EEPROM資料異常刪除的機會就很少。
發表於: 2022/8/25 20:47
|
|||
|
16F685斷電EEPROM內容就毀損
|
||||
---|---|---|---|---|
資深會員
|
最近翻新一些沒碰很久的PIC程式,更新的對象有16F1936、16F685、12F1822和12F675的。在試行時留意到一個問題,就是16F685的程式,在運作中途斷電再恢復後,EEPROM內容就會有毀損,有隨機位址的資料變成FF(即是被刪除了),但其他的就不會發生這種狀況。
小部分情況將程式在INTCON完全關閉的狀態下進入sleep指令後(沒有任何輸入可以喚醒),重接電源再次啟動MCU,EEPROM還是會有一兩格資料被刪除。 程式執行開頭的地方都沒有寫入EEPROM的指令,但就是使用16F685的好幾個程式也是會這樣,為什麼? (發文上載附件功能似乎有些問題,我無法上載任何gif或jpg截圖)
發表於: 2022/8/23 18:13
|
|||
|