最近在学习MSP430f149这块单片机,开始程序也没烧进去,弄了一天,发现串口不能下载,买了个jtag下载器,才搞定。现在也谈谈开始写程序的一些方法吧
程序重要的是框架,有这个基础之后才能行云流水的开始写程序。
include
void InitSys( );
int main( void )
{
WDTCTL=WDTPW+WDTHOLD; //关闭看门狗
InitSys( ); //初始化
start:
//以下填充用户代码
LPM3; //进入低功耗模式n,n 取值为0~4,若不希望进入低功耗模式,屏蔽本句
goto start;
}
/*********************************************************************
系统初始化
***********************************************************************/
void InitSys()
{
unsigned int iq0;
//使用XT2 振荡器
BCSCTL1 &= ~XT2OFF; //打开XT2 振荡器
do
{
IFG1 &= ~OFIFG; //清除振荡器失效标志
for(iq0=0xFF;iq0>0;iq0--); //延时,等待XT2 起振
}
while ((IFG1 & OFIFG)!= 0); //判断XT2 是否起振
BCSCTL2=SELM_2+SELS; //选择MCLK、SMCLK 为XT2
//以下填充用户代码,对各种模块、中断、外围设备等进行初始化
_EINT(); //打开全局中断控制,若不需要打开,可以屏蔽本句
}
/**********************************************************************
端口2 中断函数
***********************************************************************/
#pragma vector=PORT2_VECTOR
__interrupt void Port2()
{
//以下为参考处理程序,不使用的端口应当删除其对于中断源的判断。
if((P2IFG&BIT0)==BIT0)
{
//处理P2IN.0 中断
P2IFG &= ~BIT0; //清除中断标志
//以下填充用户代码
}
else if((P2IFG&BIT1)==BIT1)
{
//处理P2IN.1 中断
P2IFG &= ~BIT1; //清除中断标志
//以下填充用户代码
}
else if((P2IFG&BIT2)==BIT2)
{
//处理P2IN.2 中断
P2IFG &= ~BIT2; //清除中断标志
//以下填充用户代码
}
else if((P2IFG&BIT3)==BIT3)
{
//处理P2IN.3 中断
P2IFG &= ~BIT3; //清除中断标志
//以下填充用户代码
}
else if((P2IFG&BIT4)==BIT4)
{
//处理P2IN.4 中断
P2IFG &= ~BIT4; //清除中断标志
//以下填充用户代码
}
else if((P2IFG&BIT5)==BIT5)
{
//处理P2IN.5 中断
P2IFG &= ~BIT5; //清除中断标志
//以下填充用户代码
}
else if((P2IFG&BIT6)==BIT6)
{
//处理P2IN.6 中断
P2IFG &= ~BIT6; //清除中断标志
//以下填充用户代码
}
else
{
//处理P2IN.7 中断
P2IFG &= ~BIT7; //清除中断标志
//以下填充用户代码
}
LPM3_EXIT; //退出中断后退出低功耗模式。若退出中断后要保留低功耗模式,将本句屏蔽
}
/**********************************************************************
USART1 发送中断函数
***********************************************************************/
#pragma vector=USART1TX_VECTOR
__interrupt void Usart1Tx()
{
//以下填充用户代码
LPM3_EXIT; //退出中断后退出低功耗模式。若退出中断后要保留低功耗模式,将本句屏蔽
}
/**********************************************************************
USART1 接收中断函数
***********************************************************************/
#pragma vector=USART1RX_VECTOR
__interrupt void Ustra1Rx()
{
//以下填充用户代码
LPM3_EXIT; //退出中断后退出低功耗模式。若退出中断后要保留低功耗模式,将本句屏蔽
}
/***********************************************************************
端口1 中断函数
多中断中断源:P1IFG.0~P1IFG7
进入中断后应首先判断中断源,退出中断前应清除中断标志,否则将再次触发中断
************************************************************************/
#pragma vector=PORT1_VECTOR
__interrupt void Port1()
{
//以下为参考处理程序,不使用的端口应当删除其对于中断源的判断。
if((P1IFG&BIT0)==BIT0)
{
//处理P1IN.0 中断
P1IFG &= ~BIT0; //清除中断标志
//以下填充用户代码
}
else if((P1IFG&BIT1)==BIT1)
{
//处理P1IN.1 中断
P1IFG &= ~BIT1; //清除中断标志
//以下填充用户代码
}
else if((P1IFG&BIT2)==BIT2)
{
//处理P1IN.2 中断
P1IFG &= ~BIT2; //清除中断标志
//以下填充用户代码
}
else if((P1IFG&BIT3)==BIT3)
{
//处理P1IN.3 中断
P1IFG &= ~BIT3; //清除中断标志
//以下填充用户代码
}
else if((P1IFG&BIT4)==BIT4)
{
//处理P1IN.4 中断
P1IFG &= ~BIT4; //清除中断标志
//以下填充用户代码
}
else if((P1IFG&BIT5)==BIT5)
{
//处理P1IN.5 中断
P1IFG &= ~BIT5; //清除中断标志
//以下填充用户代码
}
else if((P1IFG&BIT6)==BIT6)
{
//处理P1IN.6 中断
P1IFG &= ~BIT6; //清除中断标志
//以下填充用户代码
}
else
{
//处理P1IN.7 中断
P1IFG &= ~BIT7; //清除中断标志
//以下填充用户代码
}
LPM3_EXIT; //退出中断后退出低功耗模式。若退出中断后要保留低功耗模式,将本句屏蔽
}
/***********************************************************************
定时器A 中断函数
多中断中断源:CC1~2 TA
***********************************************************************/
#pragma vector=TIMERA1_VECTOR
__interrupt void TimerA1()
{
//以下为参考处理程序,不使用的中断源应当删除
switch (__even_in_range(TAIV, 10))
{
case 2:
//捕获/比较1 中断
//以下填充用户代码
break;
case 4:
//捕获/比较2 中断
//以下填充用户代码
break;
case 10:
//TAIFG 定时器溢出中断
//以下填充用户代码
break;
}
LPM3_EXIT; //退出中断后退出低功耗模式。若退出中断后要保留低功耗模式,将本句屏蔽
}
/***********************************************************************
定时器A 中断函数
中断源:CC0
************************************************************************/
#pragma vector=TIMERA0_VECTOR
__interrupt void TimerA0()
{
//以下填充用户代码
LPM3_EXIT; //退出中断后退出低功耗模式。若退出中断后要保留低功耗模式,将本句屏蔽
}
/**********************************************************************
AD 转换器中断函数
多中断源:摸拟 0~7、VeREF+、VREF-/VeREF-、(AVcc-AVss)/2
***********************************************************************/
#pragma vector=ADC_VECTOR
__interrupt void Adc()
{
//以下为参考处理程序,不使用的中断源应当删除
if((ADC12IFG&BIT0)==BIT0)
{
//通道0
//以下填充用户代码
}
else if((ADC12IFG&BIT1)==BIT1)
{
//通道1
//以下填充用户代码
}
else if((ADC12IFG&BIT2)==BIT2)
{
//通道2
//以下填充用户代码
}
else if((ADC12IFG&BIT3)==BIT3)
{
//通道3
//以下填充用户代码
}
else if((ADC12IFG&BIT4)==BIT4)
{
//通道4
//以下填充用户代码
}
else if((ADC12IFG&BIT5)==BIT5)
{
//通道5
//以下填充用户代码
}
else if((ADC12IFG&BIT6)==BIT6)
{
//通道6
//以下填充用户代码
}
else if((ADC12IFG&BIT7)==BIT7)
{
//通道7
//以下填充用户代码
}
else if((ADC12IFG&BIT8)==BIT8)
{
//VeREF+
//以下填充用户代码
}
else if((ADC12IFG&BIT9)==BIT9)
{
//VREF-/VeREF-
//以下填充用户代码
}
else if((ADC12IFG&BITA)==BITA)
{
//温度
//以下填充用户代码
}
MSP430 系列单片机实用C 语言程序设计
– 118 –
else if((ADC12IFG&BITB)==BITB)
{
//(AVcc-AVss)/2
//以下填充用户代码
}
LPM3_EXIT; //退出中断后退出低功耗模式。若退出中断后要保留低功耗模式,将本句屏蔽
}
/**********************************************************************
USART0 发送中断函数
***********************************************************************/
#pragma vector=USART0TX_VECTOR
__interrupt void Usart0Tx()
{
//以下填充用户代码
LPM3_EXIT; //退出中断后退出低功耗模式。若退出中断后要保留低功耗模式,将本句屏蔽
}
/**********************************************************************
USART0 接收中断函数
***********************************************************************/
#pragma vector=USART0RX_VECTOR
__interrupt void Usart0Rx()
{
//以下填充用户代码
LPM3_EXIT; //退出中断后退出低功耗模式。若退出中断后要保留低功耗模式,将本句屏蔽
}
/**********************************************************************
看门狗定时器中断函数
***********************************************************************/
#pragma vector=WDT_VECTOR
__interrupt void WatchDog()
{
//以下填充用户代码
LPM3_EXIT; //退出中断后退出低功耗模式。若退出中断后要保留低功耗模式,将本句屏蔽
}
/**********************************************************************
比较器A 中断函数
***********************************************************************/
#pragma vector=COMPARATORA_VECTOR
__interrupt void ComparatorA()
{
//以下填充用户代码
LPM3_EXIT; //退出中断后退出低功耗模式。若退出中断后要保留低功耗模式,将本句屏蔽
}
/**********************************************************************
定时器B 中断函数
多中断源:CC1~6 TB
***********************************************************************/
#pragma vector=TIMERB1_VECTOR
__interrupt void TimerB1()
{
//以下为参考处理程序,不使用的中断源应当删除
switch (__even_in_range(TBIV, 14))
{
case 2:
//捕获/比较1 中断
//以下填充用户代码
break;
case 4:
//捕获/比较2 中断
//以下填充用户代码
break;
case 6:
//捕获/比较3 中断
//以下填充用户代码
break;
MSP430 系列单片机实用C 语言程序设计
– 120 –
case 8:
//捕获/比较4 中断
//以下填充用户代码
break;
case 10:
//捕获/比较5 中断
//以下填充用户代码
break;
case 12:
//捕获/比较6 中断
//以下填充用户代码
break;
case 14:
//TBIFG 定时器溢出中断
//以下填充用户代码
break;
}
LPM3_EXIT; //退出中断后退出低功耗模式。若退出中断后要保留低功耗模式,将本句屏蔽
}
/**********************************************************************
定时器B 中断函数
中断源:CC0
***********************************************************************/
#pragma vector=TIMERB0_VECTOR
__interrupt void TimerB0()
{
//以下填充用户代码
LPM3_EXIT; //退出中断后退出低功耗模式。若退出中断后要保留低功耗模式,将本句屏蔽
}
/**********************************************************************
不可屏蔽中断函数
***********************************************************************/
#pragma vector=NMI_VECTOR
__interrupt void Nmi()
{
//以下为参考处理程序,不使用的中断源应当删除
if((IFG1&OFIFG)==OFIFG)
{
//振荡器失效
IFG1 &= ~OFIFG;
//以下填充用户代码
}
else if((IFG1&NMIIFG)==NMIIFG)
{
//RST/NMI 不可屏蔽中断
IFG1 &= ~NMIIFG;
//以下填充用户代码
}
else if((FCTL3&ACCVIFG)==ACCVIFG)
{
//存储器非法访问
FCTL3 &= ~ACCVIFG;
//以下填充用户代码
}
LPM3_EXIT; //退出中断后退出低功耗模式。若退出中断后要保留低功耗模式,将本句屏蔽
}
框架程序比较长,但却是一个完整的程序结构,对于初学的读者来说,更容易获得整体的概念。MSP430 的中断种类很多,通过这个框架程序也可以方便地查询中断的处理方式。程序中的 main 函数是程序的起点。main 函数中调用了另外一个函数InitSys,InitSys 作用是对系统进行初始化。其余的是中断函数,对中断进行处理。程序的第一句将看门狗关闭,MSP430 的看门狗复位后的默认状态是打开的,如果不使用就必须关闭,否则会产生PUC 信号,从而导致系统复位。另外,在调试时也应当关闭看门
狗。接着进入InitSys 函数,进行初始化。如果使用XT2 振荡器,则必须先打开XT2 振荡器。因为振荡器失效的中断标志OFIFG 复位后是有效的,所以,首先必须复位OFIFG,清除振荡器失效标志。因为XT2 振荡器不会立刻起振,所以需要延时一段时间后再次测试OFIFG。如果OFIFG 为1,则XT2 没有起振,再次复位OFIFG,等待XT2 起振。周而复始,直至XT2起振再向下执行程序。程序接着选择MCLK 和SMCLK 的时钟源为XT2,当然也可以不这样选。接着根据需要对所使用的外围模块进行初始化。最后,如果使用了中断,则打开全局中断控制位。CPU 也可以根据需要选择进入低功耗模式,等待中断被触发再退出低功耗模式。不同的中断函数处理方式有所不同。某些中断要求退出中断函数前要复位中断标志,否则会再次触发中断。多中断源中断函数需要判断中断源,如果同时有多个中断源触发中断,则按照所编写程序判断中断触发源的顺序来确定响应中断的优先级。用户可以按照自己的顺序要求来编写程序。中断函数中最后一句LPMn_EXIT 使程序退出中断程序之后脱离低功耗模式,n 的取值范围为0~4,代表5 种低功耗模式。