xzy610030

一起探讨,一起进步,一起分享!

stm32F4----薄膜4*4矩阵键盘读取(七)

0
阅读(7418)

买了个矩阵键盘,原理图如下:


左边的为行,右边的为列,扫描的原理大概如下:行为输出,列为输入。先让第一行为0,其他行为高,读取列的电平。

key.c如下:

#include "key.h"
#include "delay.h"
//键值表
/*
1:0x01    2:0x02    3:0x03    A:0x04
4:0x05    5:0x06    6:0x07    B:0x08
7:0x09    8:0x0A    9:0x0B    C:0x0C
*:0x0D    0:0x0E    #:0x0F    D:0x10
*/
uint8_t keyNum = 0x00;   //键值

void  keyInit(void)
{
  GPIO_InitTypeDef   GPIO_InitStructure;
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);
	//key row1  output
	GPIO_InitStructure.GPIO_Pin  =  KEY_ROW1_PIN;
	GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_Speed=  GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_OType=  GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd =  GPIO_PuPd_UP;
	GPIO_Init(KEY_ROW1_PORT,&GPIO_InitStructure);

	//key row2  output
	GPIO_InitStructure.GPIO_Pin  =  KEY_ROW2_PIN;
	GPIO_Init(KEY_ROW2_PORT,&GPIO_InitStructure);

	//key row3  output
	GPIO_InitStructure.GPIO_Pin  =  KEY_ROW3_PIN;
	GPIO_Init(KEY_ROW3_PORT,&GPIO_InitStructure);

	//key row4  output
	GPIO_InitStructure.GPIO_Pin  =  KEY_ROW4_PIN;
	GPIO_Init(KEY_ROW4_PORT,&GPIO_InitStructure);
	
	//key col1  input
	GPIO_InitStructure.GPIO_Pin  =  KEY_COL1_PIN;
	GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_Speed=  GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_PuPd =  GPIO_PuPd_UP;
	GPIO_Init(KEY_COL1_PORT,&GPIO_InitStructure);	

	//key col2  input
	GPIO_InitStructure.GPIO_Pin  =  KEY_COL2_PIN;
	GPIO_Init(KEY_COL2_PORT,&GPIO_InitStructure);

	//key col3  input
	GPIO_InitStructure.GPIO_Pin  =  KEY_COL3_PIN;
	GPIO_Init(KEY_COL3_PORT,&GPIO_InitStructure);
	
	//key col4  input
	GPIO_InitStructure.GPIO_Pin  =  KEY_COL4_PIN;
	GPIO_Init(KEY_COL4_PORT,&GPIO_InitStructure);

}


static void key_Row1_scan(void)
{
  GPIO_ResetBits(KEY_ROW1_PORT,KEY_ROW1_PIN); // 0
	GPIO_SetBits(KEY_ROW2_PORT,KEY_ROW2_PIN);  //1
	GPIO_SetBits(KEY_ROW3_PORT,KEY_ROW3_PIN);  //1
	GPIO_SetBits(KEY_ROW4_PORT,KEY_ROW4_PIN);  //1
}

static void key_Row2_scan(void)
{
  GPIO_SetBits(KEY_ROW1_PORT,KEY_ROW1_PIN); // 1
	GPIO_ResetBits(KEY_ROW2_PORT,KEY_ROW2_PIN);  //0
	GPIO_SetBits(KEY_ROW3_PORT,KEY_ROW3_PIN);  //1
	GPIO_SetBits(KEY_ROW4_PORT,KEY_ROW4_PIN);  //1
}

static void key_Row3_scan(void)
{
  GPIO_SetBits(KEY_ROW1_PORT,KEY_ROW1_PIN); // 1
	GPIO_SetBits(KEY_ROW2_PORT,KEY_ROW2_PIN);  //1
	GPIO_ResetBits(KEY_ROW3_PORT,KEY_ROW3_PIN);  //0
	GPIO_SetBits(KEY_ROW4_PORT,KEY_ROW4_PIN);  //1
}

static void key_Row4_scan(void)
{
  GPIO_SetBits(KEY_ROW1_PORT,KEY_ROW1_PIN); // 1
	GPIO_SetBits(KEY_ROW2_PORT,KEY_ROW2_PIN);  //1
	GPIO_SetBits(KEY_ROW3_PORT,KEY_ROW3_PIN);  //1
	GPIO_ResetBits(KEY_ROW4_PORT,KEY_ROW4_PIN);  //0
}

uint8_t keyscan(void)
{
   uint16_t  temp;
	
	 key_Row1_scan();
	 temp = GPIO_ReadInputData(GPIOE);
	 temp  =temp & 0xD400;
	 if(temp != 0xD400)  //有键按下
	 {
	    Delay_ms(20);
      if(temp != 0xD400)	
      {
			   temp = GPIO_ReadInputData(GPIOE);
				 temp  = temp & 0xD400;
				 switch(temp)
				 {
				   case 0x5400 :  keyNum = 0x04; break;
					 case 0x9400 :  keyNum = 0x03; break;
					 case 0xc400 :  keyNum = 0x02; break;
					 case 0xd000 :  keyNum = 0x01; break;
				 }
				 while(temp != 0xD400)
				 {
			     temp = GPIO_ReadInputData(GPIOE);
				   temp  = temp & 0xD400;				 
				 }
			}				
	 }
	 
	 key_Row2_scan();
	 temp = GPIO_ReadInputData(GPIOE);
	 temp  =temp & 0xD400;
	 if(temp != 0xD400)  //有键按下
	 {
	    Delay_ms(20);
      if(temp != 0xD400)	
      {
			   temp = GPIO_ReadInputData(GPIOE);
				 temp  = temp & 0xD400;
				 switch(temp)
				 {
				   case 0x5400 :  keyNum = 0x08; break;
					 case 0x9400 :  keyNum = 0x07; break;
					 case 0xc400 :  keyNum = 0x06; break;
					 case 0xd000 :  keyNum = 0x05; break;
				 }
				 while(temp != 0xD400)
				 {
			     temp = GPIO_ReadInputData(GPIOE);
				   temp  = temp & 0xD400;				 
				 }
			}				
	 }

	 key_Row3_scan();
	 temp = GPIO_ReadInputData(GPIOE);
	 temp  =temp & 0xD400;
	 if(temp != 0xD400)  //有键按下
	 {
	    Delay_ms(20);
      if(temp != 0xD400)	
      {
			   temp = GPIO_ReadInputData(GPIOE);
				 temp  = temp & 0xD400;
				 switch(temp)
				 {
				   case 0x5400 :  keyNum = 0x0c; break;
					 case 0x9400 :  keyNum = 0x0b; break;
					 case 0xc400 :  keyNum = 0x0a; break;
					 case 0xd000 :  keyNum = 0x09; break;
				 }
				 while(temp != 0xD400)
				 {
			     temp = GPIO_ReadInputData(GPIOE);
				   temp  = temp & 0xD400;				 
				 }
			}				
	 }
	 
	 key_Row4_scan();
	 temp = GPIO_ReadInputData(GPIOE);
	 temp  =temp & 0xD400;
	 if(temp != 0xD400)  //有键按下
	 {
	    Delay_ms(20);
      if(temp != 0xD400)	
      {
			   temp = GPIO_ReadInputData(GPIOE);
				 temp  = temp & 0xD400;
				 switch(temp)
				 {
				   case 0x5400 :  keyNum = 0x10; break;
					 case 0x9400 :  keyNum = 0x0f; break;
					 case 0xc400 :  keyNum = 0x0e; break;
					 case 0xd000 :  keyNum = 0x0d; break;
				 }
				 while(temp != 0xD400)
				 {
			     temp = GPIO_ReadInputData(GPIOE);
				   temp  = temp & 0xD400;				 
				 }
			}				
	 }
   
	 return  keyNum;
	 
}

key.h:

#ifndef   _KEY_H
#define   _KEY_H
#ifdef  _cplusplus
   extern "C" {
#endif

#include "stm32f4xx.h"
		 
//key  row1  PE2
#define    KEY_ROW1_PIN   GPIO_Pin_2
#define    KEY_ROW1_PORT  GPIOE
#define    KEY_ROW1_CLK   RCC_AHB1Periph_GPIOE

//key  row2  PE4
#define    KEY_ROW2_PIN   GPIO_Pin_4
#define    KEY_ROW2_PORT  GPIOE
#define    KEY_ROW2_CLK   RCC_AHB1Periph_GPIOE

//key  row3  PE5
#define    KEY_ROW3_PIN   GPIO_Pin_5
#define    KEY_ROW3_PORT  GPIOE
#define    KEY_ROW3_CLK   RCC_AHB1Periph_GPIOE

//key  row4  PE6
#define    KEY_ROW4_PIN   GPIO_Pin_6
#define    KEY_ROW4_PORT  GPIOE
#define    KEY_ROW4_CLK   RCC_AHB1Periph_GPIOE

//key  col1  PE10
#define    KEY_COL1_PIN   GPIO_Pin_10
#define    KEY_COL1_PORT  GPIOE
#define    KEY_COL1_CLK   RCC_AHB1Periph_GPIOE

//key  col2  PE12
#define    KEY_COL2_PIN   GPIO_Pin_12
#define    KEY_COL2_PORT  GPIOE
#define    KEY_COL2_CLK   RCC_AHB1Periph_GPIOE

//key  col3  PE14
#define    KEY_COL3_PIN   GPIO_Pin_14
#define    KEY_COL3_PORT  GPIOE
#define    KEY_COL3_CLK   RCC_AHB1Periph_GPIOE

//key  col4  PE15
#define    KEY_COL4_PIN   GPIO_Pin_15
#define    KEY_COL4_PORT  GPIOE
#define    KEY_COL4_CLK   RCC_AHB1Periph_GPIOE

extern uint8_t keyNum;

extern void keyInit(void);
extern uint8_t keyscan(void);
#ifdef  _cplusplus
   }
#endif
   
#endif

main.c

#include "stm32f4xx.h"
#include "led_driver.h"
#include "uart_driver.h"
#include "data_process.h"
#include "delay.h"
#include "am2302.h"
#include "stdio.h"
#include "key.h"
AM2302_Data_TypeDef AM2302_Data;  

int fputc(int ch, FILE *f)
{
    USART_SendData(USART2, (unsigned char) ch);// USART1 可以换成 USART2 等
    while (!(USART2->SR & USART_FLAG_TXE));
    return (ch);
}

// 接收数据
int GetKey (void) 
{
    while (!(USART2->SR & USART_FLAG_RXNE));
    return ((int)(USART2->DR & 0x1FF));
}

int main(void)
{
    unsigned int RH_Value,TEMP_Value;  
    unsigned char RH_H,RH_L,TP_H,TP_L;  
	  unsigned char temp;
    LED_GPIO_Config();
	  Uart_Configuration();
	  keyInit();
//  SysTick_Init();
	  AM2302_GPIO_Config();
    Send_String( Uart2,"我是xiaozy\n");
		Delay_ms(90); 
		Delay_ms(90);
		Delay_ms(90);
		Delay_ms(90);
		Delay_ms(90);
		Delay_ms(90);
		Delay_ms(90);
		Delay_ms(90);
		Delay_ms(90);
		Delay_ms(90);
		Delay_ms(90); 
		Delay_ms(90);
		Delay_ms(90);
		Delay_ms(90);
		Delay_ms(90);
		Delay_ms(90);
		Delay_ms(90);
		Delay_ms(90);
		Delay_ms(90);
		Delay_ms(90);
    while(1)
	  {
		    /*调用Read_AM2302读取温湿度,若成功则输出该信息*/  
        if( Read_AM2302(&AM2302_Data)==SUCCESS)  
        {             
            //计算出实际湿度值的10倍  
            RH_Value= AM2302_Data.humiHighByte*256 + AM2302_Data.humiLowByte;  
            RH_H = RH_Value/10;  
            RH_L = RH_Value%10;  
            //计算出时间温度值的10倍  
            TEMP_Value = AM2302_Data.temmHighByte*256 + AM2302_Data.temmLowByte;  
            TP_H = TEMP_Value/10;  
            TP_L = TEMP_Value%10;  
            printf("\r\n读取AM2302成功!\r\n\r\n湿度为%d.%d %RH,温度为 %d.%d℃ \r\n",RH_H,RH_L,TP_H,TP_L);//“\”表示转向一下行  
        }  
        else  
            printf("Read AM2302 ERROR!\r\n");  
	    	dealData();
        temp = keyscan();
			  if(temp != 0)
				{
				  printf("\r\n读取的键值是:%d",temp);
					keyNum = 0;
				}
			  
	}
	 
	
}


实验结果:

blob.png

blob.png


必须注意的是:

GPIO_InitStructure.GPIO_PuPd =  GPIO_PuPd_UP;

本来这里之前设置的是不上拉也不下拉的,GPIO_PuPd_NOPULL,结果debug发现,每次读回的状态都不一样,应该是矩阵键盘外部没有上拉,所以,对于此种键盘,必须设置为,GPIO_PuPd_UP