精华内容
下载资源
问答
  • 独立式按键与矩阵键盘原理; 按键在闭合和断开瞬间会因弹簧开关的变形而产生电压波动现象其按键抖动波形如图 ;二. 逐行扫描法与行列互换法;二. 逐行扫描法与行列互换法;二. 逐行扫描法与行列互换法;二. 逐行扫描法...
  • 初学者肯定要经历的一个实验就是4*4矩阵键盘的代码编写,大部分都是在学校里面,有现成的实验箱,基本不需要自己动脑子。上次遇到一个哥们,他说他用的是8031的实验箱,我当时就晕了。8031是8051的前身,那个芯片连...
  • 4X4矩阵键盘扫描程序

    2017-04-19 09:21:00
    4X4矩阵键盘扫描: 1. 4根行线的GIO均设为Output,根列线的GIO均设为Input; 2. 4根行线的GIO分别置为0111、1011、1101、1110,读逐一读取列线GIO的值,可确定是哪一个按键。 电路图例如以下: 注意:...

    4X4矩阵键盘扫描:

    1. 4根行线的GIO均设为Output,根列线的GIO均设为Input;

    2. 4根行线的GIO分别置为0111、1011、1101、1110,读逐一读取列线GIO的值,可确定是哪一个按键。


    电路图例如以下:


    注意:

    1. 图中用作输入的GIO,一定要有一个上拉电阻。

    2. 芯片中的每个引脚是否用作了GPIO口来用。需配置芯片的寄存器,使引脚当作GPIO口来使用,才会有效。


    測试代码例如以下:

    #define KEY_GIO_ROW_1	37
    #define KEY_GIO_ROW_2	33
    #define KEY_GIO_ROW_3	32
    #define KEY_GIO_ROW_4	35
    #define KEY_GIO_COL_1	22
    #define KEY_GIO_COL_2	23
    #define KEY_GIO_COL_3	24
    #define KEY_GIO_COL_4	36
    int scanKey()
    {
    	int keyValue = 0;
    	int col1Value=0,col2Value=0,col3Value=0,col4Value=0,row1Value=0,row2Value=0,row3Value=0,row4Value=0;
    	static int press1=0,press2=0,press3=0,press4=0;
    	static int press5=0,press6=0,press7=0,press8=0;
    	static int press9=0,press10=0,press11=0,press12=0;
    	static int press13=0,press14=0,press15=0,press16=0;
    
    	dm365SetGPIO(KEY_GIO_ROW_1, 0);
    	dm365SetGPIO(KEY_GIO_ROW_2, 1);
    	dm365SetGPIO(KEY_GIO_ROW_3, 1);
    	dm365SetGPIO(KEY_GIO_ROW_4, 1);
    	col1Value = dm365GetGPIO(KEY_GIO_COL_1);
    	col2Value = dm365GetGPIO(KEY_GIO_COL_2);
    	col3Value = dm365GetGPIO(KEY_GIO_COL_3);
    	col4Value = dm365GetGPIO(KEY_GIO_COL_4);
    	keyValue = col1Value | (col2Value << 1) | (col3Value << 2) | (col4Value << 3);
    //	printf("=1==keyValue = %x\n",keyValue);
    	switch(keyValue)
    	{
    		case 0x0E:
    			{
    				if(!press1)
    				{
    					press1 = 1;
    					printf("KEY 1\n");
    				}
    			}
    			break;
    		case 0x0D:
    			{
    				if(!press2)
    				{
    					press2 = 1;
    					printf("KEY 2\n");
    				}
    			}
    			break;
    		case 0x0B:
    			{
    				if(!press3)
    				{
    					press3 = 1;
    					printf("KEY 3\n");
    				}
    			}
    			break;
    		case 0x07:
    			{
    				if(!press4)
    				{
    					press4 = 1;
    					printf("KEY 4\n");
    				}
    			}
    			break;
    		default:
    			{
    				press1 = 0;
    				press2 = 0;
    				press3 = 0;
    				press4 = 0;
    			}
    			break;
    	}
    
    	dm365SetGPIO(KEY_GIO_ROW_1, 1);
    	dm365SetGPIO(KEY_GIO_ROW_2, 0);
    	dm365SetGPIO(KEY_GIO_ROW_3, 1);
    	dm365SetGPIO(KEY_GIO_ROW_4, 1);
    	col1Value = dm365GetGPIO(KEY_GIO_COL_1);
    	col2Value = dm365GetGPIO(KEY_GIO_COL_2);
    	col3Value = dm365GetGPIO(KEY_GIO_COL_3);
    	col4Value = dm365GetGPIO(KEY_GIO_COL_4);
    	keyValue = col1Value | (col2Value << 1) | (col3Value << 2) | (col4Value << 3);
    //	printf("=2==keyValue = %x\n",keyValue);
    	switch(keyValue)
    	{
    		case 0x0E:
    			{
    				if(!press5)
    				{
    					press5 = 1;
    					printf("KEY 5\n");
    				}
    			}
    			break;
    		case 0x0D:
    			{
    				if(!press6)
    				{
    					press6 = 1;
    					printf("KEY 6\n");
    				}
    			}
    			break;
    		case 0x0B:
    			{
    				if(!press7)
    				{
    					press7 = 1;
    					printf("KEY 7\n");
    				}
    			}
    			break;
    		case 0x07:
    			{
    				if(!press8)
    				{
    					press8 = 1;
    					printf("KEY 8\n");
    				}
    			}
    			break;
    		default:
    			{
    				press5 = 0;
    				press6 = 0;
    				press7 = 0;
    				press8 = 0;
    			}
    			break;
    	}
    
    	dm365SetGPIO(KEY_GIO_ROW_1, 1);
    	dm365SetGPIO(KEY_GIO_ROW_2, 1);
    	dm365SetGPIO(KEY_GIO_ROW_3, 0);
    	dm365SetGPIO(KEY_GIO_ROW_4, 1);
    	col1Value = dm365GetGPIO(KEY_GIO_COL_1);
    	col2Value = dm365GetGPIO(KEY_GIO_COL_2);
    	col3Value = dm365GetGPIO(KEY_GIO_COL_3);
    	col4Value = dm365GetGPIO(KEY_GIO_COL_4);
    	keyValue = col1Value | (col2Value << 1) | (col3Value << 2) | (col4Value << 3);
    //	printf("=3==keyValue = %x\n",keyValue);
    	switch(keyValue)
    	{
    		case 0x0E:
    			{
    				if(!press9)
    				{
    					press9 = 1;
    					printf("KEY 9\n");
    				}
    			}
    			break;
    		case 0x0D:
    			{
    				if(!press10)
    				{
    					press10 = 1;
    					printf("KEY 10\n");
    				}
    			}
    			break;
    		case 0x0B:
    			{
    				if(!press11)
    				{
    					press11 = 1;
    					printf("KEY 11\n");
    				}
    			}
    			break;
    		case 0x07:
    			{
    				if(!press12)
    				{
    					press12 = 1;
    					printf("KEY 12\n");
    				}
    			}
    			break;
    		default:
    			{
    				press9 = 0;
    				press10 = 0;
    				press11 = 0;
    				press12 = 0;
    			}
    			break;
    	}
    
    	dm365SetGPIO(KEY_GIO_ROW_1, 1);
    	dm365SetGPIO(KEY_GIO_ROW_2, 1);
    	dm365SetGPIO(KEY_GIO_ROW_3, 1);
    	dm365SetGPIO(KEY_GIO_ROW_4, 0);
    	col1Value = dm365GetGPIO(KEY_GIO_COL_1);
    	col2Value = dm365GetGPIO(KEY_GIO_COL_2);
    	col3Value = dm365GetGPIO(KEY_GIO_COL_3);
    	col4Value = dm365GetGPIO(KEY_GIO_COL_4);
    	keyValue = col1Value | (col2Value << 1) | (col3Value << 2) | (col4Value << 3);
    //	printf("=4==keyValue = %x\n",keyValue);
    	switch(keyValue)
    	{
    		case 0x0E:
    			{
    				if(!press13)
    				{
    					press13 = 1;
    					printf("KEY 13\n");
    				}
    			}
    			break;
    		case 0x0D:
    			{
    				if(!press14)
    				{
    					press14 = 1;
    					printf("KEY 14\n");
    				}
    			}
    			break;
    		case 0x0B:
    			{
    				if(!press15)
    				{
    					press15 = 1;
    					printf("KEY 15\n");
    				}
    			}
    			break;
    		case 0x07:
    			{
    				if(!press16)
    				{
    					press16 = 1;
    					printf("KEY 16\n");
    				}
    			}
    			break;
    		default:
    			{
    				press13 = 0;
    				press14 = 0;
    				press15 = 0;
    				press16 = 0;
    			}
    			break;
    	}
    
    
    	return keyValue;
    }
    void *KeyMngThread()
    {
    	int resetValue = 1;
    	int resetCout = 0;
    	int alarmInValue = 1;
    	int alarmInCout = 0;
    	while(1)
    	{
    		resetValue = dm365GetGPIO(GIO_RESET);
    		if(0 == resetValue)
    		{
    			resetCout++;
    		}
    		else if(1 == resetValue)
    		{
    			resetCout = 0;
    		}
    		if(resetCout == 30)
    		{
    			resetCout = 0;
    			system("rm -f /mnt/nand/sysenv.cfg");
    			system("/bin/sync");
    //			System("reboot");
    			system("/tmp/shutdown -r now \n");
    		}
    		alarmInValue = dm365GetGPIO(GIO_ALARM_IN);
    		if(0 == alarmInValue)
    		{
    			dm365SetGPIO(GIO_LED,0);	//control led off .
    		}
    		else if(1 == alarmInValue)
    		{
    			dm365SetGPIO(GIO_LED,1);	//control led on .
    		}
    
    		scanKey();
    
    		usleep(100000);
    	}
    
    }

    代码中dm365SetGPIO( )里将GPIO默认设置为Output,

    dm365GetGPIO( )中将GPIO默认设置为Input,

    通过字符设备驱动实现应用层操作底层GPIO。

    展开全文
  • 4*4矩阵键盘扫描原理

    万次阅读 多人点赞 2017-07-27 10:18:33
    初学者肯定要经历的一个实验就是4*4矩阵键盘的代码编写,大部分都是在学校里面,有现成的实验箱,基本不需要自己动脑子。上次遇到一个哥们,他说他用的是8031的实验箱,我当时就晕了。8031是8051的前身,那个芯片连...

    初学者肯定要经历的一个实验就是4*4矩阵键盘的代码编写,大部分都是在学校里面,有现成的实验箱,基本不需要自己动脑子。上次遇到一个哥们,他说他用的是8031的实验箱,我当时就晕了。8031是8051的前身,那个芯片连ROM都没有,可以想象我们的学校都在拿什么教育祖国的花朵。废话少说,先上图:

     


        对初学者来说这篇文章会有点难,可以先研究一下如何用51单片机点亮一个发光二极管和基于CPLD-EPF10K10LC84-4(84)的交通灯设计。首先要说明的一点,矩阵键盘的动态扫描确实略显复杂,不可能就是读一个端口数据,然后马上就出来结果。这需要对依次每一行的按键进行扫描、判断,然后得出结果。如上图所示,先扫描第一行,也就是S1,S2,S3,S4四个按键的状态。在PA口输入0XFE。

        0XFE变成二进制是1111 1110,为了方便使用,记得每四个数之间加一个空格。1111 1110这个数据放到PA口上,假设这个时候S1被按下了,会出现什么情况?因为PA0是低电平,S1被按下之后S1导通,导致PA4的电平从1降到0,于是PA端口的数据就变成了1110 1110,换算成16进制就是0XEE。于是我们知道S1被按下了。

        假设是S3被按下,会出现什么情况?没错,PA6的电平被拉低,PA的端口数据变成了1011 1110,也就是0XBE。这样,我们就知道了,每一行的每一个按键被按下的时候,都会有一个对应的独一无二的值。这就是矩阵键盘的扫描原理!送上一段源码,大家看着玩吧:

    void matrixkeyscan()

    {

    uchar temp,key;

        P3=0xfe;

        temp=P3;

        temp=temp&0xf0;

        if(temp!=0xf0)

        {

          delayms(10);

     temp=P3;

     temp=temp&0xf0;

          if(temp!=0xf0)

          {

            temp=P3;

            switch(temp)

            {

              case 0xee:

                   key=0;

                   break;

              case 0xde:

                   key=1;

                   break;

              case 0xbe:

                   key=2;

                   break;

              case 0x7e:

                   key=3;

                   break;

             }

             while(temp!=0xf0)

             {

               temp=P3;

               temp=temp&0xf0;

             }

            display(key);

          }

        }

        P3=0xfd;

        temp=P3;

        temp=temp&0xf0;

        if(temp!=0xf0)

        {

          delayms(10);

          temp=P3;

          temp=temp&0xf0;

          if(temp!=0xf0)

          {

            temp=P3;

            switch(temp)

            {

              case 0xed:

                   key=4;

                   break;

              case 0xdd:

                   key=5;

                   break;

              case 0xbd:

                   key=6;

                   break;

              case 0x7d:

                   key=7;

                   break;

             }

             while(temp!=0xf0)

             {

               temp=P3;

               temp=temp&0xf0;

             }

             display(key);

          }

          }

        P3=0xfb;

        temp=P3;

        temp=temp&0xf0;

        if(temp!=0xf0)

        {

          delayms(10);

         temp=P3;

          temp=temp&0xf0;

          if(temp!=0xf0)

          {

            temp=P3;

            switch(temp)

            {

              case 0xeb:

                   key=8;

                   break;

              case 0xdb:

                   key=9;

                   break;

              case 0xbb:

                   key=10;

                   break;

              case 0x7b:

                   key=11;

                   break;

             }

             while(temp!=0xf0)

             {

               temp=P3;

               temp=temp&0xf0;

             }

            display(key);

          }

          }

        P3=0xf7;

        temp=P3;

        temp=temp&0xf0;

        if(temp!=0xf0)

        {

          delayms(10);

          temp=P3;

          temp=temp&0xf0;

          if(temp!=0xf0)

          {

            temp=P3;

            switch(temp)

            {

              case 0xe7:

                   key=12;

                   break;

              case 0xd7:

                   key=13;

                   break;

              case 0xb7:

                   key=14;

                   break;

              case 0x77:

                   key=15;

                   break;

             }

             while(temp!=0xf0)

             {

               temp=P3;

               temp=temp&0xf0;

             }

            display(key);

          }

        }

    }

    转自:http://www.51hei.com/mcu/3815.html


    展开全文
  • 矩阵键盘扫描程序实例

    千次阅读 2017-07-28 17:30:29
    使用芯片STM8S003 所用端口:PD2~PD6, PA1~PA3 其中,PD3~PD6为输出,PA1~PA3 / PD2为输入(默认上拉) /*  PortCom BIT7 BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0  PD6 PD5 PD4 PD3 PD2 PA3 PA2 PA1  */ ...

    使用芯片STM8S003

    所用端口:PD2~PD6, PA1~PA3

    其中,PD3~PD6为输出,PA1~PA3 / PD2为输入(默认上拉)

    /*
        PortCom BIT7 BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0
                      PD6  PD5  PD4  PD3  PD2  PA3  PA2  PA1
      */

    程序如下:

    /*    添加包含芯片的头文件    */
    #include<iostm8s103f3.h>
    
    
    
    volatile unsigned char CF[4];     //按键触发标志(表示4列,每一列同一行的
                                      //值是一样的但列标不一样来区分不同列的键)
    volatile unsigned char Cont[4];
    unsigned char KeyVal;     //键值
    //unsigned char KeyOut[4] = {0xef,0xdf,0xbf,0x7f};    //4X4按输出端控制
    //unsigned char KeyOut[4] = {0x7f,0xbf,0xdf,0xef};
    unsigned char KeyOut[4] = {0x3f,0x5f,0x6f,0x77};      //两个端口组合4x4端口输出控制
    unsigned char PortCom;    //两个端口组合的端口
    unsigned char cIn0,cIn1,cIn2,cIn3;
    
    
    /*******************************************************************************
    **函数名称:void delay(unsigned int ms)     Name: void delay(unsigned int ms)
    **功能描述:大概延时
    **入口参数:unsigned int ms   输入大概延时数值
    **输出:无
    *******************************************************************************/
    void delay(unsigned int ms)
    {
      unsigned int x , y;
      for(x = ms; x > 0; x--)
        for(y = 1000 ; y > 0 ; y--);
    }
    
    /*
    **描述:新型4X4按键扫描程序 放在1ms-10ms中断内使用(十分稳定不需要再写消抖程序)
    **备注:按键弹起时 keyVal = 0 单键按下 keyVal 有16个值,你自己程序可以针对不同值
    **进行不同程序操作 keyVal单键值分别为 
    **0x01,0x02,0x04,0x08,
    **0x11,0x12,0x14,0x18,
    **0x21,0x22,0x24,0x28,
    **0x31,0x32,0x34,0x38,
    */ 
    void Key_Head() 
    {
      unsigned char ReadData[4];
      static unsigned char i;
      /*
        PortCom BIT7 BIT6 BIT5 BIT4 BIT3 BIT2 BIT1 BIT0
                PD6  PD5  PD4  PD3  PD2  PA3  PA2  PA1
      */
      cIn0 = 0;
      cIn1 = 0;
      cIn2 = 0;
      cIn3 = 0;
      if(++i>=4)i=0;
    
    //  PortCom = KeyOut[i]|0x0f;                     //忽略低4位
      //输出扫描
      PD_ODR = KeyOut[i];
      //输入侦测
      cIn0 = PA_IDR_bit.IDR1;
      cIn1 = PA_IDR_bit.IDR2;
      cIn2 = PA_IDR_bit.IDR3;
      cIn3 = PD_IDR_bit.IDR2;
      PortCom = (cIn3<<3) | (cIn2<<2) | (cIn1<<1) | cIn0; 
      
      ReadData[i] = (PortCom|0xf0)^0xff;            //忽略高4位 取反 
      CF[i] = ReadData[i] & (ReadData[i] ^ Cont[i]); 
      Cont[i] = ReadData[i]; 
      //输出键值
      switch(CF[i])//第i列
      {
        case 0x08: KeyVal = ((i<<4)+8);break;
        case 0x04: KeyVal = ((i<<4)+4);break;
        case 0x02: KeyVal = ((i<<4)+2);break;
        case 0x01: KeyVal = ((i<<4)+1);break;
        default:KeyVal = 0;break;
      } 
        
      delay(30);
    }
    
    
    /*******************************************************************************
    **函数名称:void ALL_LED_Init()    Name: void ALL_LED_Init()
    **功能描述:初始化LED灯的IO口设为输出
    **入口参数:无
    **输出:无
    *******************************************************************************/
    void ALL_LED_Init()
    {
      //LED1 Init
    //  PD_DDR_bit.DDR2 = 1;    //设置端口PD->2的输入输出方向寄存器为输出方向
    //  PD_CR1_bit.C12 = 1;     //设置PD2为推挽输出
    //  PD_CR2_bit.C22 = 1;     //设置PD2的输出最大速度为10MHZ
      
      //LED2 Init
      PC_DDR_bit.DDR7 = 1;    //设置端口PC->7的输入输出方向寄存器为输出方向
      PC_CR1_bit.C17 = 1;     //设置PC7为推挽输出
      PC_CR2_bit.C27 = 1;     //设置PC7的输出最大速度为10MHZ
      
      //LED3 Init
      PC_DDR_bit.DDR6 = 1;    //设置端口PC->6的输入输出方向寄存器为输出方向
      PC_CR1_bit.C16 = 1;     //设置PC6为推挽输出
      PC_CR2_bit.C26 = 1;     //设置PC6的输出最大速度为10MHZ
      
      //LED4 Init
      PC_DDR_bit.DDR3 = 1;    //设置端口PC->3的输入输出方向寄存器为输出方向
      PC_CR1_bit.C13 = 1;     //设置PC3为推挽输出
      PC_CR2_bit.C23 = 1;     //设置PC3的输出最大速度为10MHZ
    }
    
    
    /*******************************************************************************
    **函数名称:ALLKeyInit()
    **功能描述:配置Key1 , Key2 , Key3输入按键
    **入口参数:无
    **输出:无
    *******************************************************************************/
    void ALLKeyInit()
    {
      //PA1_Init
      PA_DDR_bit.DDR1 = 0;      //GPA->PIN3 设置为输入模式
      PA_CR1_bit.C11 = 1;       //GPA->PIN3 带上拉电阻输入
      PA_CR2_bit.C21 = 0;       //GPA->PIN3  禁止外部中断
      
      //PA2_Init
      PA_DDR_bit.DDR2 = 0;      //GPA->PIN3 设置为输入模式
      PA_CR1_bit.C12 = 1;       //GPA->PIN3 带上拉电阻输入
      PA_CR2_bit.C22 = 0;       //GPA->PIN3  禁止外部中断
      
      //PA3_Init
      PA_DDR_bit.DDR3 = 0;      //GPA->PIN3 设置为输入模式
      PA_CR1_bit.C13 = 1;       //GPA->PIN3 带上拉电阻输入
      PA_CR2_bit.C23 = 0;       //GPA->PIN3  禁止外部中断
      
      //PD2_Init
      PD_DDR_bit.DDR2 = 0;      //GPD->PIN3 设置为输入模式
      PD_CR1_bit.C12 = 1;       //GPD->PIN3 带上拉电阻输入
      PD_CR2_bit.C22 = 0;       //GPD->PIN3  禁止外部中断
      
      //PD3_Init
      PD_DDR_bit.DDR3 = 1;      //GPD->PIN3 设置为输入模式
      PD_CR1_bit.C13 = 1;       //GPD->PIN3 带上拉电阻输入
      PD_CR2_bit.C23 = 1;       //GPD->PIN3  禁止外部中断
      
      //PD4_Init
      PD_DDR_bit.DDR4 = 1;      //GPD->PIN3 设置为输入模式
      PD_CR1_bit.C14 = 1;       //GPD->PIN3 带上拉电阻输入
      PD_CR2_bit.C24 = 1;       //GPD->PIN3  禁止外部中断
      
      //PD5_Init
      PD_DDR_bit.DDR5 = 1;      //GPC->PIN5 设置为输入模式
      PD_CR1_bit.C15 = 1;       //GPC->PIN5 带上拉电阻输入
      PD_CR2_bit.C25 = 1;       //GPC->PIN5  禁止外部中断
      
      //PD6_Init
      PD_DDR_bit.DDR6 = 1;      //GPC->PIN5 设置为输入模式
      PD_CR1_bit.C16 = 1;       //GPC->PIN5 带上拉电阻输入
      PD_CR2_bit.C26 = 1;       //GPC->PIN5  禁止外部中断
    }
    
    int main(void)
    {
      CLK_CKDIVR = 0x00;              //内部时钟为1分频
      ALL_LED_Init();                 //调用LED1初始化函数
      ALLKeyInit();                   //调用按钮初始化函数
    
      while(1)
      {  
        Key_Head();
        
        switch(KeyVal)
        {
        case 0x01:
          {
            PC_ODR ^= 0x80;                //异或取反LED2使其亮灭
            break;
          }
        case 0x02:
          {
            PC_ODR ^= 0x40;                //异或取反LED3使其亮灭
            break;
          }
        case 0x04:
          {
            PC_ODR ^= 0x08;                //异或取反LED4使其亮灭
            break;
          }
        case 0x08:
          {
            PC_ODR ^= 0x80;                //异或取反LED2使其亮灭
            PC_ODR ^= 0x40;                //异或取反LED3使其亮灭
            break;
          }
        case 0x11:
          {
            PC_ODR ^= 0x80;                //异或取反LED2使其亮灭
            break;
          }
        case 0x12:
          {
            PC_ODR ^= 0x40;                //异或取反LED3使其亮灭
            break;
          }
        case 0x14:
          {
            PC_ODR ^= 0x08;                //异或取反LED4使其亮灭
            break;
          }
        case 0x18:
          {
            PC_ODR ^= 0x80;                //异或取反LED2使其亮灭
            PC_ODR ^= 0x40;                //异或取反LED3使其亮灭
            break;
          }
        case 0x21:
          {
            PC_ODR ^= 0x80;                //异或取反LED2使其亮灭
            break;
          }
        case 0x22:
          {
            PC_ODR ^= 0x40;                //异或取反LED3使其亮灭
            break;
          }
        case 0x24:
          {
            PC_ODR ^= 0x08;                //异或取反LED4使其亮灭
            break;
          }
        case 0x28:
          {
            PC_ODR ^= 0x80;                //异或取反LED2使其亮灭
            PC_ODR ^= 0x40;                //异或取反LED3使其亮灭
            break;
          }
        case 0x31:
          {
            PC_ODR ^= 0x80;                //异或取反LED2使其亮灭
            break;
          }
        case 0x32:
          {
            PC_ODR ^= 0x40;                //异或取反LED3使其亮灭
            break;
          }
        case 0x34:
          {
            PC_ODR ^= 0x08;                //异或取反LED4使其亮灭
            break;
          }
        case 0x38:
          {
            PC_ODR ^= 0x80;                //异或取反LED2使其亮灭
            PC_ODR ^= 0x40;                //异或取反LED3使其亮灭
            break;
          }
        default:
          {
            KeyVal = 0;
            break;
          }
        }
      }
    }

    相关分析参考:http://blog.csdn.net/phenixyf/article/details/76090873

    http://blog.csdn.net/phenixyf/article/details/76173409




    展开全文
  • 矩阵键盘扫描接口实验是基于VHDL语言的可编程逻辑器件的设计,使用的芯片为FPGA或CPLD,软件为Quartus ii
  • 生物微矩阵芯片)分析仪是西安联尔科技有限公司开发的新产品,用于对胶体金微矩阵血清试剂引导卡、蛋白芯片、胶体金试剂盒等显色型生物信息标本的检测、结果分析和标本信号的定量、半定量、定性分析和结果判定。...
  • CH455芯片资料 CH455是一款用于驱动数码管(LED)和矩阵键盘扫描控制芯片。能够动态驱动4位数码管或者32个LED。同时支持7x4的键盘扫描。单片机通过I2C对CH455进行读写,同时包括一个#INT中断引脚,任何一个按键按下...
  • 51单片机矩阵键盘编码方法

    万次阅读 多人点赞 2017-07-23 16:33:16
    在进行矩阵键盘检测时,书本或老师一般教的都是扫描检测,即一行一行地检测或者一列一列地检测,代码繁琐复杂,且缺点很多(例如执行效率较低)。 举例电路: 矩阵键盘与8051连接如上图所示,首

    搬运到CSDN的旧文档


    众所周知,51单片机一般的键盘检测原理为非编码键盘检测,没有专门用来产生键编码号或键值的电路芯片;而我们使用的电脑键盘为编码键盘,通过编码电路芯片为每个按键产生一个编码号,可以通过串行总线把键值传输给电脑。在进行矩阵键盘检测时,书本或老师一般教的都是扫描检测,即一行一行地检测或者一列一列地检测,代码繁琐复杂,且缺点很多(例如执行效率较低)。
    举例电路:
    这里写图片描述
    矩阵键盘与8051连接如上图所示,首先,令P3=0x0f,检测P30、P31、P32、P33哪一行被按下,将此时P3的值存入寄存器1。然后,令P3=0xf0 | 寄存器1,检测P34、P35、P36、P37哪一列被按下,将此时P3的值存入寄存器2。最后,把寄存器1的值和寄存器2的值组合起来即可得到矩阵键盘的编码。

    代码如下:

    #include<reg52.h>
    unsigned char NUM=1;
    /*-----------------------------
      特殊功能位定义
    -----------------------------*/
    sbit L1=P0^0;
    sbit L2=P0^1;
    sbit L3=P0^2;
    sbit L4=P0^3;
    sbit L5=P0^4;
    sbit L6=P0^5;
    sbit L7=P0^6;
    sbit L8=P0^7;
    sbit DUAN=P2^6;
    sbit WEI=P2^7;
    /*-----------------------------
      定时器0初始化函数
    -----------------------------*/
    void init()
    {
        EA=1;
        ET0=1;
        TMOD=0X01;
        TH0=(65536-10000)/256;
        TL0=(65536-10000)%256;
    }
    /*-----------------------------
      中断服务函数
    -----------------------------*/
    void timer0()interrupt 1
    {
        TR0=0;  //定时终止
        TH0=(65536-10000)/256;  //定时器0初值重装
        TL0=(65536-10000)%256;
        NUM--;
    }
    /*--------------------------------------------------
      矩阵键盘检测兼编码函数 
    --------------------------------------------------*/ 
    unsigned char matrixkeyscan()
    {
        unsigned char temp,reg1=0,reg2=0,key=0;  //temp为临时变量,reg1为寄存器1,reg2为寄存器2,key为键盘编码号 
        P3=0x0f;
        temp=P3&0x0f;
        if(temp!=0x0f)  //按键检测兼行坐标检测 
        {
            TR0=1;        //-------------------
            while(NUM);   //  10ms去抖动延时  
            NUM=1;        //-------------------
            temp=P3&0x0f;
            if(temp!=0x0f)  //二次检测 
            {
                reg1=temp;     //把行坐标存入寄存器1
                P3=reg1|0xf0;  //关键,没有这句将导致整个函数出错
                temp=P3&0xf0;
                if(temp!=0xf0)  //检测列坐标
                {
                    reg2=temp;  //把列坐标存入寄存器2 
                    key=reg1|reg2;  //将寄存器1和寄存器2进行按位或,作用是组合坐标,格式为八位二进制的"列坐标行坐标" 
                    while(temp!=0xf0)  //等待按键释放
                        temp=P3&0xf0;
                }
            }
        }
        return key;
    }
    
    /*--------------------------------------------------
      按键功能实现函数 
    --------------------------------------------------*/ 
    void keyfunction()
    {
        unsigned char kvalue=0;
        kvalue=matrixkeyscan();
        switch(kvalue)
        {
            case 0xee: L1=~L1;/*按键01功能*/ break; 
            case 0xde: L2=~L2;/*按键02功能*/ break;
            case 0xbe: L3=~L3;/*按键03功能*/ break;
            case 0x7e: L4=~L4;/*按键04功能*/ break;
            case 0xed: L5=~L5;/*按键05功能*/ break;
            case 0xdd: L6=~L6;/*按键06功能*/ break;
            case 0xbd: L7=~L7;/*按键07功能*/ break;
            case 0x7d: L8=~L8;/*按键08功能*/ break;
            case 0xeb: /*按键09功能*/ break;
            case 0xdb: /*按键10功能*/ break;
            case 0xbb: /*按键11功能*/ break;
            case 0x7b: /*按键12功能*/ break;
            case 0xe7: /*按键13功能*/ break;
            case 0xd7: /*按键14功能*/ break;
            case 0xb7: /*按键15功能*/ break;
            case 0x77: /*按键16功能*/ break;
            default: ;//空语句 
        }
    }
    /*-----------------------------
      主函数
    -----------------------------*/
    void main()
    {
        DUAN=0;
        WEI=0;
        init();  //定时器初始化,装入初值10ms
        while(1)
        {
                keyfunction();  //按键循环检测
        }
    }
    展开全文
  • 在进行矩阵键盘检测时,书本或老师一般教的都是扫描检测,即一行一行地检测或者一列一列地检测,代码繁琐复杂,且缺点很多(例如执行效率较低)。举例电路:矩阵键盘与8051连接如上图所示,首先,令P3=0x0f,检测P30...
  • 系统级RF收发芯片nRF24E1的各个功能模块及其特性,分析了无线键盘的工作原理,介绍了怎样用nRF24E1在无线键盘中实现键盘矩阵扫描和键盘信号的无线接收和发送,并给出了实际应用中的体会。
  • 用汇编实现矩阵键盘编程设计

    千次阅读 2020-06-03 08:58:44
    用汇编实现矩阵键盘编程设计目的要求代码第一种第二种第三种小结 目的 1.掌握I/O芯片编程应用 2.掌握矩阵键盘编码设计技术 要求 用扫描法读取键值显示。 用反转法读取键值显示。 代码 这里用了三种方法,其实...
  • CH455是一款用于驱动数码管(LED)和矩阵键盘扫描控制芯片。能够动态驱动4位数码管或者32个LED。同时支持7x4的键盘扫描。单片机通过I2C对CH455进行读写,同时包括一个#INT中断引脚,任何一个按键按下都会触发中断,...
  • 亲测可用4X4矩阵键盘,简单好用,采用行列扫描方法,延时程序不占用MCU资源。 主控芯片为stm32f407VGT6
  • CH455 是数码管显示驱动和键盘扫描控制芯片。CH455内置时钟振荡电路,可以动态驱动4 位数 码管或者32 只LED;同时还可以进行28 键的键盘扫描;CH455 通过SCL 和SDA 组成的2 线串行接口 与单片机等交换数据。  2...
  • 在Proteus中仿真4×4矩阵键盘的中断

    千次阅读 2020-06-13 22:36:30
    目的:实现4×4矩阵键盘进行中断并返回信息(0~F) 使用芯片:8086、8259等 流程概述:按键按下后生成中断并扫描按键返回信息然后结束中断。 原理图: 汇编程序: ;==============================================...
  • ARM键盘接口

    2020-11-13 01:48:40
    ARM由通用接口GPI支持键盘扫描(Scanning keyboardrow)和支持键盘阵列扫描(Scanning keyboard matnx)。  其中,Port A、Port B、Port D主要用于外围芯片信号的控制,Port E有双重作用。例如,PortA控制键盘的...
  • TM1638芯片使用心得

    2020-08-11 03:36:56
    这段时间因为设计项目需要用到数码管和按钮,因为数码管过多,没有办法使用IO扫描方式,所以就是使用了专用IC驱动芯片,TM1638芯片可以驱动数码可以驱动矩阵键盘
  • 该模块采用矩阵键盘设计,通过I2C总线与主控芯片相连,利用按键产生的中断对键盘进行扫描,并完成键值的上报。详细介绍了Android系统的键盘驱动开发流程和键值处理的一些经验,实测证明达到了实用化的要求。这种...
  • STC单片机按键扫描程序

    千次阅读 2018-10-17 11:07:08
    最近在做一个电子秤相关项目,使用STC系列单片机作为主控芯片,项目第一阶段直接使用IAP15W4K58S4驱动两个矩阵键盘,一切调试顺利,在项目即将结束时老板要求使用另一块单片机驱动矩阵键盘,读取键值后通过串口传回...
  • MTK按键扫描原理

    2021-05-20 14:48:23
    MTK提供6*7共42个矩阵键盘,加上Power键总共43个按键,其中BB芯片引出6根行线ROW,7根列线COL,如下图。 下面来说明一下扫描原理: 在初始化或是没有按键的情况下,ROW设置为输出,COL设置为输入。 BB芯片的...
  • 在电子方案的设计中,通常使用键盘矩阵作为用户连接产品的一种方式。为了最大程度地减少单片机中使用的引脚数量,按键应尽可能排列成正方形矩阵。 一个示例是在16键键盘中使用4X4矩阵排列。这种布置仅需要8个引脚。...
  • 资源分配 NE555制造的频率测量最好是使用定时器0的计数器模式来测量,因此定时器0最好是专门留给NE555...在使用P34用作NE555的频率检测的时候,矩阵键盘是不能够使用的,因为矩阵键盘中用到了P34这个引脚! ...
  • 例程合集包括,定时器扫描、EEPEOM、温度、时钟、串口、A/D、矩阵键盘、外部中断、点阵等
  • EDA 电子设计自动化VHDL系列课程13 – 键盘接口电路模拟设计 本EDA系列介绍的系统环境是: 软件: VHDL编程语言 ; 工具: Quartus13.0 ...该程序模拟完成了 4*4 矩阵键盘。列数 是扫描获取,行...
  • MTK提供6*7共42个矩阵键盘,加上Power键总共43个按键,其中BB芯片引出6根行线ROW,7根列线COL,如下图。 下面来说明一下扫描原理: 在初始化或是没有按键的情况下,ROW设置为输出,COL设置为输入。 BB芯片的内部设...
  • 薄膜式标准键盘的硬件构成由四部分组成:三层薄膜、104个按键矩阵、3个指示灯和Intel 8042控制器芯片。 由三层薄膜(上层与下层都有电路,中间则是绝缘层)所组成。按键采用橡胶帽,成本低、工艺简单和手感好等优势...
  • 一、 数码管动态扫描和定时器 二、 矩阵键盘 三、 外部中断的使用 四、 实时时钟DS1302的使用 五、 PCF8591与IIC总线的使用 六、 DS18B20时钟芯片的使用 七、 超声波传感器的使用

空空如也

空空如也

1 2 3 4
收藏数 67
精华内容 26
关键字:

键盘矩阵扫描芯片