程序功能:幅度测量,0.01V - 10V,分为3个范围,分别为:0.01V - 0.1V, 0.1V - 1V, 1V - 10V,通过继电器判断哪路通道打开,
每需要测量一个幅度,按键进入中断判断应该打开哪路通道,在while()里直接测量判断好的通道
出现的问题:不加外部中断程序正常,加外部中断后有时候会自动复位,有时候死机
代码:
float vpp;
unsigned char key_temp;
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引脚中断
{
//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);
}
}
}
__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;
{
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;
}
}
}
}
}