xzy610030

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

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

0
阅读(6628)

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


左边的为行,右边的为列,扫描的原理大概如下:行为输出,列为输入。先让第一行为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


Baidu
map