我的按键程序总是发生串扰,找不到故障所在,高手帮忙呀!!
#include "msp430x14x.h"
/*****************宏********定********义*****************
* 命令字定义 *
********************************************************/
#define uchar unsigned char
#define uint unsigned int
/********************************************************
按键定义
********************************************************/
//选用端口定义
#define KEYDIR P1DIR
#define KEYIES P1IES
#define KEYIE P1IE
#define KEYIN P1IN
#define KEYIFG P1IFG
//定义键盘管脚
#define KEY0 BIT0
#define KEY1 BIT1
#define KEY2 BIT2
#define KEY3 BIT3
#define KEY_MOD (KEY0+KEY1+KEY2+KEY3)
#define KEY_TIME 50 //连续按键经过此时间,按键次数加1
#define KEY_NONE 0 //无键按下
#define KEY_P10 0x01 //P1.0键值
#define KEY_P11 0x02 //P1.1键值
#define KEY_P12 0x04 //P1.2键值
#define KEY_P13 0x08 //P1.3键值
/********************按键变量定义***********************/
uchar KeyZhi=KEY_NONE; //经过确认的键值
uchar KeyDown=KEY_NONE; //被按下的键
uchar ajsmsq; //按键扫描计数器
uchar KeyTime;
/*****************************************************************************
键盘初始化
*****************************************************************************/
void InitKey()
{
KEYDIR &= ~(KEY0+KEY1+KEY2+KEY3); //设置端口为输入
KEYIES |= (KEY0+KEY1+KEY2+KEY3); //设置下降沿中断
KEYIE |= (KEY0+KEY1+KEY2+KEY3); //打开端口中断
}
/*****************************************************************************
打开或者关闭键盘中断
sw: 0:关闭 100:打开
*****************************************************************************/
void GoKey(uchar sw)
{
if(sw==0)
KEYIE &= ~(KEY0+KEY1+KEY2+KEY3); //关闭端口中断
else
KEYIE |= (KEY0+KEY1+KEY2+KEY3); //打开端口中断
}
/*****************************************************************************
获得键值
返回值:按下的有效的键的键值
*****************************************************************************/
uchar GetKeyZhi(void)
{
uchar temp;
temp=KeyZhi;
KeyZhi=KEY_NONE; //清除键值
return temp;
}
/*****************************************************************************
判断按键的有效性
*****************************************************************************/
void IsKey()
{
if((KEYIN&KEY_MOD)==KEY_MOD)
{
//没有键按下
KeyDown=KEY_NONE;
//TACTL&=~TAIE; //关闭定时器A溢出中断
GoKey(100); //打开键盘中断
}
else
{
if(KeyTime==0)
{
//连续按键的时间到
KeyTime=KEY_TIME;
if((KEYIN|KEY0==KEY0)&&(KeyDown==KEY_P10))
{
//P1.0按键按下
KeyZhi=KEY_P10;
}
else if((KEYIN|KEY1==KEY1)&&(KeyDown==KEY_P11))
{
//P1.1按键按下
KeyZhi=KEY_P11;
}
else if((KEYIN|KEY2==KEY2)&&(KeyDown==KEY_P12))
{
//P1.2按键按下
KeyZhi=KEY_P12;
}
else if((KEYIN|KEY3==KEY3)&&(KeyDown==KEY_P13))
{
//P1.3按键按下
KeyZhi=KEY_P13;
}
else
{
KeyDown=KEY_NONE;
//TACTL&=~TAIE; //关闭定时器A溢出中断
GoKey(100); //打开键盘中断
}
}
else
{
KeyTime--;
}
}
}
/*****************************************************************************
调用方式:void power(void)
函数说明:开启/关闭加热处理
*****************************************************************************/
void power(void)
{
switch(set)
{
case 0:
break;
case 1:
{
hot_flag^=BIT7;
if((hot_flag&0x80)==0x80)
TBCTL|=MC0;
}
break;
case 2:
{
hot_flag^=BIT6;
if((hot_flag&0x40)==0x40)
TBCTL|=MC0;
}
break;
default:
break;
}
}
/*****************************************************************************
调用方式:void func(void)
函数说明:设定键处理
*****************************************************************************/
void func(void) //设定键
{
set++; //0:退出 1:温度1区 2:温度2区
if(set>=3)
set=0;
}
/*****************************************************************************
调用方式:void add(void)
函数说明:加1键处理
*****************************************************************************/
void add(void)
{
switch(set)
{
case 0:
break; //set=0,退出
case 1:
{
set_temper1++;
if(set_temper1>=56)
set_temper1=37; //温度1区加,最高到56度
}
break;
case 2:
{
set_temper2++;
if(set_temper2>=70)
set_temper2=56; //温度2区加,最高到70度
}
break;
default:
break;
}
}
/*****************************************************************************
调用方式:void sub(void)
函数说明:减1键处理
*****************************************************************************/
void sub(void)
{
switch(set)
{
case 0:
break; //set=0,退出
case 1:
{
set_temper1--;
if(set_temper1<=20) //温度1区减,最高到20度
set_temper1=37;
}
break;
case 2:
{
set_temper2--;
if(set_temper2<=37) //温度2区减,最高到37度
set_temper2=56;
}
break;
default:
break;
}
}
/*****************************************************************************
端口1中断函数
多中断中断源:P1IFG.0~P1IFG7,只用到P1.4 P1.5 P1.6 P1.7四个中断源
进入中断后应首先判断中断源,退出中断前应清除中断标志,否则将再次引发中断
******************************************************************************/
#pragma vector=PORT1_VECTOR
__interrupt void Port1()
{
uchar q0=0;
if((KEYIFG&KEY0) ==KEY0)
{
//处理P1IN.0中断
KEYIFG &= ~KEY0; //清除中断标志
KeyDown=KEY_P10; //记录按下的键值
q0=1;
}
else if((KEYIFG&KEY1) ==KEY1)
{
//处理P1IN.1中断
KEYIFG &= ~KEY1; //清除中断标志
KeyDown=KEY_P11; //记录按下的键值
q0=1;
}
else if((KEYIFG&KEY2) ==KEY2)
{
//处理P1IN.2中断
KEYIFG &= ~KEY2; //清除中断标志
KeyDown=KEY_P12; //记录按下的键值
q0=1;
}
else if((KEYIFG&KEY3) ==KEY3)
{
//处理P1IN.3中断
KEYIFG &= ~KEY3; //清除中断标志
KeyDown=KEY_P13; //记录按下的键值
q0=1;
}
else
{
//其他干扰引起的中断,不进行处理,只清除中断标志
KEYIFG=0;
}
if(q0==1)
{
GoKey(0); //关闭键盘中断
KeyTime=0;
//TACTL|=TAIE; //打开定时器A溢出中断,10s无按键关背光
//timera_init(); //送timera初始值
//__bic_SR_register_on_exit(LPM0_bits); //退出低功耗模式
}
}
问题主要是+1键有时和-1键串,set键有时也混,我的按键上拉10k电阻。
我在定时器A里20ms扫描一次按键:IsKey()
哇塞,一大段程序发上去,然后自己解决了,有意思,呵呵!