历史上的今天
返回首页

历史上的今天

今天是:2025年01月12日(星期日)

2020年01月12日 | 谈谈MSP430 的框架程序

2020-01-12 来源:eefocus

最近在学习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 种低功耗模式。

推荐阅读

史海拾趣

CONEC公司的发展小趣事

为了进一步提升公司的竞争力和市场影响力,CONEC开始了国际化布局。1990年,康耐加拿大公司的成立,标志着公司迈出了国际化的重要一步。随后,CONEC在德国、捷克共和国、美国和波兰等地设立分公司或生产基地,形成了全球性的生产和销售网络。同时,公司还积极寻求与全球领先的电子企业和技术机构的战略合作,共同推动电子行业的发展。

Davicom公司的发展小趣事

为了进一步提升自身的技术实力和市场竞争力,Davicom积极寻求与业界巨头的合作。经过多轮谈判,Davicom最终与一家国际知名的IC设计大厂达成战略合作协议。双方共同研发出一系列高性能、低功耗的网络通讯IC产品,这些产品一经推出便受到市场的热烈欢迎。

Abundance Enterprise Company公司的发展小趣事

随着电子行业的快速发展,Abundance Enterprise Company不断追求技术创新和产品升级。公司投入大量研发资源,成功开发出一系列具有自主知识产权的新型电子元器件,不仅提高了产品的性能和质量,还降低了生产成本。这些创新产品在市场上获得了广泛认可,为公司的快速发展提供了强有力的支撑。

Cortina Systems Inc公司的发展小趣事

随着国内市场的逐渐饱和,Abundance Enterprise Company开始积极拓展国际市场。公司积极参与国际电子展览和交流活动,与全球知名电子企业建立了广泛的合作关系。同时,公司还在海外设立了多个分支机构,进一步拓展国际业务。这些举措不仅提升了公司的国际影响力,也为公司的长期发展奠定了坚实基础。

ALLIED [Allied Electronics]公司的发展小趣事

Abundance Enterprise Company成立于XXXX年,初期专注于电子元器件的研发和生产。公司凭借对市场需求的敏锐洞察,迅速定位在高端电子元器件市场,通过精准的市场定位和高质量的产品,逐渐在电子行业中占据了一席之地。初创团队凭借扎实的技术基础和不懈的努力,成功打破了国外品牌在高端市场的垄断,为国内电子元器件行业树立了新的标杆。

Aeroflex Metelics / Hi-Rel Components公司的发展小趣事

随着电子行业的快速发展,Abundance Enterprise Company不断追求技术创新和产品升级。公司投入大量研发资源,成功开发出一系列具有自主知识产权的新型电子元器件,不仅提高了产品的性能和质量,还降低了生产成本。这些创新产品在市场上获得了广泛认可,为公司的快速发展提供了强有力的支撑。

问答坊 | AI 解惑

招聘(北京)Analog Application Engineer

jonathan@chinaeejob.com Analog Application Engineer Job Description 1. Routine lab administration and maintenance. 2. Accomplish various analog chip evaluations and prepare evaluation report. 3. Support FAE. 4. Design an ...…

查看全部问答>

Bootloader(U-BOOT)详解!

有助于在S3C2410上移植U-BOOT~~!…

查看全部问答>

跪求mcs-51系列单片机设计的简单系统

RT........ 还请单片机达人帮忙解决,小弟在此谢过…

查看全部问答>

水、电、气无线三表抄表系统方案

一、GPRS三表集中抄表及控制系统组成 由主站通过远程通信信道(无线信道)将多个无线计量表计量数据及相关信息集中抄读、集中监测和集中控制,并能实施用户管理增值服务的网络抄表监测控制系统。该系统主要由无线智能表、无线路由采集器、近程无线 ...…

查看全部问答>

乔布斯画传:漫长而辉煌的CEO生涯

苹果iPad发售在即,史蒂夫·乔布斯能否延续iPhone的辉煌引人关注。这是乔布斯自接受肝移植手术以来在商业舞台上的最大动作值此时机,推出《史蒂夫·乔布斯漫长而辉煌的职业生涯》。 电脑天才 1976年,史蒂夫·乔布斯与拍档合作创建了苹果公司。他 ...…

查看全部问答>

请问高手,我如何把我的矩阵键盘的其中一个键映射为F1功能啊?

在我的开发板提供的matrix_0409文件夹中没有给这个键对应的扫描码,我该怎么做才能达到这个目的啊, 我需要给应用层提供F1-F6的功能键。 有劳各位指点!…

查看全部问答>

tps65180

       Eink屏不同于普通的LCD屏,它需要+22V,-20V,+15V,-15V,+3.3V,-1.25V 等不同级别的电压,而且EInk屏是一种非常省电的屏幕,它只有在刷新(翻页)时需要开通电源,刷新完后电源就关闭了,所以需要专门有一块 ...…

查看全部问答>

maple输出的频率

在maple论坛见一贴关于输出频率的转过来,并测试了下:) /* QuickererPin :-) * * Turns a GPIO pin on and off fast using direct updates. * Copyright 2010 G Bulmer */ // #include <gpio.h>// #include <boards. ...…

查看全部问答>

关于STM8S103的AWU和ADC的问题

关于STM8S103的AWU和ADC的问题   昨天我试该单片机的awu功能,mcu睡眠醒来后,发现系统死机,后来经过一步步测试发现系统在检测ADC时系统死机。于是我在睡眠醒来后初始话ADC及pwm后,系统是没有死机,但是这样的话,我的ADC触摸按 ...…

查看全部问答>

UCOS QQ群

各位大侠,小弟刚刚建了一个  UCOS 的QQ 群 欢迎 爱好 嵌入式实时操作系统 UCOS-II 的童鞋加入,一起讨论  学习  提高 群号 : 164475364…

查看全部问答>