2021-01-24

硬件介绍

本次实验的硬件依旧时实验二所需的实验器材,只是本次需要将矩阵键盘的八个接口都利用上,且矩阵键盘的电路图如下图所示
在这里插入图片描述
然后这里我们的电源模块也需要使用RXD TXD接口。

硬件连接

在这里插入图片描述
这里我们的矩阵键盘连接的对应端口如下
在这里插入图片描述
其次,我们的电源模块中的RXD需连接在单片机的TXD上,电源模块中的TXD需连接在单片机的RXD上。

程序书写

程序思路

首先我们依旧涉及到了按键的输入,所以首先想到的也是需要消抖
其次,这里我们需要判断时哪一个按键被按下了,确定按键按下的思路:令PD8 PD9 PD10 PD11为上拉输入 PB12 PB13 PB14 PB15为浮空输入,然后按下按键后扫描每一列,判断如果是1111则这一行有按键被按下,若按键被按下再通过判断是0111 1011 1101 1110来判断是这一列的第几行被按下,从而来准确判断出是哪一个键被按下。

key.c key.h的书写

听过上面的思路我们写出了如下程序:

#include "key16.h"
#include "delay.h"

uint8_t KEY_ROW[1] = {0XFF}; //定义一个数组,存放行扫描状态


void key_init(){

	GPIO_InitTypeDef GPIO_InitStruture;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
	
	//定义PB12、PB13、PB14、PB15为推挽输出 
	GPIO_InitStruture.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruture.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
	GPIO_InitStruture.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruture);
	
	//定义PD8、PD9、PD10、PD11为上拉输入 分别定义为四行
	GPIO_InitStruture.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStruture.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11;
	GPIO_Init(GPIOD,&GPIO_InitStruture);
	

}
//如果为1,代表没有按键被按下,如果为0,代表有按键被按下
char KEY_ROW_SCAN(){

	KEY_ROW[0] = GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_8)<<3;//读取PD8的状态并左移三位
	KEY_ROW[0] = KEY_ROW[0]|GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_9)<<2;读取PD8的状态并左移两位
	KEY_ROW[0] = KEY_ROW[0]|GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_10)<<1;读取PD8的状态并左移一位
	KEY_ROW[0] = KEY_ROW[0]|GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_11);
	
	if(KEY_ROW[0] !=0x0f)//不是1111,代表肯定有一个0
		{
			delay_ms(10);
			if(KEY_ROW[0] !=0x0f){
			//0111 1011 1101 1110
				switch(KEY_ROW[0]){
					case 0x07:  //0111 第一行
						return 1;
					case 0x0b:  //1011 第二行
						return 2;
					case 0x0d:  //1101 第三行
						return 3;
					case 0x0e:  //1110 第四行
						return 4;
					default:
						return 0;
			}		
		}else return 0;
	}else return 0;
}

char KEY_SCAN(){
	char key=0;//存放那个按键被按下(按键号)
	char row_num=0;//存放行扫描结果(哪一个被按下)
	
	//扫描第0列
	KEY_CLO0_OUT_LOW;
	if( (row_num = KEY_ROW_SCAN())!=0){
		while((row_num=KEY_ROW_SCAN())!=0){//按键消抖
			key=0+row_num;
		}
	}
	KEY_CLO0_OUT_HIGH;
	
	//扫描第1列
	KEY_CLO1_OUT_LOW;
	if( (row_num = KEY_ROW_SCAN())!=0){
		while((row_num = KEY_ROW_SCAN())!=0){
			key=4+row_num;
		}
	}
	KEY_CLO1_OUT_HIGH;
	
	//扫描第2列
	KEY_CLO2_OUT_LOW;
	if( (row_num = KEY_ROW_SCAN())!=0){
		while((row_num = KEY_ROW_SCAN())!=0){
			key=8+row_num;
		}
	}
	KEY_CLO2_OUT_HIGH;
	
	//扫描第3列
	KEY_CLO3_OUT_LOW;
	if( (row_num = KEY_ROW_SCAN())!=0){
		while((row_num = KEY_ROW_SCAN())!=0){
			key=12+row_num;
		}
	}
	KEY_CLO3_OUT_HIGH;
	
	return key;
	
}

注意这里对较新内容的理解
在这里插入图片描述
在key.c中使用的部分变量与函数在key.h中定义如下

#ifndef _KEY16_H
#define _KEY16_H

#include "sys.h"
#include "stm32f10x.h"

#include <string.h>

#define KEY_row0_Pin GPIO_Pin_8
#define KEY_row1_Pin GPIO_Pin_9
#define KEY_row2_Pin GPIO_Pin_10
#define KEY_row3_Pin GPIO_Pin_11



void key_init();
char KEY_ROW_SCAN();
char KEY_SCAN();

#define KEY_CLO0_OUT_LOW  GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_RESET) 
#define KEY_CLO1_OUT_LOW  GPIO_WriteBit(GPIOB,GPIO_Pin_13,Bit_RESET)
#define KEY_CLO2_OUT_LOW  GPIO_WriteBit(GPIOB,GPIO_Pin_14,Bit_RESET)
#define KEY_CLO3_OUT_LOW  GPIO_WriteBit(GPIOB,GPIO_Pin_15,Bit_RESET)

#define KEY_CLO0_OUT_HIGH  GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_SET) 
#define KEY_CLO1_OUT_HIGH  GPIO_WriteBit(GPIOB,GPIO_Pin_13,Bit_SET)
#define KEY_CLO2_OUT_HIGH  GPIO_WriteBit(GPIOB,GPIO_Pin_14,Bit_SET)
#define KEY_CLO3_OUT_HIGH  GPIO_WriteBit(GPIOB,GPIO_Pin_15,Bit_SET)


#endif

最后效果

这里写完上面的程序之后我得到的效果便是,十六个键的按下与否都能读取,且将十六个键从上到下从左到右依次定义为了1–16.(由于不能上传视频,所以只能口述了)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值