MSP430是TI公司推出的16位低功耗单片机,已广泛应用到抄表、汽车和工业控制等领域。笔者在用汇编语言进行编程调试中发现,现有书籍和资料大多取自英文的产品手册,对程序调试的指导意义有限,难以满足初学者需要,本文就在MSP430F169的定时器调试中出现的问题进行了总结,希望更多的MSP430使用者总结出自己的使用经验,以供大家分享。
问题一:在定时器增计数模式下,程序不能正确进入中断程序。
程序如下:
时钟初始化BIC.B #XT20FF.BCSCTLIBIC.B #XTS.BCSCTL1BIS.B #SELM1.&BCSCTL2;选择XT2CLK为MCLK的时钟源;定时器初始化MOV #OFFH,&TBCCR0BIS #ID 3.&TBCTL;MCLK8分频作为定时器的时钟源BIS #CCIE+MC_1,&TBCTL;以增计数模式开始计数并开中断EINTMainloop ···JMP Mainloop;定时器中断程序TIMERB0 ADD.W &TBIV.PCRETI…TBOVER XOR.B #04h,P20UTRETI现象:TBCCR0计满0FFH,程序指向TIMERBO,执行中断便死机。
经查原因如下:当TBR计数到TBC-CR0设定值OFFH时,中断标志位TBIFG置位,指针跳转到中断程序首址TIMERBO处。在这里执行程序指针PC加上定时器中断向量TBIV内的值,指向相应的执行程序。但TBIE的中断向量要到中断标志位TBIFG置位的下一个定时器时钟周期到来时才会产生,因为用MCLK的8分频作为定时器的时钟源,所以在下一个定时器的时钟前,程序有8个指令周期的空挡。换句话说,就是中断标志位TBIFG置位后,还需8个指令周期TBIE内的中断向量才会产生。再看上面的程序,TBIFG置位后第一个指令周期执行的是跳转指令,程序指向TIMERB0处,第二个指令周期就开始执行语句“ADD.W &TBIV,PC”,而这时TBIV内的中断向量值还没有产生,所以程序会死掉。
解决办法:可以在定时器中断程序的首址TIMFERB0与执行语句“ADD.W&TBIV,PC”之间加7条以上的NOP指令,等待定时器中断向量TBIV的产生。
问题二:调用子程序时产生错误。
例如,调用延时程序的语句为:
“CAlL.DE[AY”。
执行时程序跑飞。
查看手册和相关书籍,指令格式为“CALL dst”,应该没有错,但问题依旧存在。
解决办法:找一个MSP430调用子程序的例程,发现指令的格式为“CALL#dst'‘。将调用子程序的语句改为 ”CALL #DE-LAY“再运行,问题解决。
问题三:在定时器增/减计数模式下,不能进入中断程序。
程序如下:
MOV #0FFH,&TBCCR0BIS #CCIE+MC_3,&TBCTL;以增/减计数模式开始计数并开中断…;——一一一中断向量部分——ORG 0FFEEh '
:/*0xFFFE Reset */DW RESETORG 0FFFAh;/*0xFFFA Timer B CCO */DW TIMERBOEND现象:TBR计数到0FFH,TBCCR0溢出,相应的中断标志位TBIFG也置位了,但程序无法进入中断。
解决办法:查看msp430x16x.h头文件中断向量相关部分如下:
#define TMERBl_VECTOR (12*2u)/* 0xFFF8 Timer B CCl-6,TB*/#define TIMERBO_VECTOR,(13*2u)/* 0xFFFA Timer B CCO */TBCCR0应该对应0xFFFA处的中断向量TIMERB0_VECTOR,而TBCCRI-TBCCR6应该对应OxFFF8处的中断向量TIMERBl_VECTOR,但TBCCR0溢出时,程序指针就是不指向0xFFFA处的中断,向量。查阅所有手册和书籍,均没有相关说明和解释。经过尝试,笔者将上面程序中的”ORG OFFFAh“改为”ORGOFFF8h“后,程序运行就正常了,即这时使用的是中断向量TIMERBl_VECTOR。
另外,”ORG 0FFF8h“不能写为”ORG TIMERBl_VECTOR“,若写成后者,可以编译,但程序不会执行。