矩阵键盘

2019-03-24 20:39发布

C:Userszhoukai53670


#include<avr/io.h>
#include<avr/delay.h>

int main()
{       
        char temp,key;
        DDRA = 0x0f;
        while(1)
        {
                PORTA = 0x08;//设置行4输出高电平,其它为低电平
                temp = PINA;//读取PA口电平
                temp &= 0xf0;//屏蔽行电平
                if(temp != 0x00)//是否有按键按下
                {
                        _delay_ms(20);//延时20ms消抖
                        temp = PINA;//再次读取PA口电平
                        temp &= 0xf0;//屏蔽行电平
                        if(temp != 0x00)//确认有按键按下
                        {
                                temp = PINA;
                                temp &= 0xf0;
                                switch(temp)
                                {
                                        case 0x10 : key =1;break;
                                        case 0x20 : key =2;break;
                                        case 0x40 : key =3;break;
                                        case 0x80 : key =4;break;
                                }
                        }

                }
                while(temp != 0x00)//松手检测
                {
                        temp = PINA;
                        temp &= 0xf0;
                }



                PORTA = 0x04;//设置行3输出高电平,其它为低电平
                temp = PINA;//读取PA口电平
                temp &= 0xf0;//屏蔽行电平
                if(temp != 0x00)//是否有按键按下
                {
                        _delay_ms(20);//延时20ms消抖
                        temp = PINA;//再次读取PA口电平
                        temp &= 0xf0;//屏蔽行电平
                        if(temp != 0x00)//确认有按键按下
                        {
                                temp = PINA;
                                temp &= 0xf0;
                                switch(temp)
                                {
                                        case 0x10 : key =5;break;
                                        case 0x20 : key =6;break;
                                        case 0x40 : key =7;break;
                                        case 0x80 : key =8;break;
                                }
                        }

                }
                while(temp != 0x00)//松手检测
                {
                        temp = PINA;
                        temp &= 0xf0;
                }



                PORTA = 0x01;//设置行2输出高电平,其它为低电平
                temp = PINA;//读取PA口电平
                temp &= 0xf0;//屏蔽行电平
                if(temp != 0x00)//是否有按键按下
                {
                        _delay_ms(20);//延时20ms消抖
                        temp = PINA;//再次读取PA口电平
                        temp &= 0xf0;//屏蔽行电平
                        if(temp != 0x00)//确认有按键按下
                        {
                                temp = PINA;
                                temp &= 0xf0;
                                switch(temp)
                                {
                                        case 0x10 : key =9;break;
                                        case 0x20 : key =10;break;
                                        case 0x40 : key =11;break;
                                        case 0x80 : key =12;break;
                                }
                        }

                }
                while(temp != 0x00)//松手检测
                {
                        temp = PINA;
                        temp &= 0xf0;
                }



                PORTA = 0x01;//设置行1输出电平,其它为低电平
                temp = PINA;//读取PA口电平
                temp &= 0xf0;//屏蔽行电平
                if(temp != 0x00)//是否有按键按下
                {
                        _delay_ms(20);//延时20ms消抖
                        temp = PINA;//再次读取PA口电平
                        temp &= 0xf0;//屏蔽行电平
                        if(temp != 0x00)//确认有按键按下
                        {
                                temp = PINA;
                                temp &= 0xf0;
                                switch(temp)
                                {
                                        case 0x10 : key =13;break;
                                        case 0x20 : key =14;break;
                                        case 0x40 : key =15;break;
                                        case 0x80 : key =16;break;
                                }
                        }

                }
                while(temp != 0x00)//松手检测
                {
                        temp = PINA;
                        temp &= 0xf0;
                }
        }

}       
哪位大哥帮我看一看这个程序有什么问题?
我用PROTUES仿真的时候,当按键被按下后,对应被设置为输入的IO口就出现高电平,这是正常的,可是我松手后对应被设置为输入的IO口还是高电平,感觉像是开关没有弹起一样,后来试了好久都找不到原因。后来我注释掉其中三行,只留一行按键却很正常,哪位大哥帮我看一看,我真的很想知道原因。 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
Li_Lei
1楼-- · 2019-03-24 22:10
你的扫描输出是输出口,扫描输入相应io口如果设置成输入上拉就用低电平扫比如1110,1101,1011,...
如果是输入下拉状态就用高电平扫,比如0001,0010,0100,1000...
Li_Lei
2楼-- · 2019-03-25 03:57
估计你没有输入下拉
zhaojun_xf
3楼-- · 2019-03-25 06:06
/*****************************************************
函 数 名:uchar Key_scan(void)
功    能:4x4按键,按键扫描
说    明:对按键进行扫描,从而得到键编码
入口参数:无
返 回 值:有键按下返回:键编码=行扫描值+列扫描值;无按键返回0  
*****************************************************/
uchar Key_scan(void)
{
  uchar key;         // 存放键编码
  P1=0xf0;           // 取高 4 位值.即:列扫描值
  key=P1&0xf0;       // 存放键编码的高4位
  P1=0x0f;           // 取低 4 位值.即:行扫描值
  key=(P1&0x0f)|key; // 低4位与高4位进行合并
  if(key!=0xff)
  {
    return(key);     // 有键按下,返回键编码
  }
    return(0);       // 无键按下,返回0
}

/*****************************************************
函 数 名:uchar Key_switch(void)
功    能:按键转换程序
说    明:对按键码进行转换
入口参数:无
返 回 值:ASCII码  
*****************************************************/
uchar Key_switch(void)
{
   uchar key;
   key=Key_scan();
   Delay5Ms();
   switch(key)
   {
      case 0xee:return(49);break;   /* "1"键  */
          case 0xed:return(50);break;   /* "2"键  */
          case 0xeb:return(51);break;   /* "3"键  */
          case 0xe7:return(65);break;   /* "A"键  */
      case 0xde:return(52);break;   /* "4"键  */
          case 0xdd:return(53);break;   /* "5"键  */
          case 0xdb:return(54);break;   /* "6"键  */
          case 0xd7:return(66);break;   /* "B"键  */                                 
          case 0xbe:return(55);break;   /* "7"键  */                             
          case 0xbd:return(56);break;   /* "8"键  */
          case 0xbb:return(57);break;   /* "9"键  */
          case 0xb7:return(67);break;   /* "C"键  */
          case 0x7e:return(42);break;   /* "*"键  */
          case 0x7d:return(48);break;   /* "0"键  */
          case 0x7b:return(35);break;   /* "#"键  */
          case 0x77:return(68);break;   /* "D"键  */
          case 0x00:return(00);break;   /* "无"键  */
   }

   return(00);
}
Timson
4楼-- · 2019-03-25 11:59


[ 本帖最后由 Timson 于 2013-7-2 10:04 编辑 ]

一周热门 更多>