當前位置:首頁 > 芯聞號 > 充電吧
[導讀]總結一些細節(jié)的問題,再分析功能實現(xiàn)上的缺陷:

  上回說到剛接觸PIC沒20天的菜鳥碧水長天準備"野心勃勃"寫一段LCD顯示精確時鐘的但遭到無情狙擊的故事,幸好得到這里行家的點撥,方能理清一點頭緒,于是,今天就接著上回的故事,總結一些通用的注意事項,并對LCD顯示精確時鐘進行功能實現(xiàn)上的分析.

  

一、先總結一些細節(jié)的問題,再分析功能實現(xiàn)上的缺陷:

1. 關于中斷現(xiàn)場的保護和恢復的問題
  由于movf指令可以影響STATUS,而W又要在現(xiàn)場保護過程中起中轉寄存器的作用,因此,應先保護W,再保護STATUS,最后是保存其他現(xiàn)場變

量。保存的時候應注意,如果W的備份寄存器w_temp若不是位于快速存取區(qū)70H~7FH,假如w_temp定位為0x20,那么還需保證bank1,bank2,

bank3中的0xA0,0x120,0x1A0出的單元沒有被派做他用。如果fsr_temp,pclath_temp等也不是定義在快速存取區(qū)的話,那么,需注意在備份FSR

,PCLATH之前,要確保當前操作在bank0處(當然,在其他bank也可,但必須注意在恢復現(xiàn)場的時候,也要保證在相同的bank中對備份積存器進

行操作,為了方便起見,建議控制在bank0處進行保存和恢復操作)。
   至于,備份寄存器若定位與快取區(qū)中,那么對bank沒有要求,但對次序的要求仍然存在的。
  
  這是經過改進后的恢復和保存現(xiàn)場代碼:
ORG     0x000                  ; processor reset vector
    nop                      ; ICD need
     goto    main              ; go to beginning of program

    ORG     0x004             ; interrupt vector location
    movwf   w_temp            ; 先保存W
    movfw    STATUS            ; 再保存STATUS到W中
    clrf     STATUS          ; 注意該指令,確保對status_temp,pclath_temp的操作在bank0中
                      ; (如果備份寄存器定義在快取區(qū)中,可無取消此條clrf及恢復現(xiàn)場那條clrf指令)
    movwf    status_temp       ; 保存上上條指令備份在W中的STATUS
    movfw    PCLATH          ; 備份PCLATH
    movwf    pclath_temp
    movfw    FSR          ; 備份FSR
    movwf    fsr_temp      
    ; 可添加其他欲保護的變量

;******************** 中斷服務代碼
    btfss    INTCON,T0IE      ; 判斷是否為T0中斷
    goto    other_int
    btfss    INTCON,T0IF      ; it 's the time of T0 int
    goto    other_int
    bcf    INTCON,T0IF      ; 是T0中斷,清除中斷標志
    movlw    0x10          ; 微秒的高位字節(jié)加上定時時間 256x16分頻=4096=0x1000的高位(0x10)
    addwf    us+1
    goto    end_int          
other_int              ; 可添加其他中斷服務代碼
    nop              ; other isr code can be added
;**********************************
end_int                  ; 恢復現(xiàn)場
    clrf    STATUS          ; 確?;謴同F(xiàn)場的操作在bank0中(如果備份寄存器定義在快取區(qū)中,可無取消此條指令)
    ; 可添加恢復其他變量
    movfw    fsr_temp      ; 恢復FSR
    movwf    FSR
    movfw    pclath_temp      ; 恢復PCLATH(FSR和PCLATH的恢復無先后之分)
    movwf    PCLATH
    movfw   status_temp       ; 先恢復STATUS
    movwf    STATUS            ;
    swapf   w_temp,f
    swapf   w_temp,w          ; 最后恢復W,采用swapf是因為其不會影響STATUS
    retfie                    ; 中斷返回

;*********


2.(保留區(qū)域,待添加)

--------------------------------------------

二、分析功能實現(xiàn)上的缺陷,并由中斷響應及子程序暫禁中斷所引起的問題說開去

  先將昨天貼的源程序的main部分的代碼拿出來分析:
  主程序要實現(xiàn)的功能是顯示時鐘:   
                  HH MM SS
                  00:00:00
  定時中斷每次產生4096us的增量,在中斷服務中,將此時間增量累加在(us+1:us)兩個相鄰的字節(jié)中,由_clock子程序
對(us+1:us)進行及時判斷,超出50ms即取走一個50ms的增量,并保留余量在(us+1:us)中以保證長時間定時精確.

主程序流程:

main
    nop
    call    _init         ; 調用初始化子程序,清緩沖區(qū),實現(xiàn)液晶顯示器和TMR0的初始化操作.
    call    _disp1        ; 調用顯示字符"    HH MM SS    "的子程序
loop   
    call    _clock        ; 調用時間更新子程序,更新定時中斷產生的時間累加值
    call    _convert      ; 調用時鐘的小時,分,秒的BCD碼轉換子程序,并換成字符對應的ASCII碼
    call    _disp2        ; 調用轉換后的小時:分:秒字符的顯示子程序
    goto    loop      ; 執(zhí)行主循環(huán)

分析如下:
   由于_clcok和_convert碼制字符轉換子程序與時間顯示_disp2子程序是前后的順序關系的,在時間顯示時,前兩個子程序是不工作的,由于

LCM的慢顯特性,使得該子程序執(zhí)行時間較長,這樣,即使中斷定時時間已經累計到應改變顯示結果的條件,但此刻_disp2若仍在顯示上一時間

,使得_clcok不能及時更新時間,并且_convert不能轉換代碼,那么顯示結果仍然沒有變化。當loop循環(huán)執(zhí)行一次完畢之后,_clock和_convert才開始更新.
   但是這里可能會有個疑問:既然如此,計算_disp2的執(zhí)行時間大概為500ms,當_disp2子程序執(zhí)行完畢之后,那么也開始循環(huán)執(zhí)行_clock和

_convert,然后LCM再顯示,此刻應該顯示的是更新的時間了吧,總時間也大概為1s多一點,為何執(zhí)行結果大概等到1分鐘左右,秒區(qū)數字才加1呢?   
   問題提得很好。

   思考原因可能為 :由于_clock不能及時更新時間,及不能及時取走(us+1:us)中大于50ms時的50ms量,但中斷服務代碼中始終嚴格執(zhí)行下面兩

條指令:
    movlw    0x10          ; 256x16分頻=4096=0x1000的高位(0x10)
    addwf    us+1          ; 微秒的高位字節(jié)加上定時時間
多次累加后(15次累加令us+1單元的內容為從00H到F0H)令us+1單元溢出,丟失定時的時間增量,若當_clock更新時,(us+1:us)發(fā)生溢出使得其

值小于50ms(代數值50000),因此也不能使得變量ms50的值增加,那么秒鐘變量sec也不會變化,轉換后時間顯示仍然保持不變.
  注意: 當_clock更新時間時,(us+1:us)若滿足大于50 000的條件,則ms50變量加一,在main主程序中_clock循環(huán)更新時,若捕捉到20次

(us+1:us)單元大于50000(50ms)時,sec的值才能加1。而這個在多次更新過程中捕捉該條件的周期,就是秒區(qū)顯示加1的周期,我認為這個周

期是固定的,也許是30秒,也許是1分鐘,也許更長,只要程序長度和結構沒有發(fā)生變化。后來在程序中,我增加延時子程序的時間,結果秒區(qū)數字加1的間隔時間也跟著延長了。

   到了這里,知道了問題所在,那么在基于原程序的框架下,我對幾種解決方案都嘗試了一下:

方案1:
     [既然癥結是在_clock不能真實捕捉到每一次中斷時間累加增量(us+1:us)值大于50ms(50000)的條件,那么,將_clock內嵌中斷中去,中

斷每一次改變us+1的值然后馬上進行時間更新,這樣,使得_clock能真實捕捉每一次(us+1:us)值大于50ms(50000)的條件,也能真實更新系統(tǒng)時

間。]

  方案1分析:這樣確實可以保證每一次都可以捕捉us時間增量,不考慮運行的結果問題,該方案有幾個缺點:

  1) 中斷服務代碼由于調用了_clock子程序,顯得異常臃腫;
  2) 每次中斷(4096us)都調用_clock,判斷其是否到50ms(值為50000),增加了程序的開銷,效率較低;
  3) 由于LCM慢顯示特性的原因,可能使得結果仍然不能令人滿意:

  關于3) 我描述一下一下:雖然此刻,秒區(qū)的數字能基本上每秒鐘跳變一次了,但是調試過程中出現(xiàn)了一個問題: 秒區(qū)數字跳變有時會忽略下

一個值,而跳到下下一個值去,比如,當前顯示12,然后馬上顯示14。

  那么問題出在什么地方呢? 試想,若_convert在進行格式轉換時,發(fā)生中斷,且更改了sec變量,那么,_convert會按新的值進行轉換,這

樣,本來這次要轉換并送顯示的舊值被新值給覆蓋了,所以,_disp2在顯示的時候,也就根據_convert的轉換結果,忠實地顯示了一個新值,將

本來應該顯示的值給忽略了。

  既然如此,有什么辦法來解決呢?兩個方法:

  (a)  _convert在對時間變量進行格式轉換時,暫時禁止TMR0中斷,轉換后再開啟TMR0中斷;
  (b)  將_conver也歸并到中斷代碼中去,規(guī)定次序,使得_clock更新時間后,_convert再進行轉換,這樣,格式轉換區(qū)的變量不用擔心被

_clock修改;
   
   **那么方法(a)會存在什么問題呢?試想:當_convert在轉換時,TMR0定時時間到,TMR0向內核提交中斷,但由于TMR0中斷請求被禁止,即使

_convert轉換完畢之后,允許TMR0中斷,那么TMR0的中斷請求會不會被丟棄呢? 顯然,根據PIC的中斷系統(tǒng),當TMR0定時時間到后,首先將

T0IF置1,并由T0IF向內核提出中斷請求,如果該中斷請求被禁止,那么只要其中斷標志T0IF仍然保持為1,當該中斷響應解禁之后,內核根據

T0IF立即響應其中斷。
   因此,方法(a)中"TMR0的中斷請求可能會被遺棄的擔心"是多余的.

   并且,由于_convert的執(zhí)行時間少于一個中斷周期,所以它對中斷的暫禁操作不會出現(xiàn)在一個暫禁中斷的過程中,中斷標志T0IF的多次被置一

的現(xiàn)象,所以不會發(fā)生中斷響應被沖掉的不良后果。同樣,_clock子程序在沒有加載到中斷服務代碼中去時,其對TMR0的暫禁影響與_convert分

析的結果相同.

   那么,既然如此,我認為這樣的話,由于_disp2的執(zhí)行時間也不會超過1秒,因此,不會出現(xiàn)當秒跳變時,_convert來不及轉換而丟棄上一次待

轉換的字符。所以,結果應該是正常.
   于是按照這種方法修改程序,結果發(fā)現(xiàn)秒區(qū)每次都跳變,最小增量為2,最多為為3(跳變周期大約1.2秒)。于是將延遲子程序的外循環(huán)值由

64H-〉40H(大概右25ms變成16ms),結果仍然如此,秒區(qū)每次都跳變,只是跳變節(jié)奏比未修改延時子程序前變快很多(跳變周期大約0.6s),但最

小跳變增量1,最多為2。

    [正在分析其根源,也請有興趣的兄弟一起思考一下.....]


   那么那試試方法(b).我按方法(b)修改了程序,結果發(fā)現(xiàn),仍然出現(xiàn)秒區(qū)數字跳變的情況。

    究其原因,跟3)類似:當_disp2運行的時候,準備從顯示緩沖區(qū)取字符來顯示,如果發(fā)生中斷,_clock,_convert更改了顯示緩沖區(qū)的內容

,使得本來即將待顯示的內容被替換成下一次顯示的內容。所以,該方法依然存在,而且,由于_disp執(zhí)行時間大于一次中斷的255us,如果在

_disp執(zhí)行過程暫禁TMR0中斷將會丟棄中斷請求(即:TMR0的中斷請求被自己下一次中斷請求覆蓋,上一次中斷請求被忽略,顯示時間將變慢)。



----------------------------------------------------------------

方案2:

   [中斷服務仍然只改變us+1的值,但是格式轉換及顯示功能內嵌到_clock子程序中去,主程序執(zhí)行_clock循環(huán)。]
  
   下午我按這種方式更改了程序,在軟件模擬時發(fā)現(xiàn)程序跑飛。原因是:內嵌了這些功能之后,代碼由400行變成500多行,在_disp1查表顯示

字符時,_table已經超過PCL的256字ROM空間,而查表時未注意PCLATH內容,以致跑飛。解決此問題后,下載到ICD中運行,發(fā)現(xiàn)結果倒是正常

了,但是感覺時間好像有一點點慢。
   呵呵,細心的站友想必已經看出來了,由于加了顯示功能的_clock子程序中依然是暫時禁止TMR0中斷的,雖然該時間顯示功能只是在時間跳

變時刷新LCD屏幕,但是正是由于在時間跳變時執(zhí)行時間刷新的周期過長(大于4096us),TMR0 的多次中斷請求最后只被響應一次,即T0IF多次

被置1后,卻只能在_clock子程序末對TMR0解禁時得到一次中斷響應,未被響應的累積時間被丟棄了,沒有加到(us+1:us)中去,引起時鐘顯示變

慢了.


方案3:

由于前兩個方案均存在不近人意的問題,難道在用TMR0做秒表時,且當"定時中斷的周期小于LCD慢顯器件的驅動刷新周期的情況下",就沒有一個

完美的解決方案么?
  留在這里和有興趣的站友一起思考...
   

  呵呵,羅羅嗦嗦地寫了這么一堆,就做為學習總結吧,也希望對一些和我一樣的新手有一些啟發(fā)...
本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或將催生出更大的獨角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數字化轉型技術解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關鍵字: AWS AN BSP 數字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術公司SODA.Auto推出其旗艦產品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關鍵字: 汽車 人工智能 智能驅動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務連續(xù)性,提升韌性,成...

關鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據媒體報道,騰訊和網易近期正在縮減他們對日本游戲市場的投資。

關鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數據產業(yè)博覽會開幕式在貴陽舉行,華為董事、質量流程IT總裁陶景文發(fā)表了演講。

關鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數據產業(yè)博覽會上,華為常務董事、華為云CEO張平安發(fā)表演講稱,數字世界的話語權最終是由生態(tài)的繁榮決定的。

關鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應對環(huán)境變化,經營業(yè)績穩(wěn)中有升 落實提質增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務引領增長 以科技創(chuàng)新為引領,提升企業(yè)核心競爭力 堅持高質量發(fā)展策略,塑強核心競爭優(yōu)勢...

關鍵字: 通信 BSP 電信運營商 數字經濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術學會聯(lián)合牽頭組建的NVI技術創(chuàng)新聯(lián)盟在BIRTV2024超高清全產業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術創(chuàng)新聯(lián)...

關鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關鍵字: BSP 信息技術
關閉
關閉