Createdon:2012-9-6Author:zhangbin
本文引用地址:https://www.eepw.com.cn/article/201611/322846.htm
学习笔记
formsp430g2553
redesignedbyzhangbin
2012-09-06
versions:12_09_01
AllRightsReserved
这里主要记录我的使用矩阵键盘输入数据的方法。在系统的设计中,输入数据是经常遇到的,而矩阵键盘是最常用的输入设备。如果矩阵键盘的扫描没有了问题,那么怎样用矩阵键盘输入数据呢,例如我要输入253.45这个数,该怎么实现呢。
下面是我用的两个实现方法:
一、是借用一个诡异的值,也就是键盘扫描时不可能扫到的值,这个数与键盘完全无关,主要是用来标志有新的按键按下。我使用的是msp430g2553的中断检测按键的,原理是任意一个按键按下时,就会进入中断函数,然后在中断中再进行判断按下的是哪一个键。能够实现这种方法的基础是msp430g2553的一个IO口组(比如P1,P2)的8个IO口都共用一个中断向量,一组中,无论哪一个IO口触发了中断,都会进入同一个中断中。所以这样就可以用中断来判断有没有按键按下了,然后在中断中再进行进一步判断按下的是哪一个按键。这样比使用循环扫描的方法节省了不少单片机的资源,不用按键时,不用一直循环扫描按键。其中键盘中断部分的程序如下:
//Port1interruptserviceroutine
#pragmavector=PORT1_VECTOR
__interruptvoidPort_1(void)
{
uchartemp;
_DINT();//关中断
P1DIR&=~(BIT0+BIT1+BIT2+BIT3);//在中断设为输入,用于消抖因为IO脚默认为输入,所以这句话不要也行,但是
//最好加上使程序清晰
delay_ms(5);//延迟5ms,消抖延迟5ms10ms都行
temp=P1IN&0x0f;//提取连接按键的4位IO的值
key=99;//给key一个诡异的值,也就是键盘扫面时,不可能扫到的值,这个值完全与键盘无关,在这里也就是1~15以外的值
//主要是用来标志有新的按键按下
if(temp==0x01)
{
key=1;
}
elseif(temp==0x02)
{
key=2;
}
elseif(temp==0x03)
{
key=3;
}
elseif(temp==0x04)
{
key=4;
}
elseif(temp==0x05)
{
key=5;
}
elseif(temp==0x06)
{
key=6;
}
elseif(temp==0x07)
{
key=7;
}
elseif(temp==0x08)
{
key=8;
}
elseif(temp==0x09)
{
key=9;
}
elseif(temp==0x0a)
{
key=0;
}
elseif(temp==0x0b)
{
key=11;
t_flag=3;//t_flag=0表示只进行温度的检测,不进行控制
key_flag=1;//设置温度
key_count=0;
key=99;
set_t=0.0;//先把温度值设为0
}
elseif(temp==0x0c)
{
key=12;
t_flag=4;
key_flag=2;//设置时间
key_count=0;
key=99;
set_time=0;//先把温度值设为0
}
elseif(temp==0x0d)//40°
{
key=13;
t_flag=1;
}
elseif(temp==0x0e)
{
key=14;
t_flag=2;//60
}
elseif(temp==0x0f)
{
key=15;
t_flag=0;//t_flag=0表示只进行温度的检测,不进行控制
}
if(key_flag==1)//设定温度
{
if(key!=99)
{
set_t=set_t*10+key;
//wr_int(4,1,set_t);
key=99;
key_count++;
//wr_int(3,3,key_count);
if(key_count==4)
{
set_t=(float)set_t/10;
wr_float_3(4,1,set_t);//显示设定的温度值
key_flag=0;
key_count=0;
}
}
}
if(key_flag==2)//设定时间
{
if(key!=99)
{
set_time=set_time*10+key;
wr_int(4,2,set_time);//显示设定的时间
key=99;
key_count++;
//wr_int(3,2,key_count);
if(key_count==4)
{
set_time_1=set_time;//中间缓冲值替换掉set_time,因为set_time在中断中很敏感,很容易乱码
//wr_int(3,2,set_time);
int_flag=1;//时间设置标志位置位
key_flag=0;
key_count=0;
}
}
}
//wr_int(0,1,key);//显示
P1IFG&=~(BIT0+BIT1+BIT2+BIT3);//P1.3IFGcleared软件清除中断标志位
_EINT();//打开中断
}
二,是使用一个数组暂存按下的值,然后在进行组合,成为想要的值。数组中元素的个数为为想要输入的数据的总的位数,程序如下:
//Port1interruptserviceroutine
#pragmavector=PORT1_VECTOR//P1口中断,键盘中断
__interruptvoidPort_1(void)
{
uchari=0;
ucharj=0;
_DINT();//键盘处理,关闭中断
key_interrupt_flag=1;
if((key_flag==1)||(key_flag==2))//如按下了设定温度或时间键,开始计数
{
key_count++;//用于计数按下键的次数,好实现输入设定的温度和时间
}
key=rd_key();//读取键值
//while((P1IN&BIT3)==0);//等待按键松开
for(i=0;i<10;i++)
{
if(key==key_code[i])//利用数组进行键值转化
key=i;//转化为了对应的数字
}
wr_int(2,1,key);//显示
if(key==60)//*键设定温度
{
key_flag=1;//置1
}
elseif(key==62)//#键设定时间
{
key_flag=2;
}
elseif(key==47)//B:40°键
{
set_t=40;
set_t_flag=1;//温度设为40°,标志位为1
set_t_flag_1=set_t_flag;
wr_float_1(1,0,set_t);//显示设定温度值
}
elseif(key==55)//C:60°键
{
set_t=60;
set_t_flag=2;//温度设为60°,标志位为2
set_t_flag_1=set_t_flag;
wr_float_1(1,0,set_t);//显示设定温度值
}
if((key_count==1)&&(key<=9))
{
a[0]=key;
}
elseif((key_count==2)&&(key<=9))
{
a[1]=key;
}
elseif((key_count==3)&&(key<=9))
{
a[2]=key;
}
elseif((key_count==4)&&(key<=9))
{
a[3]=key;
}
if(key_flag==1)//温度控制
{
set_t=a[0]*1000+a[1]*100+a[2]*10+a[3];
set_t=set_t/10;
wr_float_1(1,0,set_t);//显示设定温度值
control_flag=1;//温度控制
control_flag_1=control_flag;//暂存起来
wr_int(0,3,control_flag);//显示状态,便于观察,调试时用
set_t_flag=3;//温度设为任意温度,标志位为3
set_t_flag_1=set_t_flag;
}
if(key_flag==2)//时间控制
{
set_time=a[0]*1000+a[1]*100+a[2]*10+a[3];
set_time=set_time/10;
wr_float_1(5,0,set_time);//显示设定时间值
control_flag=2;//时间控制
control_flag_1=control_flag;//暂存起来
wr_int(0,3,control_flag);//显示状态,便于观察,调试时用
second=0;//秒数计时清零,开始计时
wr_int(0,2,second);//显示秒
time_m=0;//时间段清零
}
if(key_count==4)//设定完成设定温度和设定时间只能为xxx.x的形式
{
key_count=0;
key_flag=0;
for(j=0;j<4;j++)
{
a[j]=0;//数组清零
}
}
if(key==39)//A:温度控制开启或取消键按一下开启,再按一下取消
{
if(control_flag!=0)
control_flag=0;
elseif(control_flag==0)
{
control_flag=control_flag_1;//还原
}
wr_int(0,3,control_flag);//显示状态,便于观察,调试时用
if(set_t_flag!=0)
set_t_flag=0;
elseif(set_t_flag==0)
{
set_t_flag=set_t_flag_1;//还原
}
}
P1IFG&=~BIT3;//中断标志位清零
_EINT();//打开中断
}
//对应按键功能:*:设定温度键#:设定时间键A:温度控制开启或取消键按一下开启,再按一下取消B:40°键C:60°键
评论