打印

msp430g2553的矩阵按键程序

[复制链接]
6556|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
e_hcwi66|  楼主 | 2012-9-23 09:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
IAR环境下的程序!
矩阵按键在单片机设计中经常见到,下面给大家几个程序!如果有需求可以看看!
矩阵按键,扫描
下面程序是淘来的!
#include<msp430g2553.h>
/***************全局变量***************/
unsigned char Key_Val;          //存放键值
void CtrlKey(unsigned char sw); //控制键盘开关//sw=0关 sw=1开
/*******************************************
函数名称:Init_Keypad
功    能:初始化扫描键盘的IO端口
参    数:无
返回值  :无
********************************************/
void Init_Keypad(void)
{     
  P1DIR = 0x0f;       //P1.0~P1.3设置为输出状态,P1.4~P1.7输入 状态(上拉H)
  P1OUT=0;
  P1IES =0xf0;    //P1.4~P1.7允许中断
  P1IE  =0xf0;   //P1.4~P1.7下降沿触发中断
  P1IFG=0;      //中断标志清0
  Key_Val = 0;
}

/*******************************************
函数名称:Check_Key
功    能:扫描键盘的IO端口,获得键值
参    数:无
返回值  :无
********************************************/
//p14\5\6\7 接上拉电阻
/***************************************
            key_Val 对应键值
        列:[p14]  [p15]  [p16]   [p17]
             ↓     ↓     ↓     ↓
行:
[p13]→      1      2      3      4   
[p12]→      5      6      7      8   
[p11]→      9     10     11     12   
[p10]→     13     14     15     16   
***************************************/
void Check_Key(void)
{
  unsigned char row ,col,tmp1,tmp2;
  unsigned char keymap[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};//设置键盘逻辑键值
  
  tmp1 = 0x08;
  for(row = 0;row < 4;row++)              //行扫描
  {
    P1OUT = 0x0f;                       //P1.0~P1.3输出全1
    P1OUT -= tmp1;                      //P1.0~p1.3输出四位中有一个为0
    tmp1 >>=1;                              
    if((P1IN & 0xf0)<0xf0)              //是否P1IN的P1.4~P1.7中有一位为0
    {                       
      tmp2 = 0x10;                        // tmp2用于检测出哪一位为0  
      for(col = 0;col < 4;col++)          // 列检测
      {         
        if((P1IN & tmp2) == 0x00)       // 是否是该列,等于0为是
        {         
          Key_Val = keymap[row*4 + col];  // 获取键值
          return;                         // 退出循环
        }
        tmp2 <<= 1;                       // tmp2右移1位
      }
    }
  }      
}

/*******************************************
函数名称:delay
功    能:延时约15ms,完成消抖功能
参    数:无
返回值  :t= tmp*5*clk 根据使用时钟调整tmp值
********************************************/
void delay(void)
{
    unsigned int tmp;
     
    for(tmp = 12000;tmp > 0;tmp--);
}
/*******************************************
函数名称:Key_Event
功    能:检测按键,并获取键值
参    数:无
返回值  :无
********************************************/
void Key_Event(void)
{     
    unsigned char tmp;
     
    P1OUT =0;                  // 设置P1OUT全为0,等待按键输入
    tmp = P1IN;                // 获取 p1IN
    if((tmp & 0xf0) < 0xf0)      //如果有键按下
    {                     
        delay();                 //消除抖动
        Check_Key();             // 调用check_Key(),获取键值
    }     
}


/*********************************************************************
控制打开或者关闭键盘中断
SW= 0:关闭;   ELSE:打开
*********************************************************************/
void CtrlKey(unsigned char sw)
{
if(sw==0)
   P1IE =0;     //关闭端口中断
else
           P1IE =0xf0; //打开端口中断
}

/*端口1按键中断*/
#pragma vector=PORT1_VECTOR
__interrupt void Port(void)
{
  if((P1IFG&0xf0)!=0)
  {  
    Key_Event();
    if(Key_Val!=0)         //键值!=0有键按下
    {
      CtrlKey(0);         //关键盘中断
    }
  }
  
  P1IFG=0;P1OUT=0;   //清中断标志
}
下面的程序是自己改了下,端口发生了变化!
按键矩阵也发生了变化!
/***********************************************************************************************************************************************************/
#include<msp430g2553.h>

/***************全局变量***************/
unsigned char Key_Val;          //存放键值
void main()
{
  WDTCTL=WDTPW+WDTHOLD;
  Init_Keypad();
  _BIS_SR(LPM3_bits + GIE); //最低功耗睡眠
   while(1);
}
/*******************************************
函数名称:Init_Keypad
功    能:初始化扫描键盘的IO端口
参    数:无
返回值  :无
********************************************/
void Init_Keypad(void)
{     
  P1DIR = 0x38; //P1.0~P1.3设置为输出状态,P1.4~P1.7输入 状态(上拉H)
  P1OUT=0;
   
P1IES =0xC0;    //P1.4~P1.7允许中断
  P1IE  =0xC0;   //P1.4~P1.7下降沿触发中断
  P1IFG=0;      //中断标志清0
  Key_Val = 0;
}

/*******************************************
函数名称:Check_Key
功    能:扫描键盘的IO端口,获得键值
参    数:无
返回值  :无
********************************************/
//p13\14\15 接上拉电阻
/***************************************
            key_Val 对应键值
        列:[p13]  [p14]  [p15]   
             ↓     ↓     ↓   
行:
[p17]→      1      2      3        
[p16]→      4      5      6        

***************************************/
void Check_Key(void)
{
  unsigned char row ,col,tmp1,tmp2;
  unsigned char keymap[] = {1,2,3,4,5,6};//设置键盘逻辑键值
  
  tmp1 = 0x08;                        //从(xxxx1xxx相左移)
  for(row = 0;row < 3;row++)              //列扫描
  {
    P1OUT = 0x38;                       //P1.3~P1.5输出全1
    P1OUT -= tmp1;                      //P1.3~p1.5输出四位中有一个为0
    tmp1 <<=1;                              
    if((P1IN & 0xC0)<0xC0)              //是否P1IN的P1.4~P1.7中有一位为0
    {                       
      tmp2 = 0x80;                        // tmp2用于检测出哪一位为0  
      for(col = 0;col < 2;col++)          // 行检测
      {         
        if((P1IN & tmp2) == 0x00)       // 是否是该列,等于0为是
        {         
          Key_Val = keymap[row*4 + col];  // 获取键值
          return;                         // 退出循环
        }
        tmp2 >>= 1;                       // tmp2右移1位
      }
    }
  }      
}

/*******************************************
函数名称:delay
功    能:延时约15ms,完成消抖功能
参    数:无
返回值  :t= tmp*5*clk 根据使用时钟调整tmp值
********************************************/
void delay(void)
{
    unsigned int tmp;
     
    for(tmp = 12000;tmp > 0;tmp--);
}
/*******************************************
函数名称:Key_Event
功    能:检测按键,并获取键值
参    数:无
返回值  :无
********************************************/
void Key_Event(void)
{     
    unsigned char tmp;
     
    P1OUT =0;                  // 设置P1OUT全为0,等待按键输入
    tmp = P1IN;                // 获取 p1IN
    if((tmp & 0xf0) < 0xf0)      //如果有键按下
    {                     
        delay();                 //消除抖动
        Check_Key();             // 调用check_Key(),获取键值
    }     
}

#pragma vector=PORT1_VECTOR
__interrupt void Port(void)
{
   delay();
    if((P1IN&0XC0)<0XC0)
  {
   
    Check_Key();
  switch(Key_Val)
  {
  case 1:
    {         ;自己接相应按键的功能
      break;
    }
  case 2:
     {      ;自己接相应按键的功能

       break;
     }
  case 3:
     {     ;自己接相应按键的功能

       break;
     }
  case 4:
     {     ;自己接相应按键的功能

       break;
     }
  case 5:
     {    ;自己接相应按键的功能

       break;
     }
  case 6:
     {   ;自己接相应按键的功能

       break;
     }
  default:break;
      
  }
  }
    P1IFG=0;   //清中断标志
  }
下面这个按键用了数组了,存放按键的值,可以应用于密码锁之类的应用!为网上淘来
/************************************************************************************************************************************************************/
// 此示例程序为中断方式,得到键盘的键值,存放在队列keybuff[10]中
// 此示例程序没有显示,
// 键盘的按键按下引起P1口的中断服务程序,得到键盘的键值,保存到键值队列
// 在其他的中断服务程序中通过键值队列中的数据引导程序的流程
#include <msp430x14x.h>  
unsigned char keybuff[10];
unsigned char keypoint=0;
void delay(int v)
    {
        while(v!=0)v--;
    }

unsigned char key(void)
  {
    unsigned char x=0xff;
    P1DIR=0X0F;
    P1OUT=0X01;                 //扫描第一行
    if((P1IN&0X70)==0X10)      
       x=0;
       else
          if((P1IN&0X70)==0X20)
            x=1;
                else
                  if((P1IN&0X70)==0x40)
                    x=2;
       else
        {
          P1OUT=0X2;            //扫描第二行
          if((P1IN&0X70)==0X10)
             x=3;
             else
               if((P1IN&0X70)==0X20)
                  x=4;
                    else
                      if((P1IN&0X70)==0x40)
                        x=5;
           else
           {
            P1OUT=0X4;           //扫描第三行
            if((P1IN&0X70)==0X10)
            x=6;
              else
                if((P1IN&0X70)==0X20)
                x=7;
                  else
                  if((P1IN&0X70)==0x40)
                    x=8;
             else
             {P1OUT=8;           //扫描第四行
             if((P1IN&0X70)==0X10)
       x=9;
       else
          if((P1IN&0X70)==0X20)
            x=10;
                else
                  if((P1IN&0X70)==0x40)
                    x=11;
                    }
             }      
         }   
  return(x);
  }
  
  
unsigned char keyj(void)
    {unsigned char x;
    P1DIR=0x0f;
    P1OUT=0x0f;        //键盘硬件:P10--P13为行线,最上面一根为P10
    x=(P1IN&0X70);      //         P14--P16为列线,最左边一根为P14,列线下拉
    return(x);          // 无按键,返回 0?;  有按键返回 非0
    }  
     
      
interrupt[PORT1_VECTOR] void port1key(void)
        {
        if(keyj()!=0X00)
           {
           delay(300)  ;   //消抖动
               if(keyj()!=0X0)
                 {
                    keybuff[keypoint]=key();    //按键见键值保存到队列
                    keypoint++;                 //
                    if(keypoint==10)
                         keypoint=0;
                  }
            }
         P1OUT=0X0F;
         P1IFG=0X0;         //清除中断标志
        }

   

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;  /*   // Stop WDT */
  P1DIR=0XF;
  P1OUT=0XF;
  P1IES=0X0;
  P1IE=0X70;    //列线上升沿允许P1中断
   _EINT();                      /*/ Enable interrupts                 */
  
  while(1)
  {
  
     LPM0;                  
    _NOP();   
   
  }
}
这个是单个按键是,输入端的P1REN要设为1。允许上拉电阻!为网上淘来
/************************************************************************************************************************************************************/
关于msp430g2553的按键程序,虽然很简单,但是纠结了一个下午,错就错在看视频的时候那个老师的片子没有加上拉电阻但是正常运行,我的却不可以,现在找到问题,希望对和我一样遇着这个问题的人有所帮助;

#include "msp430g2553.h"
#define keyin (P1IN & 0x08)
void delay(void);

int main(void)
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
  
  P1REN |= BIT3;
  P1DIR |= BIT6;
  P1OUT &= ~BIT6;

  while(1)
  {
    if(keyin != 0x08)
    {
       delay();
       if(keyin != 0x08)
       {
         while(keyin !=0x08);
         P1OUT ^= BIT6;
       }
    }
  }
}



void delay(void)
{
  unsigned int i;
  for(i=12000; i>0; i--);
}


有意见的读者,可以评论,希望帮到大家了!

相关帖子

沙发
happy啦啦啦| | 2012-9-23 14:46 | 只看该作者
这个程序对于初学单片机的人来说,很有帮助的

使用特权

评论回复
板凳
lasbell2012| | 2012-9-23 15:02 | 只看该作者
还是很有用的,刚开始学习,谢谢楼主

使用特权

评论回复
地板
wjzx111056| | 2012-9-23 19:17 | 只看该作者
嗯,很基础的程序,对初学者很有用,谢谢楼主的分享~~~~~~~~~~~~~~

使用特权

评论回复
5
zyp0322| | 2013-7-14 09:37 | 只看该作者
这两个程序都能显示吗

使用特权

评论回复
6
firstblood| | 2013-7-14 19:48 | 只看该作者
该程序还是蛮不错的,挺一下的了

使用特权

评论回复
7
hawksabre| | 2013-7-14 20:32 | 只看该作者
顶一个   楼主   谢谢你的共享   谢谢

使用特权

评论回复
8
心静坚持| | 2013-7-24 15:43 | 只看该作者
都错的:sleepy:

使用特权

评论回复
9
buyashenshi| | 2013-8-22 01:26 | 只看该作者
感谢楼主啊,呵呵呵,真心不错。

使用特权

评论回复
10
无酒亦醉| | 2014-8-31 16:07 | 只看该作者
谢谢楼主,正在学习

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

7

帖子

0

粉丝