题目:基于STM32控制的矩阵键盘的仿真设计
课程名称:ARM 嵌入式系统
学生姓名:张宇
学生学号:1314030140
系别:电子工程学院
专业:通信工程
年级:2013级
指导教师:权循忠
淮南师范学院电气信息工程学院12级电技专业电子线路CAD课程设计
电子工程学院制
2015年10月
目录
1摘要 (1)
2关键字 (1)
3引言 (1)
4 STM32控制的矩阵键盘系统方案计制定 (1)
4.1 系统总体设计方案 (1)
4.2总体设计框图 (1)
4.3矩阵键盘简介 (2)
5 矩阵键盘设计原理分析 (2)
5.1 STM32复位和时钟电路设计 (2)
5.2 矩阵键盘电路的设计 (2)
5.3按键去抖动 (3)
5.4 按键显示电路 (3)
6程序流程图 (4)
7 总体电路图 (5)
8 软件仿真 (5)
9 总结 (6)
10 参考文献: (6)
11 附录 (7)
基于STM32控制的矩阵键盘的仿真设计
学生:张宇
指导老师:权循忠
电子工程学院通信工程
1摘要
矩阵键盘又称行列键盘,它是用四条I/O线作为行线,四条I/O线作为列线组成的键盘。在行线和列线的每个交叉点上设置一个按键。这样键盘上按键的个数就为4*4个。这种行列式键盘结构能有效地提高ARM嵌入式系统中I/O口的利用率。
2关键字
矩阵键盘行列键盘ARM嵌入式系统
3引言
随着人们生活水平的不断提升,ARM嵌入式无疑是人们追求的目标之一,它给人带来的方便也是不可否认的,要为现代人工作、科研、生活、提供更好更方便的设备就需要从ARM嵌入式技术入手,一切向若数字化控制,智能化控制方向发展。用ARM嵌入式来控制的数码管显示按键也在广泛应用,其控制系统具有极大意义。展望未来,急速的响应速度将成为个性的ARM嵌入式发展的趋势,越来越多的ARM嵌入式正如雨后春笋般涌现。
4 STM32控制的矩阵键盘系统方案计制定
4.1 系统总体设计方案
该智能键盘电路由ARM最小系统,矩阵键盘电路和显示电路组成,在常规的4*4矩阵键盘的基础上,通过改进实现了用4个IO口完成4*4矩阵键盘。
4.2总体设计框图
本电路主要由3大部分电路组成:矩阵键盘电路、ARM最小系统电路、按键显示电路。其中ATM最小系统主要由复位电路和时钟电路组成。电路复位后数码管显示字符“—”表示没有按键,显示电路由STM32的PD0—PD7来控制数码管显示是哪个按键按下。总体设计方框图,如图1所示。
图1总体设计方框图
4.3矩阵键盘简介
矩阵键盘又称行列键盘,它是用四条I/O线作为行线,四条I/O线作为列线组成的键盘。在行线和列线的每个交叉点上设置一个按键。这样键盘上按键的个数就为4*4个。这种行列式键盘结构能有效地提高ARM嵌入式系统中I/O口的利用率。
5 矩阵键盘设计原理分析
5.1 STM32复位和时钟电路设计
此电路主要是复位电路和时钟电路两部分,其中复位电路采用按键手动复位和上电自动复位组合,电路如图2(右)所示:其中14脚为STM32的复位端。时钟电路如图2(左)所示:晶振采用的是8MHz和32.786KHz,8MKz分别接STM32的12脚和13脚,32.786KHz分别接STM32的8脚和9脚。
图2 STM复位和时钟电路设计
5.2 矩阵键盘电路的设计
该电路的四个端子分别接STM32的PB12—PB15,电路如图3所示。
图3 矩阵键盘电路
该矩阵键盘电路扫描方法如下:
(1)PB15,PB14,PB13,PB12设置为输入并内部上拉。程序读取这四个IO口引脚电平,如果某个IO为低电平,则该列中相应IO口对应行处的按键按下。
(2)PB15输出低电平,PB14,PB13,PB12设置为输入并内部上拉。程序读取PB14,PB13,PB12这三个IO口的引脚电平。如果某个IO为低电平,则是第一列中相应IO口对应行处的按键按下。
(3)PB14输出低电平,PB15,PB13,PB12设置为输入并内部上拉。程序读取PB15,PB13,PB12这三个IO口的引脚电平。如果某个IO为低电平,则是第二列中相应IO口对应行处的按键按下。
(4)PB13输出低电平,PB15,PB14,PB12设置为输入并内部上拉。程序读取PB15,PB14,PB12这三个IO口的引脚电平。如果某个IO为低电平,则是第三列中相应IO口对应行处的按键按下。
(5)PB12输出低电平,PB15,PB14,PB13设置为输入并内部上拉。程序读取PB15,PB14,PB13这三个IO口的引脚电平。如果某个IO为低电平,则是第四列中相应IO口对应行处的按键按下。
5.3按键去抖动
每隔10ms扫描键盘一次,当扫描某个按键按下时,则开始计数,当连续4次扫描(也就是40ms)都是这个按键按下时,说明按键有效。如果不到四次计数,就采集不到该按键按下,则说明该按键无效。
5.4 按键显示电路
本设计采用STM32的IO口PD0—PD7来控制数码管来实时显示按键状态。当按键有按下时,数码管将显示对应的按键编号“0—F”,对应表示的按键是“SW1
—SW16”。按键显示电路,如图4。
图4 按键显示电路
6程序流程图
先对键盘初始化,看读列线是否有键按键,再延时消抖,再看读列是否有键按下,最后根据当前状态识别按键,显示键值。
程序流程图,如图5所示。
图5 程序流程图
流程图描述:先对键盘值进行初始化,判断列线是否有按键按下,若无直接返回结果,若有则进行延时消抖,然后继续判断列线是否有按键按下,若无直接返回结果,若有根据当前状态识别按键,显示按键值,返回结果。
7 总体电路图
把矩阵键盘电路、ARM最小系统电路、按键显示电路连接在一起。其中ATM最小系统主要由复位电路和时钟电路组成。
总体电路图,如图6所示。
图6 总体电路图
8 软件仿真
首先,我们进行软件仿真,点击按钮Debug,然后再点击波形图按钮,出现逻辑分析窗口,点击Setup,新建6个信号PORTB.2、PORTB.8、PORTB.9、PORTB.10、PORTB.13、和PORTB.14。Display Type全部选择Bit,然后选择各个颜色。然后再点击Peripherals General Purpose I/O GPIOB。然后设置各个引脚电平,然后在x=KEY_Scan()处设置一个断点,点击Run按钮,会出现以下波形即实验成功。
图7 软件仿真
9 总结
一学期的ARM课程即将结束,从一开始对ARM的完全陌生到现在的慢慢入门,其中体会到了很多ARM的妙处和实用意义。通过这次矩阵键盘的设计,使我对ARM有了更深的理解。在做课程论文时增强了对论文格式的修改,熟悉和掌握了ARM工程项目的建立与生成,在遇到程序出现错误时及时的翻书查看或者上网查找,并且在后期的ARM实训课中自己尝试在ARM开发板上进行调试,让我深刻领悟到理论和实践相结合的重要意义。只有把理论运用到实践中才能很好掌握理论和技术。所以以后不管在学什么知识都要重视理论与实践相结合。这样就好觉得其实学知识也不是那么难,更重要的是体现的学习的实际用处。
10 参考文献:
[1] 彭刚、秦志强等.基于ARM Cortex-M3的STM32系列嵌入式微控制器应用实践[M].北京:电子工业出版社
[2] 李宁.基于MDK的STM32处理器开发应用 [M].北京航空航天大学出版社,2008.
[3]潘松、黄继业等.EDA技术实用教程(第一版)[M].科学出版社 2002年10月
[4]陆坤、奚大顺、李之权等.电子设计技术[M].四川:电子科技大学出版社.1997年.682-688,838-941
[5]赵俊超.集成电路设计VHDL教程(第一版)[M].北京:北京希望电子出版社.2002年
[6]杨邦文.新型实用电路制作200例[M].北京:人民邮电出版社.1998年.175-288
[7]许海燕、付炎著.嵌入式系统技术与应用.机械工业出版社.2002年
[8]周主力主编.ARM嵌入式系统基础教程.北京航空航天大学出版社.2005年
[9]田泽主编.嵌入式系统开发与应用教程.北京航空航天大学出版社
11 附录
主程序
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "key.h"
#include "usart.h"
#include "stdio.h"
int main(void)
{
int x;
SystemInit();
delay_init(72); //延时初始化
NVIC_Configuration();
uart_init(9600);
LED_Init();
KEY_Init(); //初始化与按键连接的硬件接口
while(1)
{
x=KEY_Scan(); //得到键值
switch(x)
{
case 0:
// LED=0;
printf("D\n");
break;
case 1:
LED=1;
printf("C\n");
break;
case 2:
LED=2;
printf("B\n");
break;
case 3:
LED=3;
printf("A\n");
break;
case 4:
LED=4;
printf("#\n");
break;
case 5:
LED=5;
printf("9\n");
break;
case 6:
LED=6;
printf("6\n");
break;
case 7:
LED=7;
printf("3\n");
break;
case 8:
LED=8;
printf("0\n");
break;
case 9:
LED=9;
printf("8\n");
break;
case 10:
LED=10;
printf("5\n");
break;
case 11:
LED=11;
printf("2\n");
break;
case 12:
LED=12;
printf("*\n");
break;
case 13:
LED=13;
printf("7\n");
break;
case 14:
LED=14;
printf("4\n");
break;
case 15:
LED=15;
printf("1\n");
break;
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
key.c //按键扫描
#include "stm32f10x.h"
#include "delay.h"
#include "key.h"
/*本文件的函数,主要实现矩阵键盘的功能。矩阵键盘使用PB8到PB15引脚,其中,PB8到PB11固定为
推挽输出,PB12到PB15固定为下拉输入。即,无键按下时,对应PB12到PB15为0,有键按下时,PB12到PB15中,
对应的引脚为高。*/
void KEY_Init(void) //初始化矩阵键盘要使用的GPIO口。
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //定义PB8到PB11为上拉输入、、。
GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11;
GPIO_Init(GPIOB,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //定义PB12到PB15为下拉输入。
GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
//因为上面定义引脚为输出时,已经打开整个GPIOA的时钟了,
//所以此处不再需要函数RCC_APB2PeriphClockCmd()来打开时钟了。
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
int KEY_Scan(void) //实现矩阵键盘。返回值为,各按键的键值,此键值由用户自己定义。
{
u8 KeyVal; //keyVal为最后返回的键值。
GPIO_Write(GPIOB,(GPIOB->ODR & 0xf0ff | 0x0f00)); //先让PB8到PB11全部输出高。
if((GPIOB->IDR & 0xf000)==0x0000) //如果PB12到PB15全为0,则没有键按下。此时,返回值为-1.
return -1;
else
{
delay_ms(5); //延时5ms去抖动。
if((GPIOB->IDR & 0xf000)==0x0000)//如果延时5ms后,PB12到PB15又全为0,则,刚才引脚的电位变化是抖动产生的.
return -1;
}
GPIO_Write(GPIOB,(GPIOB->ODR & 0xf0ff | 0x0100)); //让PB11到PB8输
出二进制的0001.
switch(GPIOB->IDR & 0xf000)//对PB12到PB15的值进行判断,以输出不同的键值。
{
case 0x1000: KeyVal=15; break;
case 0x2000: KeyVal=11; break;
case 0x4000: KeyVal=7; break;
case 0x8000: KeyVal=3; break;
}
GPIO_Write(GPIOB,(GPIOB->ODR & 0xf0ff | 0x0200)); //让PB11到PB8输出二进制的0.
switch(GPIOB->IDR & 0xf000) //对PB12到PB15的值进行判断,以输出不同的键值。
{
case 0x1000: KeyVal=14; break;
case 0x2000: KeyVal=10; break;
case 0x4000: KeyVal=6; break;
case 0x8000: KeyVal=2; break;
}
GPIO_Write(GPIOB,(GPIOB->ODR & 0xf0ff | 0x0400)); //让PB11到PB8输出二进制的1011.
switch(GPIOB->IDR & 0xf000) //对PB12到PB15的值进行判断,以输出不同的键值。
{
case 0x1000: KeyVal=13; break;
case 0x2000: KeyVal=9; break;
case 0x4000: KeyVal=5; break;
case 0x8000: KeyVal=1; break;
}
GPIO_Write(GPIOB,(GPIOB->ODR & 0xf0ff | 0x0800)); //让PB11到PB8输出二进制的0111.
switch(GPIOB->IDR & 0xf000) //对PB12到PB15的值进行判断,以输出不同的键值。
{
case 0x1000: KeyVal=12; break;
case 0x2000: KeyVal=8; break;
case 0x4000: KeyVal=4; break;
case 0x8000: KeyVal=0; break;
}
return KeyVal;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////
key.h 文件
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
#define KEY0 PBin(8) //PB8
#define KEY1 PBin(9) //PB9
#define KEY2 PBin(10) //PA10
#define KEY3 PBin(11) //PA11
#define KEY4 PBin(12) //PA12
#define KEY5 PBin(13) //PA13
#define KEY6 PBin(14) //PA14
#define KEY7 PBin(15) //PA15
void KEY_Init(void);//IO初始化
int KEY_Scan(void);
方法一、 ORG 0000H LJMP MAIN ORG 0100H MAIN: MOV P1,#0F0H //P1口设初值F0,矩阵按键高四位置1,低四位置0, JNB P1.4,Y0 //用JNB检测按键端口,P1.4口低电平跳转 Y0 JNB P1.5,Y1 JNB P1.6,Y2 JNB P1.7,Y3 SJMP MAIN Y0: MOV 30H,#00H MOV P1,#0EFH JNB P1.4,X0 MOV P1,#0DFH JNB P1.4,X1 MOV P1,#0BFH JNB P1.4,X2 MOV P1,#07FH JNB P1.4,X3 Y1: MOV 30H,#01H MOV P1,#0EFH JNB P1.0,X0 MOV P1,#0DFH JNB P1.1,X1 MOV P1,#0BFH JNB P1.2,X2 MOV P1,#7FH JNB P1.3,X3 Y2: MOV 30H,#02H MOV P1,#0EFH JNB P1.0,X0 MOV P1,#0DFH JNB P1.1,X1 MOV P1,#0BFH JNB P1.2,X2 MOV P1,#7FH JNB P1.3,X3 Y3: MOV 30H,#03H MOV P1,#0EFH
MOV P1,#0DFH JNB P1.1,X1 MOV P1,#0BFH JNB P1.2,X2 MOV P1,#7FH JNB P1.3,X3 X0: MOV 31H,#00H ACALL DELAY MOV P1,#0F0H LJMP JISUAN X1: MOV 31H,#01H ACALL DELAY MOV P1,#0F0H LJMP JISUAN X2: MOV 31H,#02H ACALL DELAY MOV P1,#0F0H LJMP JISUAN X3: MOV 31H,#03H ACALL DELAY MOV P1,#0F0H LJMP JISUAN JISUAN: MOV A,31H MOV B,#04H MUL AB ADD A,30H MOV DPTR,#TAB MOVC A,@A+DPTR MOV P0,A CC: MOV A,P1 ANL A,#0F0H XRL A,#0F0H JNZ CC LCALL MAIN DELAY: MOV R4,#0C5H D1: MOV R5,#43H D0: MOV R6,#10H
键盘是单片机常用输入设备,在按键数量较多时,为了节省I/O口等单片机资源,一般采取扫描的方式来识别到底是哪一个键被按下。即通过确定被按下的键处在哪一行哪一列来确定该键的位置,获取键值以启动相应的功能程序。 4*4矩阵键盘的结构如图1(实物参考见万用板矩阵键盘制作技巧)。在本例中,矩阵键盘的四列依次接到单片机的P1.0~P1.3,四行依次接到单片机的P1.4~P1.7;同时,将列线上拉,通过10K电阻接电源。 查找哪个按键被按下的方法为:一个一个地查找。 先第一行输出0,检查列线是否非全高; 否则第二行输出0,检查列线是否非全高; 否则第三行输出0,检查列线是否非全高; 如果某行输出0时,查到列线非全高,则该行有按键按下; 根据第几行线输出0与第几列线读入为0,即可判断在具体什么位置的按键按下。 下面是具体程序:
void Check_Key(void) { unsigned char row,col,tmp1,tmp2; tmp1 = 0x10; //tmp1用来设置P1口的输出,取反后使 P1.4~P1.7中有一个为0 for(row=0;row<4;row++) // 行检测 { P1 = 0x0f; // 先将p1.4~P1.7置高 P1 =~tmp1; // 使P1.4~p1.7中有一个为0 tmp1*=2; // tmp1左移一位 if ((P1 & 0x0f) < 0x0f) // 检测P1.0~P1.3中是否有一位为0,只要有,则说明此行有键按下,进入列检测 { tmp2 = 0x01; // tmp2用于检测出哪一列为0 for(col =0;col<4;col++) // 列检测 { if((P1 & tmp2)==0x00) // 该列如果为低电平则可以判定为该列 { key_val =key_Map[ row*4 +col ]; // 获取键值,识别按键;key_Map为按键的定义表 return; // 退出循环 } tmp2*=2; // tmp2左移一位 } } } } //结束 这是一种比较经典的矩阵键盘识别方法,实现起来较为简单,程序短小精炼。
/*编译环境:Keil 7.50A c51 */ /*******************************************************/ /*********************************包含头文件********************************/ #include
/*风清云扬*/ # include } else if(temp0==0x0b) { switch (temp1) { case 0xe0: num=12;break; case 0xd0: num=11;break; case 0xb0: num=10;break; case 0x70: num=9;break; default:num=0;break; } } else if(temp0==0x07) { switch (temp1) { case 0xe0: num=16;break; case 0xd0: num=15;break; case 0xb0: num=14;break; case 0x70: num=13;break; default:num=0;break; } } } } return num; } void main() { char num; while(1) { num=key_scan(); P2=num/10; P3=num%10; } } X4扫描式矩阵键盘课程设计 (总13页) -CAL-FENGHAI.-(YICAI)-Company One1 -CAL-本页仅作为文档封面,使用请直接删除 4X4扫描式矩阵键盘课程设计 课程设计名称: 4_4扫描式矩阵键盘设计 姓名: DUKE 班级:电子1008班 学号: 10086 成绩: 日期: 2014年1月6日 摘要 随着21世纪的到来,电子信息行业将是人类社会的高科技行业之一,式设施现代化的基础,也是人类通往科技巅峰的直通路。电子行业的发展从长远来看很重要,但最主要的还是科技问题。 矩阵式键盘提高效率进行按键操作管理有效方法,它可以提高系统准确性,有利于资源的节约,降低对操作者本身素质的要求。是它能准时、实时、高效地显示按键信息,以提高工作效率和资源利用率。 矩阵式键盘乃是当今使用最为广泛的键盘模式,该系统以N个端口连接控制N*N 个按键,显示在LED数码管上。单片机控制依据这是键盘显示系统,该系统可以对不同的按键进行实时显示,其核心是单片机和键盘矩阵电路部分,主要对按键与显示电路的关系、矩阵式技术及设备系统的硬件、软件等各个部分进行实现。 4*4矩阵式键盘采用AT89C51单片机为核心,主要由矩阵式键盘电路、译码电路、显示电路等组成,软件选用C语言编程。单片机将检测到的按键信号转换成数字量,显示于LED显示器上。该系统灵活性强,易于操作,可靠性高,将会有更广阔的开发前景。 目录 第一章:系统功能要求-------------------------------------------------------- 4*4 矩阵式键盘系统概述------------------------------------------------ 本设计任务和主要内容--------------------------------------------------- 第二章:方案论证--------------------------------------------------------------- 第三章:系统硬件电路的设计------------------------------------------------ 单片机控制系统原理----------------------------------------------------- 原理图绘制说明---------------------------------------------------------- 画出流程图---------------------------------------------------------------- 原理图绘制--------------------------------------------------------------- 第四章:系统程序的设计------------------------------------------------------ 程序的编写步骤----------------------------------------------------------- 4×5矩阵键盘驱动程序 一、工作原理及接口电路 4×5矩阵键盘有4条列线,5条行线共20个按键。每个按键对应不同键值,键盘扫描采用外部中断扫描方式,本系统中键盘为无源结构,键盘工作时不依靠任何外部电源。4×5矩阵键盘结构图如图2-10 所示。 图2-10 4×5矩阵键盘结构图 1)4×5矩阵键盘结构及按键抖动消除 当键盘中按键数量较多时为减少I/O口的占用,通常将按键排列成矩阵形式,如图2-12所示。在矩阵式键盘中,每条行线和列线在交叉处不直接连通,而是通过一个机械弹性开关加以连接。这样5条列线(R0~R4)和4条行线(L0~L3)就可以构成20个按键的矩阵键盘。键盘采用了无源结构,工作是不依靠任何外部电源。 由于机械弹性开关的机械触点的弹性作用,一个按键开关在闭合时并不会马上稳定的闭合,在断开时也不会马上断开,因而机械开关在闭合及断开瞬间均伴有一连串的抖动,如图2-11所示。 图2-11 按键时的抖动 抖动的时间长短由按键开关机械特性及按键的人为因素决定,一般为5ms~20ms。按键抖动如果处理不当会引起一次按键被误处理多次,所以消除抖动是必要的。消除抖动的有硬件处理和软件处理两种方法。当按键较多一般采用软件消抖方式。软件消抖原理为当检测出按键闭合后执行一个延时程序(产生5ms~20ms的延时),待前沿抖动消失后再次检测按键的状态,如果按键仍保持闭合状态则可确认为有键按下。当检测到按键释放并执行延时程序,待后沿抖动消失后才转入按键的处理程序。 1)矩阵键盘的工作原理 从4×5矩阵键盘的4条列线和5条行线分别引出9条端线接于单片机的9个I/O 口,由于键盘采用了无源结构所以行列线的电平由单片机I/O口的电平决定。进入按键处理程序后先使4条列线全为低电平,5条行线全为高电平,为读行线状态做准备,没有按键时这种状态不会被改变。当键盘上的某个按键闭合时,则该键所对应的行线和列线被短路。例如:6号键被按下时列线L2与行线R1被短路,此时行线R1电平被列线L2拉低,由原来的高电平变为低电平而其它行线电平依然不变,为低电平。此时单片机可读得行线状态进而判断按键所在行并记录下行号。之后使得4条列线全为高电平,5条行线全为低电平,为读列线状态做准备。同理6号键被按下时列线L2与行线R1被短路,此时列线L2电平被行线R1拉低,由原来的高电平变为低电平而其它行线电平依然不变,为低电平。此时单片机可读得列线状态进而判断按键所在列并记录下列号。然后按一定的按键编码规则可计算出6号键的键值。 2)键盘扫描方式 键盘扫描方式一般有三种:循环扫描方式,定时扫描方式,外部中断扫描方式。循环扫描方式需要不停地扫描键盘,影响其它功能执行工作效率低。定时扫描方式是利用单片机内部的定时器,产生一个适当时间的定时中断,单片机响应中断时对键盘进行扫描取键值过程,但是这种扫描方式不管键盘上是不是有键闭合单片机总是定时地扫描工作效率还是不高。外部中断扫描方式是只在键盘上有 #include temp=P2; temp&=0x0f; if(temp!=0x0f) { temp=P2; switch(temp) { case 0xb7:num=4;break; case 0xbb:num=5;break; case 0xbd:num=6;break; case 0xbe:num=7;break; } } } P2=0xdf; temp=P2; temp&=0x0f; if(temp!=0x0f) { delay1ms(2); temp=P2; temp&=0x0f; if(temp!=0x0f) { temp=P2; switch(temp) { case 0xd7:num=8;break; case 0xdb:num=9;break; case 0xdd:num=10;break; case 0xde:num=11;break; } } } P2=0xef; temp=P2; temp&=0x0f; if(temp!=0x0f) { delay1ms(2); 4×4矩阵键盘51单片机识别实验与程序 1.实验任务 如图所示,用AT89S51的并行口P1接4×4矩阵键盘,以-作输入线,以-作输出线;在数码管上显示每个按键的“0-F”序号。对应的按键的序号排列如图所示 图 2.硬件电路原理图 图 3.系统板上硬件连线 (1.把“单片机系统“区域中的-端口用8芯排线连接到“4X4行列式键盘” 区域中的C1-C4 R1-R4端口上; (2.把“单片机系统”区域中的AD0-AD7端口用8芯排线连接到“四路静态数码显示模块”区域中的任一个a-h端口上;要求:AD0对应着a,AD1 对应着b,……,AD7对应着h。 4.程序设计内容 (1.4×4矩阵键盘识别处理 (2.每个按键有它的行值和列值,行值和列值的组合就是识别这个按键的编码。矩阵的行线和列线分别通过两并行接口和CPU通信。每个按键 的状态同样需变成数字量“0”和“1”,开关的一端(列线)通过电 阻接VCC,而接地是通过程序输出数字“0”实现的。键盘处理程序的 任务是:确定有无键按下,判断哪一个键按下,键的功能是什么;还 要消除按键在闭合或断开时的抖动。两个并行口中,一个输出扫描码, 使按键逐行动态接地,另一个并行口输入按键状态,由行扫描值和回 馈信号共同形成键编码而识别按键,通过软件查表,查出该键的功能。 5.程序框图 图 C语言源程序 #include <> unsigned char code table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; unsigned char temp; S T M矩阵键盘程序公司标准化编码 [QQX96QT-XQQB89Q8-NQQJ6Q8-MQM9N] /*--------------------------------------------------------------------------------------* 矩阵键盘驱动 * 文件: * 编写人: LiuHui * 描述:扫描4x4 矩阵键盘输入,并返回键值 * 适用范围:驱动采用库编写,适用于STM32F10x 系列单片机 * 所用引脚: PA0-PA7 * 编写时间: 2014 年5 月20 日 --------------------------------------------------------------------------------------*/ #include "" #include "" #include "" /*--------------------------------矩阵键盘初始化----------------------------------------* 功能:初始化stm32 单片机GPIO //PA0-PA7 * 参数传递: * 输入:无 * 返回值:无 --------------------------------------------------------------------------------------*/ void KeyBoard_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; = GPIO_Speed_10MHz; = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; = GPIO_Speed_10MHz; = GPIO_Mode_IPD; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_SetBits(GPIOA, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3); GPIO_ResetBits(GPIOA, GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7); } /*------------------------------矩阵键盘扫描--------------------------------------------* 功能:扫描矩阵键盘,并返回键值 * 参数: * 输入:无 * 返回:有键按下返回该键值 * 无键按下时则返回0 南京林业大学 实验报告 基于AT89C51 单片机4x4矩阵键盘接口电路设计 课程机电一体化设计基础 院系机械电子工程学院 班级 学号 姓名 指导老师杨雨图 2013年9月26日 一、实验目的 1、掌握键盘接口的基本特点,了解独立键盘和矩阵键盘的应用方法。 2、掌握键盘接口的硬件设计方法,软件程序设计和贴士排错能力。 3、掌握利用Keil51软件对程序进行编译。 4、用Proteus软件绘制“矩阵键盘扫描”电路,并用测试程序进行仿真。 5、会根据实际功能,正确选择单片机功能接线,编制正确程序。对实验结果 能做出分析和解释,能写出符合规格的实验报告。 二、实验要求 通过实训,学生应达到以下几方面的要求: 素质要求 1.以积极认真的态度对待本次实训,遵章守纪、团结协作。 2.善于发现数字电路中存在的问题、分析问题、解决问题,努力培养独立 工作能力。 能力要求 1.模拟电路的理论知识 2.脉冲与数字电路的理念知识 3.通过模拟、数字电路实验有一定的动手能力 4.能熟练的编写8951单片机汇编程序 5.能够熟练的运用仿真软件进行仿真 三、实验工具 1、软件:Proteus软件、keil51。 2、硬件:PC机,串口线,并口线,单片机开发板 四、实验内容 1、掌握并理解“矩阵键盘扫描”的原理及制作,了解各元器件的参数及格 元器件的作用。 2、用keil51测试软件编写AT89C51单片机汇编程序 3、用Proteus软件绘制“矩阵键盘扫描”电路原理图。 4、运用仿真软件对电路进行仿真。 五.实验基本步骤 1、用Proteus绘制“矩阵键盘扫描”电路原理图。 2、编写程序使数码管显示当前闭合按键的键值。 3、利用Proteus软件的仿真功能对其进行仿真测试,观察数码管的显示状 态和按键开关的对应关系。 4、用keil51软件编写程序,并生成HEX文件。 5、根据绘制“矩阵键盘扫描”电路原理图,搭建相关硬件电路。 6、用通用编程器或ISP下载HEX程序到MCU。 7、检查验证结果。 s t m控制乘矩阵键盘程 序带松手检测 Document serial number【NL89WT-NY98YT-NC8CB-NNUUT-NUT108】 #include"stm32f10x.h" #include"delay.h" /*本文件的函数,主要实现矩阵键盘的功能。矩阵键盘使用PA0到PA7引脚,其中,PA0到PA3固定为推挽输出,PA4到PA7固定为 下拉输入。即,无键按下时,对应PA4到PA7为0,有键按下时,PA4到PA7中,对应的引脚为高。 此程序有一点要注意:要用到的IO口,必须是PX0-PX7,,不能是其他连续的数字。。如果非要改。。如:已经没有连续的0-7的IO口,需要在几个地方修改,请注意!! 此程序带有松手检测。。。。*/ voidInitKey(void)//初始化矩阵键盘要使用的GPIO口。 { GPIO_InitTypeDefGPIOStru; GPIOStru.GPIO_Mode=GPIO_Mode_Out_PP;//定义PA0到PA3为推挽输出。 GPIOStru.GPIO_Speed=GPIO_Speed_50MHz; GPIOStru.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_Init(GPIOA,&GPIOStru); GPIOStru.GPIO_Mode=GPIO_Mode_IPD;//定义PA4到PA7为下拉输入。 GPIOStru.GPIO_Speed=GPIO_Speed_50MHz; GPIOStru.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7; //因为上面定义引脚为输出时,已经打开整个GPIOA的时钟了,所以此处不再需要函数RCC_APB2PeriphClockCmd()来打开时钟了。 GPIO_Init(GPIOA,&GPIOStru); } intkey(void)//实现矩阵键盘。返回值为,各按键的键值,此键值由用户自己定义。 { intKeyVal=0; //keyVal为最后返回的键值。 u16WriteVal=0; //WriteVal为要写给PA口的数据。 GPIO_Write(GPIOA,(GPIOA->ODR&0xfff0|0xf));//先让PA0到PA3全部输出高。 if((GPIOA->IDR&0x00f0)==0x0000)//如果,PA4到PA7全为0,则,没有键按下。此时,返回值为-1. return-1; else { delay_ms(5);//延时5ms去抖动。 if((GPIOA->IDR&0x00f0)==0x0000)//如果,延时5ms后,PA4到PA7又全为0,则,刚才引脚的电位变化是抖动产生的. return-1; } GPIO_Write(GPIOA,(GPIOA->ODR&0xfff0|0x1)); //让PA3到PA0输出二进制的0001. switch(GPIOA->IDR&0x00f0) //对PA4到PA7的值进行判断,以输出不同的键值。 { case0x0010:KeyVal=15; break; STM32用矩阵键盘,不带外部中断,可以多个按键同时按下 C代码: STM32用矩阵键盘,不带外部中断,可以多个按键同时按下 /**************矩阵键盘.h文件*********************************/ #ifndef __COMMON_H #define __COMMON_H #include "" /* 4*4矩阵键盘 */ void keyboard_init(void); void update_key(void); extern unsigned char key[4][4]; #endif /**************矩阵键盘.c文件*****************************/ #include "" struct io_port { GPIO_TypeDef *GPIO_x; unsigned short GPIO_pin; }; static struct io_port key_output[4] = { {GPIOD, GPIO_Pin_0}, {GPIOD, GPIO_Pin_1}, {GPIOD, GPIO_Pin_2}, {GPIOD, GPIO_Pin_3} static struct io_port key_input[4] = { {GPIOD, GPIO_Pin_4}, {GPIOD, GPIO_Pin_5}, {GPIOD, GPIO_Pin_6}, {GPIOD, GPIO_Pin_7} }; unsigned char key[4][4]; void keyboard_init(void) { GPIO_InitTypeDef GPIO_InitStructure; unsigned char i; /* 键盘行扫描输出线输出高电平 */ /* PA0 PA1 PA2 PA3 输出*/ = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; = GPIO_Mode_Out_PP; = GPIO_Speed_50MHz; GPIO_Init(GPIOD, &GPIO_InitStructure); /* 键盘列扫描输入线键被按时输入高电平放开输入低电平 */ /* PA4 PA5 PA6 PA7 输入*/ = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; = GPIO_Mode_IPU; GPIO_Init(GPIOD, &GPIO_InitStructure); for(i = 0; i < 4; i++) { GPIO_SetBits(key_output[i].GPIO_x, key_output[i].GPIO_pin); } /*--------------------------------------------------------------------------------------* 矩阵键盘驱动 * 文件: keyboard.c * 编写人:LiuHui * 描述:扫描4x4 矩阵键盘输入,并返回键值 * 适用范围:驱动采用ST3.5 库编写,适用于STM32F10x 系列单片机 * 所用引脚:PA0-PA7 * 编写时间:2014 年5 月20 日 --------------------------------------------------------------------------------------*/ #include "stm32f10x.h" #include "keyboard.h" #include "dealy.h" /*--------------------------------矩阵键盘初始化----------------------------------------* 功能:初始化stm32 单片机GPIO //PA0-PA7 * 参数传递: * 输入:无 * 返回值:无 --------------------------------------------------------------------------------------*/ void KeyBoard_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_SetBits(GPIOA, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3); GPIO_ResetBits(GPIOA, GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7); } /*------------------------------矩阵键盘扫描--------------------------------------------* 功能:扫描矩阵键盘,并返回键值 * 参数: * 输入:无 * 返回:有键按下返回该键值 * 无键按下时则返回0 --------------------------------------------------------------------------------------*/ u8 Read_KeyValue(void) { u8 KeyValue=0; if((GPIO_ReadInputData(GPIOA)&0xff)!=0x0f) { #include /***************************************************************************** *** * 描述: * * 矩阵键盘数码管显示键值 * * 排线连接方法:JP8(P1)与JP4(矩阵键盘接口)连接 P0与JP3(静态数码管)连接 * * 矩阵键盘定义: * * P1.1-P1.4为列线,P1.4-P1.7为行线 * * 喇叭接P1.5口矩阵键盘P1口, * * 注意:请将JP165短路冒断开 * ****************************************************************************** **/ #include /* --------------------------------------------- 名称: 矩阵键盘依次输入控制使用行列逐级扫描 论坛: 编写: shifang 日期: 2009.5 修改:无内容: 如计算器输入数据形式相同从右至左使用行列扫描方法 */ #include 分 别对应相应的数码管点亮,即位码 unsigned char TempData[8]; //存储显示值的全局变量 void DelayUs2x(unsigned char t);//us 级延时函数声明 void DelayMs(unsigned char t); //ms 级延时 void Display (un sig ned char FirstBit, un sig ned char Num);/数码管显示函数un sig ned char KeySca n(v oid);/键盘扫描unsigned char KeyPro(void); void Init_Timer0(void);// 定时器初始化 /* ----------------------------------------------- 主函数 ----------------------------------------------- */ void main (void){unsigned char num,i,j; unsigned char temp[8]; Init_Timer0(); while (1)// 主循环{num=KeyPro(); if(num!=0xff){if(i<8){temp[i]=dofly_DuanMa[num]; for(j=0;j<=i;j++) TempData[7-i+j]=temp[j];}i++; if(i==9)〃多出一个按键输入为了清屏原本应该为8{i=0; 单片机 4*4 矩阵键盘应用 (2011-03-10 20:18:38) 转载▼ 在单片机按键使用过程中,当键盘中按键数量较多时为了减少端口的占用通常将按键排列成矩阵形式如下图所示,在矩阵式键盘中每条水平线和垂直线在交叉处不直接连通而是通过一个按键加以连接,到底这样做是出意何种目的呢?大家看下面电路图,单片机的整一个8位端口可以构成 4*4=16 个矩阵式按键,相比独立式按键接法多出了一倍,而且线数越多区别就越明显,假如再多加一条线就可以构成 20个按键的键盘,但是独立式按键接法只能多出1个按键。由此可见,在需要的按键数量比较多时,采用矩阵法来连接键盘是非常合理的,矩阵式结构的键盘显然比独立式键盘复杂一些,单片机对其进行识别也要复杂一些。确定矩阵式键盘上任何一个键被按下通常采用行扫描法。行扫描法又称为逐行查询法它是一种最常用的多按键识别方法。因此,我们就以行扫描法为例介绍矩阵式键盘的工作原理。 图5-4(4*4矩阵式按键的接法) 首先,不断循环地给低四位独立的低电平,然后判断键盘中有无键按下。将低位中其中一列线(P1.0~P1.3中其中一列)置低电平然后检测行线的状态(高4位,即P1.4~P1.7,由于线与关系,只要与低电平列线接通,即跳变成低电平),只要有一行的电平为低就延时一段时间以消除抖动,然后再次判断,假如依然为低电平,则表示键盘中真的有键被按下而且闭合的键位于低电平的4个按键之中任其一,若所有行线均为高电平则表示键盘中无键按下。再其次,判断闭合键所在的具体位置。在确认有键按下后 ,即可进入确定具体闭合键的过程。其方法是: 依次将列线置为低电平,即在置某一根列线为低电平时,其它列线为高电平。同时再逐行检测各行线的电平状态;若某行为低,则该行线与置为低电平的列线交叉处的按键就是闭合的按键。下面图5-5是4*4矩阵式按键接法的软件算法操作流程。X4扫描式矩阵键盘课程设计
4×5矩阵键盘驱动程序
简单的单片机矩阵键盘程序的写法
矩阵键盘单片机识别实验与程序
STM矩阵键盘程序
矩阵键盘设计实验报告
stm控制乘矩阵键盘程序带松手检测
STM32矩阵键盘实现方法收集
STM32_矩阵键盘程序4×4
51单片机矩阵键盘按键C语言程序
矩阵键盘C语言程序
51单片机矩阵键盘扫描程序
矩阵键盘原理详解,配套程序和电路