Quantcast
Channel: MSP 低功耗微控制器论坛 - 最近的话题
Viewing all articles
Browse latest Browse all 3634

I/O中断异常MSP430G2553

$
0
0

程序功能:幅度测量,0.01V - 10V,分为3个范围,分别为:0.01V - 0.1V,               0.1V - 1V,              1V - 10V,通过继电器判断哪路通道打开,

每需要测量一个幅度,按键进入中断判断应该打开哪路通道,在while()里直接测量判断好的通道

出现的问题:不加外部中断程序正常,加外部中断后有时候会自动复位,有时候死机

代码:

float vpp;
unsigned char key_temp;
void key(void)
{
  //1位按键电路涉及引脚配置
  P1SEL  &=~ BIT4;                           //设置P1.4管脚为普通I/O
  P1SEL2 &=~ BIT4;
  P1DIR  &=~ BIT4;                           //输入
   
  P1IFG=0x00;                                //p1清除中断标志
 
  P1IES |= BIT4;                             //设置p1.4引脚的中断触发边沿为下降沿
  P1IE  |= BIT4;                             //使能p1.4引脚中断
  _EINT( );                                  //MSP430系统开中断
}
#pragma vector=PORT1_VECTOR                   //P1端口中断服务程序
__interrupt void PORT1_key1(void)            
{
  time1s( );                                  //软件去抖动
  P1IFG=0;
  P1OUT &=~  BIT2;
  P1OUT &=~  BIT3;
  P1OUT |= BIT1;
  time1s( );                                  //等待继电器稳定
  measure( );
  if(vpp>=0.33)
  {
    key_temp=0;
    wr_lcd_s(0, 0x30);                                                   // 基本指令
    wr_lcd_s(0, 0x80);                                                   // 基本指令:指定显示地址(3行,5列)
                                                                              // 在 "data=" 的后面显示数据 data_temp
    wr_lcd_s(1, 11 + 0x30);
  }
  else
  {
      P1OUT &=~  BIT1;
      P1OUT &=~  BIT3;
      P1OUT |=  BIT2;
      time1s( );
      measure( );
      if(vpp>0.33)
      {
        key_temp=1;
        wr_lcd_s(0, 0x30);                                                   // 基本指令
        wr_lcd_s(0, 0x80);                                                   // 基本指令:指定显示地址(3行,5列)
                                                                              // 在 "data=" 的后面显示数据 data_temp
        wr_lcd_s(1, 22 + 0x30);
      }
      else
      {
        P1OUT &=~  BIT1;
        P1OUT &=~  BIT2;
        P1OUT |=  BIT3;
        key_temp=2;
        wr_lcd_s(0, 0x30);                                                   // 基本指令
        wr_lcd_s(0, 0x80);                                                   // 基本指令:指定显示地址(3行,5列)
                                                                              // 在 "data=" 的后面显示数据 data_temp
        wr_lcd_s(1, 33 + 0x30);
      }
  }
}
int main( )
{
  WDTCTL=WDTPW+WDTHOLD;                                                         // 关闭看门狗
 
  P1SEL &=~ 0x0e;                                                               //配置P1.1-P1.3为普通数字输入输出管脚
  P1SEL2&=~ 0x0e;
  P1DIR |= 0x0e;                                                               //配置P1.1-P1.3为输出管脚
  P1OUT &=~ 0x0e;
 
  time1s( );                                                                    // 满足 LCD12864 的复位要求
  lcd_begin( );                                                                 // LCD 初始化 
  time1s( );
  adc10_begin( );
  time1s( );
  char_disp(char_tab1e);                                                 // 字符(char_tab1e)显示
  time1s( ); 
  time1s( );
  char_disp(data_tab1e);                                                 // 字符(data_tab1e)显示
  time1s( );
  key( );                                                                       //必须配置在while()前面
  while(1)
  {
    switch(key_temp)
    {
      case 0:
        P1OUT &=~  BIT2;
        P1OUT &=~  BIT3;
        P1OUT |= BIT1;
        measure( );
        vpp=vpp*3000;
        wr_lcd_s(0, 0x30);                                                   // 基本指令
        wr_lcd_s(0, 0x80);                                                   // 基本指令:指定显示地址(3行,5列)
                                                                              // 在 "data=" 的后面显示数据 data_temp
        wr_lcd_s(1, 0 + 0x30);
        show(vpp);
        time1s( );
        break;
  
      case 1:
          P1OUT &=~  BIT1;
          P1OUT &=~  BIT3;
          P1OUT |= BIT2;
          measure( );
          vpp=vpp/3.3*1000;
          wr_lcd_s(0, 0x30);                                                   // 基本指令
          wr_lcd_s(0, 0x80);                                                   // 基本指令:指定显示地址(3行,5列)
                                                                                // 在 "data=" 的后面显示数据 data_temp
          wr_lcd_s(1, 1 + 0x30);
          show(vpp);
          time1s( );
          break;
 
      case 2:
          P1OUT &=~  BIT2;
          P1OUT &=~  BIT1;
          P1OUT |= BIT3;
          measure( );
          vpp=vpp/33*1000;
          wr_lcd_s(0, 0x30);                                                   // 基本指令
          wr_lcd_s(0, 0x80);                                                   // 基本指令:指定显示地址(3行,5列)
                                                                                // 在 "data=" 的后面显示数据 data_temp
          wr_lcd_s(1, 2 + 0x30);
          show(vpp);
          time1s( );
          break;
    default:break;
    }
  }
}

Viewing all articles
Browse latest Browse all 3634

Trending Articles