日志档案

发表于 2007-12-9 19:18:25

0

标签: 键盘扫描  

4*4键盘扫描

                      4*4键盘扫描文档

  今天把4*4键盘的程序从单片机上移植到了NIOS上。

   4*4键盘扫描电路

 

 

程序采用间隔时间进行扫描法,由于键盘的抖动时间为10ms-20ms之间,所以在定时器中加入一个标志位,当定时10ms后,就进入判断,采用类似FPGA的状态机法,进行扫描。有效的避开了抖动。

状态一,判断是否有键按下,有键按下,则转到状态二。

状态二:再进行判断有没键按下,有按下,则进行扫描,进入状态三。没有,则返回状态一。

   状态三: 根据行码,和列码进行判断键值,根据相应的键值执行相应的程序。进入状态四

   状态四: 判断键是否释放,松开,则返回状态一,没有,则在状态四。

首先分为行信号(key4—key7),作为输入端口,用于读取IO口上的电平值,初始时写0

列信号(key0---key3),作为输出端口,为送入扫描信号。

在初始时,将所有的列信号(输出口)(key3—key3)置为低电平,在没有任何键按下时,读取(输入口)key4—key7上的电平值将为1,当任何一个按键按下时,则key4-key7中将会有一行被拉低,则表示有键按下。

这时就开始从key0-key3送入扫描字,进行扫描。扫描字为0111,101111011110

如果在它的输入端口发现一个0值,则就知道了在哪一列上有键按下。没有的话,则扫描字左移,继续扫描。根据行值,列值,来读出键值。

 

根据上面的接口电路。Key7—key0对应着键盘的接口高位到低位。

假如:开始key7-key4作为输入口,由于上拉电阻,则读出的数据为1key0-key3作为输出口,写低电平。当键S4按下时,则Key4电平被拉低,判断出在第一行上有键按下。这时,进行扫描。在key0-key3送入扫描字1110,读取key4-key7口上电平,发现key4上的电平为0,则判断出第四列有键按下。则得出s4键按下。键值为key7:key0=1110 (行码)&1110(列扫描字)==1110 1110以此累推。

 

总结:经过移植几种程比较,这种效率最高。而且占用的时间比较少。不过在NIOS上移植,可以结合FPGA,直接做个4*4键盘扫描控制器,当有键按下时,可以进入中断。这样的话,节省了CPU的时间。当有键按下时,送出键按下标志位。进入中断。读取键值,执行键盘程序。可见NIOS的强大功能,和可配置性,还有很多东西待去学习。

/**********************************************************

*功能: 键盘扫描函数

*说明:

*********************************************************/

unsigned char read_key(void)

{

   unsigned char i;

   unsigned char key_return = 0;

  

   IOWR_ALTERA_AVALON_PIO_DIRECTION(KEY_PIO_BASE,0X0f);

   //高四位作为输入,读取数据,低四位为输出

   Key_data=0x00;//低四位输出口写0

    switch (key_state)

  {

      case 0:

           // 读按键高四位I/O电平,当有键按下时为0,没按下时为1 

    if((IORD_ALTERA_AVALON_PIO_DATA(KEY_PIO_BASE)&0xf0)==0xf0)

      {

              break;//无键按下返回

      }

     else

      {

             key_state=1; //有键按下      

      }break;

     

      case 1://进行扫描键值

             {

       if((IORD_ALTERA_AVALON_PIO_DATA(KEY_PIO_BASE)&0xf0)==0xf0)

                                                      //读取高四位电平

         {

              break;//无键按下返回,是误动作

         }

      else

        { //有键按下去抖

                    key_line=0x08;

                    for(i=1;i<=4;i++)

                    {

                           Key_data=~key_line;//1111 0111

                           key_value=0xf0&IORD_ALTERA_AVALON_PIO_DATA(KEY_PIO_BASE);

                           if (key_value == 0xf0)

        {

          key_line >>= 1;       // 没有按键,继续扫描

        }

        else

        {

          key_state=2;          // 有按键,停止扫描,转入下一个状态

         }

                    }

              }

             }

            

             case 2:

       {

            switch (key_line|key_value) //0000 1000

             {

                 case 0x78:

              key_return=1;break;

           case 0x74:

              key_return=2;break;

           case 0x72:

              key_return=3;break;

           case 0x71:

              key_return=4;break;

           case 0xb8:

              key_return=5;    break;

           case 0xb4:

              key_return=6;break;

           case 0xb2:

              key_return=7;break;

           case 0xb1:

              key_return=8;break;

            case 0xd8:

              key_return=9;break;

           case 0xd4:

              key_return=10;break;

           case 0xd2:

              key_return=11;break;

           case 0xd1:

              key_return=12;break;

            case 0xe8:

              key_return=13;    break;

           case 0xe4:

              key_return=14;break;

           case 0xe2:

              key_return=15;break;

           case 0xe1:

              key_return=16;break;  

            }  

        key_state = 3;  // 状态转换到键释放态

        

        } break;

       

       case 3:       //键已经释放,确认了有键按下

       

        {

        Key_data=0xf0;//低四位写0,高四位作为输入口,不受影响

       if((0xf0&IORD_ALTERA_AVALON_PIO_DATA(KEY_PIO_BASE))==0xf0)

        key_state = 0;

        }

         break; //按键已释放,转换到按键初始态

       

      

      }

      return key_return;         //当返回为0时,表示没有键按下,

  }        

 

系统分类: 汽车电子   |   用户分类: NIOS的学习   |   来源: 原创   |   【推荐给朋友】

    阅读(1096)    回复(3)  

投一票您将和博主都有获奖机会!

  • 虫子

    2007-12-11 9:44:45

    有个问题?就是如果我HOLD着一个键不放,再按别的键的话那别的键就没有功能出了是吧?能否做到在这样的情况下也别的按键也有功能呢?

  • jianglongjian

    2007-12-11 13:31:09

    这里是只有当键释放了,才能往下执行的..要想达到你的要求,要在程序里面再处理一下,应该是可以达到的. 这个要看程序具体要怎么写的.

  • CESAD

    2007-12-12 12:47:11

    多个按键同时按下了怎么处理??