MSP430 是TI 公司推出的16 位低功耗單片機,已廣泛應用到抄表、汽車和工業控制等領域。筆者在用匯編語言進行編程調試中發現,現有書籍和資料大多取自英文的產品手冊,對程序調試的指導意義有限,難以滿足初學者需要,本文就在MSP430F169 的定時器調試中出現的問題進行了總結,希望更多的MSP430 使用者總結出自己的使用經驗,以供大家分享。 問題一:在定時器增計數模式下,程序不能正確進入中斷程序。
程序如下: ;時鐘初始化 BIC.B #XT2OFF,BCSCTL1 BIC.B #XTS,BCSCTL1 BIS.B #SELM1,&BCSCTL2 ;選擇XT2CLK 為MCLK 的時鐘源
;定時器初始化 MOV #0FFH,&TBCCR0 BIS # ID_3,&TBCTL ;MCLK8 分頻作為定時器的時鐘源 BIS # CCIE +MC_1,&TBCTL ;以增計數模式開始計數并開中斷 EINTMainloop ... JMP Mainloop
;定時器中斷程序 TIMERB0 ADD.W &TBIV,PC RETI ... TBOVER XOR.B #04h,P2OUT RETI ------------------------------------------------------------------------------- 現象:TBCCR0 計滿0FFH,程序指向TIMERB0,執行中斷便死機。 經查原因如下:當TBR 計數到TBC-CR0 設定值0FFH 時,中斷標志位TBIFG 置位,指針跳轉到中斷程序首址TIMERB0 處。在這里執行程序指針PC 加上定時器中斷向量TBIV 內的值,指 向相應的執行程序。但TBIE 的中斷向量要到中斷標志位TBIFG 置位的下一個定時器時鐘周期到來時才會產生,因為用MCLK 的8 分頻作為定時器的時鐘源,所以在下一個定時器的時鐘前,程序有8 個指令周期的空擋。換句話說,就是中斷標志位TBIFG 置位后,還需8 個指令周期TBIE內的中斷向量才會產生。再看上面的程序,TBIFG 置位后第一個指令周期執行的是跳轉指令,程序指向TIMERB0 處,第二個指令周期就開始執行語句“ADD.W &TBIV,PC”,而這時TBIV 內的中斷向量值還沒有產生,所以程序會死掉。 決辦法:可以在定時器中斷程序的首址TIMERB0 與執行語句“ADD.W&TBIV,PC”之間 加7 條以上的NOP 指令,等待定時器中斷向量TBIV 的產生。
問題二:調用子程序時產生錯誤。 例如,調用延時程序的語句為:“CALL DB-LAY”,執行時程序跑飛。查看手冊和相關書籍,指令格式為“CALL dst”,應該沒有錯,但問題依舊存在。 解決辦法:找一個MSP430 調用子程序的例程,發現指令的格式為“CALL #dst”。將調用子程序的語句改為“CALL #DE-LAY”再運行,問題解決。
問題三:在定時器增/減計數模式下,不能進入中斷程序。 程序如下: MOV #0FFH,&TBCCR0 BIS # CCIE +MC_3,&TBCTL;以增/減計數模式開始計數并開中斷; --------中斷向量部分------ ORG 0FFFEh ;/﹡ 0xFFFE Reset ﹡/ DW RESET ORG 0FFFAh ;/﹡ 0xFFFA Timer B CC0 ﹡/ DW HMERB0 END
現象:TBR 計數到0FFH,TBCCR0 溢出,相應的中斷標志位TBIFG 也置位了,但程序無法 進入中斷。 解決辦法:查看msp430x16x..h 頭文件中斷向量相關部分如下: #define TIMERB1_VECTOR(12 ﹡ 2u) /﹡ 0xFFF8 Timer B CC1-6, TB ﹡/ #define TIMERB0_VECTOR(13 ﹡ 2u) /﹡ 0xFFFA Timer B CC0 ﹡/
TBCCR0 應該對應0xFFFA 處的中斷向量TIMERB0_VECTOR,而TBCCR1~TBCCR6 應該 對應0xFFF8 處的中斷向量TIMERB1_VECTOR,但TBCCR0 溢出時,程序指針就是不指向0xFFFA 處的中斷向量。查閱所有手冊和書籍,均沒有相關說明和解釋。經過嘗試,筆者將上面程序中的“ORG 0FFFAh”改為“ORG0FFF8h”后,程序運行就正常了,即這時使用的是中斷向量 TIMERB1_VECTOR。 另外,“ORG 0FFF8h”不能寫為“ORG TIMERB1_VECTOR”,若寫成后者,可以編譯,但 程序不會執行。 |
|