stm32F4----薄膜4*4矩阵键盘读取(七)
0赞
发表于 3/10/2017 1:05:48 AM
阅读(9096)
买了个矩阵键盘,原理图如下:

左边的为行,右边的为列,扫描的原理大概如下:行为输出,列为输入。先让第一行为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
#endifmain.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;
}
}
}实验结果:


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