This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430F5529A按键中断



首先,想确认一下MSP430F5529A launchpad上的两个按键S1和S2是否是由P1.7和P2.2控制的?

我现在在编写一个电子秤的中断程序,总体的思路是主程序设置好中断允许后显示欢迎界面,并进入LPM3状态。由按键S1和S2启动中断响应。首次按下S1时进入程序1,执行之后系统进入LPM3状态,等待后续中断。之后按下S1,进入程序2,执行完后也进入LPM3状态。按下S2,显示“谢谢使用”,并退出。

检验是否是首次按下S1,采用的是全局变量k,当首次进入之后修改k的值,使得中断响应执行程序2.

现在的问题是:出现按下S2却进入S1中断响应的问题,同时也有只按下一次S1,却先执行程序1后又执行程序2的现象,请问应该怎么修改?

其次,想问问按下S2(相当于关机键)之后,进入哪一种状态可以做到关闭显示屏?

刚刚接触MSP430,也是第一次学习单片机,有很多基础的问题,希望能得到大家的帮助!

谢谢。

具体的代码如下:

主函数:

void main(void)
{


P1DIR = 0X7F;//调零,按下S1开始称重,按下S1:设置P1.7为输入状态
P1IE = 0X80;//设置P1.7开中断
P1IES = 0X7f;//设置P1.7中断为shangsheng沿中断
P1REN = 0X7f;//配置xia拉电阻
P1OUT = 0X80;
P1IFG = 0;//清除P1的中断标志,无所谓,因为不用这个标志判断进入何种中断程序
// _EINT();//开全局中断
P2DIR = 0XFB;//关机,按下S2(P2.2),设为输入状态
P2IE = 0X04;//设置P2.2开中断
P2REN = 0Xfb;//配置shang拉电阻
P2IES = 0Xfb;//设置P2中断为xiajiang沿中断
P2OUT = 0X04;

_EINT();//开全局中断
welcome();
LPM3;
}

中断响应:

#pragma vector = PORT1_VECTOR
__interrupt void P1_ISR(void)
{
switch(m)
{
case 1:
{
m = 0;
ADC();
zero[0] = results[0];
display0();
// _EINT();
P1IFG =0;
LPM3;
break;
}
case 0:
{
ADC(); //称量程序
char q[4];
results[0] = results[0] - zero[0];
for(int i=3 ; i>=0; --i)
{
q[i] = results[0]%10+48;
results[0]=results[0]/10;
}
display(q);
// _EINT();
P1IFG = 0;
LPM3;
break;
}
}

}

#pragma vector = PORT2_VECTOR
__interrupt void P2_ISR(void)
{

display2();

P2IFG&=~BIT2;

}

主要的函数:ADC();是一ADC转换的程序,工作起来也是有问题的。如下所示:

void display0( void);
void display( char *ptr );
void display2( void );
void delay(void);
void welcome( void );

void ADC(void)
{
unsigned int i;
WDTCTL = WDTPW+WDTHOLD; // 关闭看门狗
P7SEL |= 0x03; // 使能时钟端口
UCSCTL6 |= XCAP_3; // 配置晶振电容



while ( (SFRIFG1 & OFIFG)) /////////////////////////////////// 判断晶振是否起振///////////////////////////////////////////////////////////////////////////////////////////
{
UCSCTL6 &= ~(XT1LFOFFG + DCOFFG); // 清除失效标志位
//SFRIFG1 &= ~OFIFG; // 清除失效中断标志位
SFRIFG1 = 0x00;
}
UCSCTL4 = SELM__DCOCLK + SELS__DCOCLK; // 选择时钟源
P7DIR &= ~(BIT4 + BIT5); // P7.7口A7输入
P7SEL |= (BIT4 + BIT5); // P7口第二功能
ADC12CTL2 = ADC12RES_2 + ADC12REFOUT; // AD基本配置
ADC12CTL0 = ADC12ON + ADC12MSC + ADC12SHT03 + ADC12REFON + ADC12REF2_5V;
ADC12MCTL0 |= ADC12SREF_1 + ADC12INCH_10; // 采样温度
ADC12MCTL1 |= ADC12SREF_1 + ADC12INCH_11; // 采样VACC/2
ADC12MCTL2 |= ADC12INCH_12; // 通道12输入
ADC12MCTL3 |= ADC12INCH_13 + ADC12EOS; // 通道13输入
ADC12CTL1 = ADC12SHP + ADC12CONSEQ_3; // 选择转换模式
for (i=0;i<0xFFFF;i++); // 等待基准电压建立
UCSCTL8 |= MODOSCREQEN;
ADC12IE |= 0X08; // 使能通道4中断
ADC12CTL0 |= ADC12ENC; // 开启转换
_EINT(); // 打开总中断
ADC12CTL0 |= ADC12SC; // 转换开始
LPM3; // 进入低功耗3
}

#pragma vector = ADC12_VECTOR
__interrupt void ADC12ISR(void)
{
results[0] = ADC12MEM3; // 保存第一通道值
_EINT();

}

  • 因为你的程序稍微复杂些,建议先画好流程图,按照图来写代码,才不容易乱。

    关闭显示屏,一般是用mcu控制关断显示屏的供电电路,并把相关控制io设置成一定状态就可以了

  • 不知道你用的是哪款Launchpad,如果是白色的那种,P1.7是S1,P2.2是S2。进入终端先请标志位,430是简单的单片机,尽量不要做中断嵌套,也不要在ISR里写复杂的东西。初学者建议先学习一下Launchpad users experience的例程吧~