stm控制乘矩阵键盘程序带松手检测精编WORD版
- 格式:docx
- 大小:279.88 KB
- 文档页数:6
/--------------------------------------------------------------------------------------矩阵键盘驱动文件: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参数传递:输入:无返回值:无--------------------------------------------------------------------------------------/voidKeyBoard_Initvoid{GPIO_InitTypeDefGPIO_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_InitGPIOA,&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_InitGPIOA,&GPIO_InitStructure;GPIO_SetBitsGPIOA,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;GPIO_ResetBitsGPIOA,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;}/------------------------------矩阵键盘扫描--------------------------------------------功能:扫描矩阵键盘,并返回键值参数:输入:无返回:有键按下返回该键值无键按下时则返回0--------------------------------------------------------------------------------------/u8Read_KeyValuevoid{u8KeyValue=0;ifGPIO_ReadInputDataGPIOA&0xff=0x0f{Delay_ms10;ifGPIO_ReadInputDataGPIOA&0xff=0x0f{GPIO_SetBitsGPIOA,GPIO_Pin_0;GPIO_ResetBitsGPIOA,GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3; switchGPIO_ReadInputDataGPIOA&0xff{case0x11:KeyValue=1;break;case0x21:KeyValue=5;break;case0x41:KeyValue=9;break;case0x81:KeyValue=13;break;}GPIO_SetBitsGPIOA,GPIO_Pin_1;GPIO_ResetBitsGPIOA,GPIO_Pin_0|GPIO_Pin_2|GPIO_Pin_3; switchGPIO_ReadInputDataGPIOA&0xff{case0x12:KeyValue=2;break;case0x22:KeyValue=6;break;case0x42:KeyValue=10;break;case0x82:KeyValue=14;break;}GPIO_SetBitsGPIOA,GPIO_Pin_2;GPIO_ResetBitsGPIOA,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_3;switchGPIO_ReadInputDataGPIOA&0xff{case0x14:KeyValue=3;break;case0x24:KeyValue=7;break;case0x44:KeyValue=11;break;case0x84:KeyValue=15;break;}GPIO_SetBitsGPIOA,GPIO_Pin_3;GPIO_ResetBitsGPIOA,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2; switchGPIO_ReadInputDataGPIOA&0xff{case0x18:KeyValue=4;break;case0x28:KeyValue=8;break;case0x48:KeyValue=12;break;case0x88:KeyValue=16;break;}GPIO_SetBitsGPIOA,GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3; GPIO_ResetBitsGPIOA,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;whileGPIO_ReadInputDataGPIOA&0xff=0x0f;returnKeyValue;}}return0;}/--------------------------------THEEND--------------------------------------------//--------------------------------------------------------------------------------------矩阵键盘驱动文件:keyboard.h编写人:LiuHui描述:扫描4x4矩阵键盘输入,并返回键值适用范围:驱动为ST3.5库编写,适用于STM32F10x系列单片机所用引脚:PA0-PA7编写时间:2013 年11 月22日版本:1.0--------------------------------------------------------------------------------------/ifndef__KEYBOARD_Hdefine__KEYBOARD_HvoidKeyBoard_Initvoid;u8Read_KeyValuevoid;endif/----------------------------------THEEND------------------------------------------include"stm32f10x.h"voidKeyBoard_Initvoid{GPIO_InitTypeDefGPIO_InitStructure;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_All;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitGPIOA,&GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_All;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;GPIO_InitGPIOB,&GPIO_InitStructure;GPIO_SetBitsGPIOB,GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6; GPIO_ResetBitsGPIOB,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10; }//3êˉPA,PBvoidDelay_msinttime{inti=0;whiletime--{i=12000;whilei--;}}u8Read_KeyValuevoid{u8KeyValue=1;ifGPIO_ReadInputDataGPIOB&0xff=0x0f{Delay_ms10;ifGPIO_ReadInputDataGPIOB&0xff=0x0f{GPIO_SetBitsGPIOB,GPIO_Pin_3;GPIO_ResetBitsGPIOB,GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6; switchGPIO_ReadInputDataGPIOB&0xff{case0x11:KeyValue=7;break;case0x21:KeyValue=4;break;case0x41:KeyValue=1;break;case0x81:KeyValue=0;break;}GPIO_SetBitsGPIOB,GPIO_Pin_4;GPIO_ResetBitsGPIOB,GPIO_Pin_3|GPIO_Pin_5|GPIO_Pin_6; switchGPIO_ReadInputDataGPIOB&0xff{case0x12:KeyValue=8;break;case0x22:KeyValue=5;break;case0x42:KeyValue=2;break;case0x82:KeyValue=0;break;}GPIO_SetBitsGPIOB,GPIO_Pin_5;GPIO_ResetBitsGPIOB,GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_6;switchGPIO_ReadInputDataGPIOB&0xff{case0x14:KeyValue=9;break;case0x24:KeyValue=6;break;case0x44:KeyValue=3;break;case0x84:KeyValue=0;break;}GPIO_SetBitsGPIOB,GPIO_Pin_6;GPIO_ResetBitsGPIOB,GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;switchGPIO_ReadInputDataGPIOB&0xff{case0x18:KeyValue=0;break;case0x28:KeyValue=0;break;case0x48:KeyValue=0;break;case0x88:KeyValue=0;break;}GPIO_SetBitsGPIOB,GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6; GPIO_ResetBitsGPIOB,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10; //whileGPIO_ReadInputDataGPIOB&0xff=0x0f;returnKeyValue;}}return0;}uint16_ttable={0xEB,0x28,0xB3,0xBA,0x78,0xDA,0xDB,0xA8,0xFB,0xFA}; intmain{RCC_APB2PeriphClockCmdRCC_APB2Periph_GPIOA,ENABLE;RCC_APB2PeriphClockCmdRCC_APB2Periph_GPIOB,ENABLE;KeyBoard_Init;intkeyvalue=Read_KeyValue;GPIO_WriteGPIOA,tablekeyvalue;/while1{inti;fori=0;i<10;i++{GPIO_WriteGPIOA,tablei;Delay_ms500;}}//u8keyvalue;forinti=0;;i++{KeyBoard_Init;keyvalue=Read_KeyValue;GPIO_WriteGPIOA,tablekeyvalue;Delay_ms500;}/}include"stm32f10x.h"voidKeyBoard_Initvoid{GPIO_InitTypeDefGPIO_InitStructure;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_All;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitGPIOA,&GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6| GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;GPIO_InitGPIOB,&GPIO_InitStructure;GPIO_SetBitsGPIOB,GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6;GPIO_ResetBitsGPIOB,GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;}voidDelay_msinttime{inti=0;whiletime--{i=12000;whilei--;}}u8Read_KeyValuevoid{ifGPIO_ReadInputDataGPIOB&0xff=0x73//在这个程序下为什么无论是GPIO_ReadInputDataGPIOB&0xff=0x73还是GPIO_ReadInputDataGPIOB&0xff==0x73都能往下运行,而在屏蔽Delay_ms10后则只能运行一种,是因为这个Delay_ms10对if里的判断有影响吗{Delay_ms10;GPIO_WriteGPIOA,0x33;}return0;}intmain{RCC_APB2PeriphClockCmdRCC_APB2Periph_GPIOA,ENABLE;RCC_APB2PeriphClockCmdRCC_APB2Periph_GPIOB,ENABLE;KeyBoard_Init;Read_KeyValue;}。
stm32控制4乘4矩阵键盘程序带松手检测#include "stm32f10x.h"#include "delay.h"/*本文件的函数,主要实现矩阵键盘的功能。
矩阵键盘使用PA0到PA7引脚,其中,PA0到PA3固定为推挽输出,PA4到PA7固定为下拉输入。
即,无键按下时,对应PA4到PA7为0,有键按下时,PA4到PA7中,对应的引脚为高。
此程序有一点要注意:要用到的IO口,必须是PX0-PX7,,不能是其他连续的数字。
如果非要改。
如:已经没有连续的0-7的IO口,需要在几个地方修改,请注意~~此程序带有松手检测。
*/void InitKey(void) //初始化矩阵键盘要使用的GPIO口。
{GPIO_InitTypeDef GPIOStru;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(通用输入输出)引脚相连接。
步骤二:引脚控制接下来,我们需要使用程序控制GPIO引脚的输入输出状态。
对于矩阵键盘而言,我们通常会将一行的引脚设置为输出,将一列的引脚设置为输入,然后将输出引脚设置为高电平,输入引脚设置为上拉或下拉电阻。
步骤三:按键扫描在第二步的基础上,我们可以进行按键的扫描操作。
具体方法是,先将某一行的引脚设置为低电平,然后读取每一列的引脚状态。
如果某一列引脚为低电平,则表示该按键被按下。
步骤四:按键处理一旦我们检测到某个按键被按下,就可以执行相应的按键处理操作。
这可能包括记录按键信息、执行某些特定的功能或触发一些事件。
步骤五:循环扫描,我们需要将以上步骤放入一个循环中进行不断的扫描。
这样可以实现对整个矩阵键盘的实时检测和响应。
示例代码下面是一个简单的矩阵键盘程序设计的示例代码,使用C语言编写:cinclude <stdio.h>include <wiringPi.h>define ROWS 4define COLS 4int rows[ROWS] = { 2, 3, 4, 5 };int cols[COLS] = { 6, 7, 8, 9 };char keyMap[ROWS][COLS] = {{'1', '2', '3', 'A'},{'4', '5', '6', 'B'},{'7', '8', '9', 'C'},{'', '0', '', 'D'}};void init() {wiringPiSetup();for (int i = 0; i < ROWS; i++) {pinMode(rows[i], OUTPUT);digitalWrite(rows[i], HIGH);}for (int i = 0; i < COLS; i++) {pinMode(cols[i], INPUT);pullUpDnControl(cols[i], PUD_UP);}}char getKey() {while (1) {for (int i = 0; i < ROWS; i++) {digitalWrite(rows[i], LOW);for (int j = 0; j < COLS; j++) {if (digitalRead(cols[j]) == LOW) { return keyMap[i][j];}}digitalWrite(rows[i], HIGH);}}}int mn() {init();while (1) {char key = getKey(); printf(\。
4×4矩阵键盘原理及其在单片机中的简单应用基于Proteus仿真1、4×4矩阵键盘的工作原理如下图所示,4×4矩阵键盘由4条行线和4条列线组成,行线接P3。
0-P3。
3,列线接P3.4-P3。
7,按键位于每条行线和列线的交叉点上.按键的识别可采用行扫描法和线反转法,这里采用简单的线反转法,只需三步。
第一步,执行程序使X0~X3均为低电平,此时读取各列线Y0~Y3的状态即可知道是否有键按下。
当无键按下时,各行线与各列线相互断开,各列线仍保持为高电平;当有键按下时,则相应的行线与列线通过该按键相连,该列线就变为低电平,此时读取Y0Y1Y2Y3的状态,得到列码.第二步,执行程序使Y0~Y3均为低电平,当有键按下时,X0~X3中有一条行线为低电平,其余行线为高电平,读取X0X1X2X3的状态,得到行码。
第三步,将第一步得到的列码和第二步得到的行码拼合成被按键的位置码,即Y0Y1Y2Y3X0X1X2X3(因为行线和列线各有一条为低电平,其余为高电平,所以位置码低四位和高四位分别只有一位低电平,其余为高电平)。
也就是说,当某个键按下时,该键两端所对应的行线和列线为低电平,其余行线和列线为高电平。
比如,当0键按下时,行线X0和列线Y0为低电平,其余行列线为高电平,于是可以得到0键的位置码Y0Y1Y2Y3X0X1X2X3为0111 0111,即0X77。
当5键按下时,行线X1和列线Y1为低电平,其余行列线为高电平,于是可得到5键的位置码Y0Y1Y2Y3X0X1X2X3为1011 1011,即0XBB.全部矩阵键盘的位置码如下:2、4×4矩阵键盘在单片机的简单应用举例(一)如下图所示,运行程序时,按下任一按键,数码管会显示它在矩阵键盘上的序号0~F,并且蜂鸣器发出声音,模拟按键的声音。
此处采用线反转法识别按键。
C程序如下:#include〈reg51。
h〉#define uchar unsigned char#define uint unsigned intsbit buzzer=P1^0;uchar code dis[]= //0~9,A~F的共阳显示代码{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0X88,0X83,0XC6,0XA1,0X86,0X8E};uchar code tab[]= //矩阵键盘按键位置码{0x77,0xb7,0xd7,0xe7,0x7b,0xbb,0xdb,0xeb,0x7d,0xbd,0xdd,0xed,0x7e,0xbe,0xde,0xee};void delay(uint x)//延时函数{uchar i;while(x-—)for(i=0;i<120;i++);}uchar scan() //矩阵键盘扫描函数,得到按键号,采用线反转法{uchar a,b,c,i;P3=0XF0;//P3口输出11110000a=P3; //读取列码delay(10);//防抖延时10msP3=0X0F;//P3口输出00001111b=P3;//读取行码c=a+b;//得到位置码for(i=0;i<16;i++)if(c==tab[i])return i;//查表得到按键序号并返回return —1; //无按键,则返回—1}void beep() //蜂鸣器发出声音,模拟按键的声音{ uchar i;for(i=0;i<100;i++){buzzer=~buzzer;delay(1);}buzzer=0;}void main(){uchar key;buzzer=0; //关闭蜂鸣器while(1){key=scan(); //得到按键号if(key!=—1)//有按键则显示,并且蜂鸣器发出声音{P0=dis[key];beep();delay(100);}}}Proteus仿真运行结果如下:3、4×4矩阵键盘在单片机的简单应用举例(二)如下图所示,运行程序时,按下的按键键值越大,点亮的LED灯越多,例如,按下1号键时,点亮一只LED 灯,按下2号键时,点亮两只LED灯,按下16号键时,点亮全部LED灯。
单片机驱动4X4矩阵式键盘输入程序(1)单片机驱动4X4矩阵式键盘输入程序 (1)用AT89S51单片机的并行口P1接4×4矩阵键盘,以P1.0-P1.3作输入线,以P1.4-P1.7作输出线;在数码管上显示每个按键的“0-F”序号。
实现键盘输入的识别。
我将给大家提供c和汇编两个版本的4X4矩阵式键盘输入程序。
如汇编语言源程序:KEYBUF EQU 30HORG 00HSTART: MOV KEYBUF,#2WAIT:MOV P3,#0FFHCLR P3.4MOV A,P3ANL A,#0FHXRL A,#0FHJZ NOKEY1LCALL DELY10MSMOV A,P3ANL A,#0FHXRL A,#0FHJZ NOKEY1MOV A,P3ANL A,#0FHCJNE A,#0EH,NK1MOV KEYBUF,#0LJMP DK1NK1: CJNE A,#0DH,NK2MOV KEYBUF,#1LJMP DK1NK2: CJNE A,#0BH,NK3 MOV KEYBUF,#2LJMP DK1NK3: CJNE A,#07H,NK4 MOV KEYBUF,#3LJMP DK1NK4: NOPDK1:MOV A,KEYBUFMOV DPTR,#TABLE MOVC A,@A+DPTRMOV P0,ADK1A: MOV A,P3ANL A,#0FHXRL A,#0FHJNZ DK1ANOKEY1:MOV P3,#0FFHCLR P3.5MOV A,P3ANL A,#0FHXRL A,#0FHJZ NOKEY2LCALL DELY10MSMOV A,P3ANL A,#0FHXRL A,#0FHJZ NOKEY2MOV A,P3ANL A,#0FHCJNE A,#0EH,NK5MOV KEYBUF,#4LJMP DK2NK5: CJNE A,#0DH,NK6 MOV KEYBUF,#5LJMP DK2NK6: CJNE A,#0BH,NK7 MOV KEYBUF,#6LJMP DK2NK7: CJNE A,#07H,NK8 MOV KEYBUF,#7LJMP DK2NK8: NOPDK2:MOV A,KEYBUFMOV DPTR,#TABLE MOVC A,@A+DPTRMOV P0,ADK2A: MOV A,P3ANL A,#0FHXRL A,#0FHJNZ DK2ANOKEY2:MOV P3,#0FFHCLR P3.6MOV A,P3ANL A,#0FHXRL A,#0FHLCALL DELY10MSMOV A,P3ANL A,#0FHXRL A,#0FHJZ NOKEY3MOV A,P3ANL A,#0FHCJNE A,#0EH,NK9MOV KEYBUF,#8LJMP DK3NK9: CJNE A,#0DH,NK10 MOV KEYBUF,#9LJMP DK3NK10: CJNE A,#0BH,NK11 MOV KEYBUF,#10LJMP DK3NK11: CJNE A,#07H,NK12 MOV KEYBUF,#11LJMP DK3NK12: NOPDK3:MOV A,KEYBUFMOV DPTR,#TABLEMOVC A,@A+DPTRMOV P0,ADK3A: MOV A,P3ANL A,#0FHXRL A,#0FHJNZ DK3AMOV P3,#0FFHCLR P3.7MOV A,P3ANL A,#0FHXRL A,#0FHJZ NOKEY4LCALL DELY10MSMOV A,P3ANL A,#0FHXRL A,#0FHJZ NOKEY4MOV A,P3ANL A,#0FHCJNE A,#0EH,NK13MOV KEYBUF,#12LJMP DK4NK13: CJNE A,#0DH,NK14 MOV KEYBUF,#13LJMP DK4NK14: CJNE A,#0BH,NK15 MOV KEYBUF,#14LJMP DK4NK15: CJNE A,#07H,NK16 MOV KEYBUF,#15LJMP DK4NK16: NOPDK4:MOV A,KEYBUFMOV DPTR,#TABLEMOVC A,@A+DPTRMOV P0,ADK4A: MOV A,P3ANL A,#0FHXRL A,#0FHJNZ DK4ANOKEY4:LJMP WAITDELY10MS:MOV R6,#10D1: MOV R7,#248DJNZ R7,$DJNZ R6,D1RETTABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H DB 7FH,6FH,77H,7CH,39H,5EH,79H,71HEND。
实验五矩阵键盘实验一、实验内容1、编写程序,做到在键盘上每按一个数字键(0-F)用发光二极管将该代码显示出来。
按其它键退出。
2、加法设计计算器,实验板上有12个按键,编写程序,实现一位整数加法运算功能。
可定义“A”键为“+”键,“B”键为“=”键。
二、实验目的1、学习独立式按键的查询识别方法。
2、非编码矩阵键盘的行反转法识别方法。
三、实验说明1、MCS51系列单片机的P0~P3口作为输入端口使用时必须先向端口写入“1”。
2、用查询方式检测按键时,要加入延时(通常采用软件延时10~20mS)以消除抖动。
3、识别键的闭合,通常采用行扫描法和行反转法。
行扫描法是使键盘上某一行线为低电平,而其余行接高电平,然后读取列值,如读列值中某位为低电平,表明有键按下,否则扫描下一行,直到扫完所有行。
行反转法识别闭合键时,要将行线接一并行口,先让它工作在输出方式,将列线也接到一个并行口,先让它工作于输入方式,程序使CPU通过输出端口在各行线上全部送低电平,然后读入列线值,如此时有某键被按下,则必定会使某一列线值为0。
然后,程序对两个并行端口进行方式设置,使行线工作于输入方式,列线工作于输出方式,并将刚才读得的列线值从列线所接的并行端口输出,再读取行线上输入值,那么,在闭合键所在行线上的值必定为0。
这样,当一个键被接下时,必定可以读得一对唯一的行线值和列线值。
由于51单片机的并口能够动态地改变输入输出方式,因此,矩阵键盘采用行反转法识别最为简便。
行反转法识别按键的过程是:首先,将4个行线作为输出,将其全部置0,4个列线作为输入,将其全部置1,也就是向P1口写入0xF0;假如此时没有人按键,从P1口读出的值应仍为0xF0;假如此时1、4、7、0四个键中有一个键被按下,则P1.6被拉低,从P1口读出的值为0xB0;为了确定是这四个键中哪一个被按下,可将刚才从P1口读出的数的低四位置1后再写入P1口,即将0xBF写入P1口,使P1.6为低,其余均为高,若此时被按下的键是“4”,则P1.1被拉低,从P1口读出的值为0xBE;这样,当只有一个键被按下时,每一个键只有唯一的反转码,事先为12个键的反转码建一个表,通过查表就可知道是哪个键被按下了。
矩阵键盘程序设计一、介绍矩阵键盘是一种常见的输入设备,通常由多个行和列组成。
每个键都和一个特定的行列交叉点相连,通过检测行和列的连接状态来判断按下的是哪个键。
本文档将介绍如何设计一个基于矩阵键盘的程序。
二、硬件要求为了实现矩阵键盘程序,我们需要以下硬件设备:1-矩阵键盘:包括行和列连接点,每个键与一个特定行列连接。
2-微控制器:用于检测行列的连接状态,并处理按键输入。
3-连接线:连接矩阵键盘和微控制器的电缆。
三、程序设计步骤设计一个矩阵键盘程序的基本步骤如下:1-初始化:设置微控制器的输入输出引脚,并配置矩阵键盘的行列连接点。
2-扫描键盘:循环扫描每个连接点,判断是否有按键按下。
3-按键处理:如果有按键按下,触发相应的事件或执行相应的操作。
4-循环:重复进行扫描和处理,实现实时响应。
四、初始化设置在程序的启动阶段,需要进行初始化设置以准备矩阵键盘的使用。
1-设置输入输出引脚:将微控制器上的引脚设置为输入或输出模式,以便连接矩阵键盘和其他设备。
2-配置连接点:设置行和列的连接点,将矩阵键盘的每个键与特定的行列连接。
五、扫描键盘扫描矩阵键盘是检测按键状态的关键步骤。
1-选定一行:将矩阵键盘的行连接点设置为高电平,其他行连接点设置为低电平。
2-读取列状态:读取每一列连接点的状态,判断是否有按键按下。
3-判断按键:根据读取到的列状态,确定按下的是哪个键。
可以使用一个矩阵或查找表来管理键和行列交叉点之间的对应关系。
六、按键处理一旦检测到按键按下,程序需要触发相应的事件或执行相应的操作。
1-事件处理:例如,如果按下的是数字键,则触发相应数字的事件。
2-操作执行:例如,如果按下的是功能键,则执行相应的功能。
七、附件本文档涉及的附件包括以下内容:1-矩阵键盘的电路图:详细描述了键盘的连接方式和连接点的布局。
2-微控制器的引脚分配表:列出了微控制器上各个引脚与矩阵键盘的连接方式。
八、法律名词及注释1-版权:对于矩阵键盘的设计,可能涉及版权保护的内容,需要遵守相关法律法规。
实验三矩阵键盘识别实验
一、实验目的
掌握单片机I/O口的输入检测的方法、矩阵按键的识别方法、键盘消抖等。
学会实时程序的调试技巧。
二、实验原理
我们在手动按键的时候,由于机械抖动或是其它一些非人为的因素很有可能会造成误识别,一般手动按下一次键然后接着释放,按键两片金属膜接触的时间大约为50ms 左右,在按下瞬间到稳定的时间为5-10ms,在松开的瞬间到稳定的时间也为5-10ms,如果我们在首次检测到键被按下后延时10ms 左右再去检测,这时如果是干扰信号将不会被检测到,如果确实是有键被按下,则可确认,以上为按键识别去抖动的原理。
三、实验内容
实验板上电时,数码管不显示,顺序按下矩阵键盘后,在数码管上依次显示0到F,6个数码管同时静态显示即可。
下图中按键s6-s218条线分别联接p3口相连,p3.0~p3.3控制1~4行,p3.4~p3.7控制1~4列。
图1 实验板键盘电路原理图
四、实验步骤
1、按实验要求在Keil中创建项目,编辑、编译程序。
2、将编译生成的目标码文件(后缀为.Hex)传入实验板中。
3、在实验板上运行程序,观察实验运行结果并记录。
STM32 4*4矩阵键盘程序main.c#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:// LED0=0;printf("D\n");break;case 1:printf("C\n");break;case 2:printf("B\n");break;case 3:printf("A\n");break;case 4:printf("#\n");break;case 5:printf("9\n");break;case 6:printf("6\n");break;case 7:printf("3\n");break;case 8:printf("0\n");break;case 9:printf("8\n");break;case 10:printf("5\n");break;case 11:printf("2\n");break;case 12:printf("*\n");break;case 13:printf("7\n");break;case 14:printf("4\n");break;case 15:printf("1\n");break;}}}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////key.c //按键扫描#include "stm32f10x.h"#include "delay.h"#include "key.h"/*本文件的函数,主要实现矩阵键盘的功能。
//==========================Keyboard.h///* --------------------------------------------- 本程序实现 4*5 键盘的扫描 从左到右,从上到下,键值 依次为 1-20------------------------------- */ #ifndef __KEYBOARD_H #define __KEYBOARD_H #include "stm32f10x_lib.h" //选择扫描模式#define Interrupt_Scan // 中断扫描模式 ,要在 NVIC 在中打开对应中断/*可以自己定义其它扫描方式 */ #define DELAY_COUNT 0x0FFFF /* 键盘控制引脚定义 */ #define Keyboard_Control_Port GPIOD #define Keyboard_Line_1 #define Keyboard_Line_2 #define Keyboard_Line_3 #define Keyboard_Line_4 #define Keyboard_Line_5 #define Keyboard_Row_1 #define Keyboard_Row_2 #define Keyboard_Row_3 #define Keyboard_Row_4#define Keyboard_LineBase Keyboard_Line_1#define Keyboard_RowBaseKeyboard_Row_1 #define Keyboard_Line(Keyboard_Line_1 | Keyboard_Line_2 | Keyboard_Line_3 | Keyboard_Line_4 | Keyboard_Line_5) #define Keyboard_Row(Keyboard_Row_1 | Keyboard_Row_2 | Keyboard_Row_3 | Keyboard_Row_4)#ifdef Interrupt_Scan /* 中断扫描模式宏定义 */ #define Keyboard_EXTI_Row1 #define Keyboard_EXTI_Row2#define Keyboard_EXTI_Row3#define Keyboard_EXTI_Row4EXTI_Line5EXTI_Line6 EXTI_Line7 EXTI_Line8 #define Keyboard_EXTI_PortSource GPIO_PortSourceGPIOD#define Keyboard_EXTI_PinSource1 GPIO_PinSource5#define Keyboard_EXTI_PinSource2 GPIO_PinSource6GPIO_Pin_0GPIO_Pin_1 GPIO_Pin_2 GPIO_Pin_3 GPIO_Pin_4 GPIO_Pin_5 GPIO_Pin_6GPIO_Pin_7 GPIO_Pin_8#define Keyboard_EXTI_PinSource3 GPIO_PinSource7#define Keyboard_EXTI_PinSource4 GPIO_PinSource8 #define Keyboard_IRQ_ChannelEXTI9_5_IRQChannel#define Keyboard_EXTI_Line (Keyboard_EXTI_Row1 | Keyboard_EXTI_Row2 |Keyboard_EXTI_Row3 | Keyboard_EXTI_Row4)#endif /* 中断扫描模式宏定义*//* 键盘全局变量声明*/extern unsigned int Keyboard_Val ; //当前键值extern unsigned char Keyboard_Change_Flag ; // 键值改变标志,读取新的键值后由主程序清零/* 键盘接口函数声明*/#ifdef Interrupt_Scanextern void Init_Keyboard_Interrupt(void) ;// 键盘初始化为键盘扫描模式#endifextern void Delay(vu32 nCount) ; // 用于延时消抖#endif /* KEYBOARD_H *///=================================================================////============================Keyboard.c=============================// #include "stm32f10x_lib.h"#include "Keyboard.h"unsigned int Keyboard_Val = 0 ; //保存键值unsigned char Keyboard_Change_Flag = 0 ; // 键值改变标志,读取键值后清零/****************************************************************函数名称: Init_Keyboard_Interrupt功能: 键盘初始化为中断扫描模式初始化键盘需要的IO,Line1-Line5 设为输出低Row1-Row4 接上拉电阻,使能下降沿中断参数: 无返回值: 无*****************************************************************/void Init_Keyboard_Interrupt(void){GPIO_InitTypeDef GPIO_InitStructure ;EXTI_InitTypeDef EXTI_InitStructure ;EXTI_DeInit() ;//Line1-Line5 设为输出高GPIO_InitStructure.GPIO_Pin = Keyboard_Line ;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; // 推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;GPIO_Init(Keyboard_Control_Port ,&GPIO_InitStructure) ;GPIO_SetBits(Keyboard_Control_Port ,Keyboard_Line) ;//Row1-Row4 设置为下拉输入,用来接收上升沿中断GPIO_InitStructure.GPIO_Pin = Keyboard_Row;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD ; // 下拉输入GPIO_Init(Keyboard_Control_Port ,&GPIO_InitStructure) ;EXTI_ClearITPendingBit(Keyboard_EXTI_Row1) ; //清除中断标志位GPIO_EXTILineConfig(Keyboard_EXTI_PortSource ,Keyboard_EXTI_PinSource1 ); //Pinsource 不能取或EXTI_ClearITPendingBit(Keyboard_EXTI_Row2) ; //清除中断标志位GPIO_EXTILineConfig(Keyboard_EXTI_PortSource ,Keyboard_EXTI_PinSource2 );EXTI_ClearITPendingBit(Keyboard_EXTI_Row3) ; //清除中断标志位GPIO_EXTILineConfig(Keyboard_EXTI_PortSource ,Keyboard_EXTI_PinSource3 );EXTI_ClearITPendingBit(Keyboard_EXTI_Row4) ; //清除中断标志位GPIO_EXTILineConfig(Keyboard_EXTI_PortSource ,Keyboard_EXTI_PinSource4 );//设置Row1-Row4 为上升沿中断EXTI_InitStructure.EXTI_Line = Keyboard_EXTI_Line;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt ;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising ;EXTI_InitStructure.EXTI_LineCmd = ENABLE ;EXTI_Init(&EXTI_InitStructure) ;}/****************************************************************函数名称: Delay功能: 在扫描按键时,用于延时消抖参数: nCount -- 延时长度返回值: 无*****************************************************************/void Delay(vu32 nCount){for(; nCount!= 0;nCount--);}//==============================================================////=========================stm32f10x_it.c============================// void EXTI9_5_IRQHandler(void){unsigned long tmpFlag=0 ; //保存需要的中断标志位unsigned char i = 0 ; //循环标量tmpFlag = EXTI->PR & Keyboard_EXTI_Line ; // 只取设定过的标志位EXTI->PR = tmpFlag ;switch(tmpFlag) //判断是哪个标志位置位{case Keyboard_EXTI_Row1:GPIO_ResetBits(Keyboard_Control_Port ,Keyboard_Line) ;for(i=0 ;i<5 ;i++) //扫描方式判断按键{GPIO_SetBits(Keyboard_Control_Port ,(Keyboard_LineBase<<i)) ;if(GPIO_ReadInputDataBit(Keyboard_Control_Port ,Keyboard_Row_1)) {Delay(DELAY_COUNT) ; //延时消抖if(GPIO_ReadInputDataBit(Keyboard_Control_Port ,Keyboard_Row_1)) {Keyboard_Val = 1+i ;Keyboard_Change_Flag = 1 ;break ;}}}GPIO_SetBits(Keyboard_Control_Port ,Keyboard_Line) ;EXTI->PR = Keyboard_EXTI_Row1 ; // 清除中断标志break ;case Keyboard_EXTI_Row2:GPIO_ResetBits(Keyboard_Control_Port ,Keyboard_Line) ;for(i=0 ;i<5 ;i++)// 扫描方式判断按键{GPIO_SetBits(Keyboard_Control_Port ,(Keyboard_LineBase<<i)) ;if(GPIO_ReadInputDataBit(Keyboard_Control_Port ,Keyboard_Row_2)) {Delay(DELAY_COUNT) ; //延时消抖if(GPIO_ReadInputDataBit(Keyboard_Control_Port ,Keyboard_Row_2)) {Keyboard_Val = 6+i ;Keyboard_Change_Flag = 1 ;break ;}}}GPIO_SetBits(Keyboard_Control_Port ,Keyboard_Line) ;EXTI->PR = Keyboard_EXTI_Row2 ; //清除中断标志break ;case Keyboard_EXTI_Row3:GPIO_ResetBits(Keyboard_Control_Port ,Keyboard_Line) ;for(i=0 ;i<5 ;i++) // 扫描方式判断按键{GPIO_SetBits(Keyboard_Control_Port ,(Keyboard_LineBase<<i)) ;if(GPIO_ReadInputDataBit(Keyboard_Control_Port ,Keyboard_Row_3)) {Delay(DELAY_COUNT) ; //延时消抖if(GPIO_ReadInputDataBit(Keyboard_Control_Port ,Keyboard_Row_3)) {Keyboard_Val = 11+i ;Keyboard_Change_Flag = 1 ;break ;}}}GPIO_SetBits(Keyboard_Control_Port ,Keyboard_Line) ;EXTI->PR = Keyboard_EXTI_Row3 ; //清除中断标志break ;case Keyboard_EXTI_Row4:GPIO_ResetBits(Keyboard_Control_Port ,Keyboard_Line) ;for(i=0 ;i<5 ;i++) // 扫描方式判断按键{GPIO_SetBits(Keyboard_Control_Port ,(Keyboard_LineBase<<i)) ;if(GPIO_ReadInputDataBit(Keyboard_Control_Port ,Keyboard_Row_4)) {Delay(DELAY_COUNT) ; //延时消抖if(GPIO_ReadInputDataBit(Keyboard_Control_Port ,Keyboard_Row_4)) {Keyboard_Val = 16+i ;Keyboard_Change_Flag = 1 ;break ;}}}GPIO_SetBits(Keyboard_Control_Port ,Keyboard_Line) ;EXTI->PR = Keyboard_EXTI_Row4 ; //清除中断标志break ;default:break ;}}/////* 注:使用时要使能AFIO 时钟和EXTI9_5IRQ */ 写得不是很好,拿出来分享一下,希望大家能够提点建议!。
实验一矩阵键盘检测一、实验目的:1、学习非编码键盘的工作原理和键盘的扫描方式。
2、学习键盘的去抖方法和键盘应用程序的设计.二、实验设备:51/AVR实验板、USB连接线、电脑三、实验原理:键盘接口电路是单片机系统设计非常重要的一环,作为人机交互界面里最常用的输入设备。
我们可以通过键盘输入数据或命令来实现简单的人机通信。
1、按键的分类一般来说,按键按照结构原理可分为两类,一类是触点式开关按键,如机械式开关、导电橡胶式开关等;另一类是无触点式开关按键,如电气式按键,磁感应按键等。
前者造价低,后者寿命长。
目前,微机系统中最常见的是触点式开关按键(如本学习板上所采用按键).按键按照接口原理又可分为编码键盘与非编码键盘两类,这两类键盘的主要区别是识别键符及给出相应键码的方法。
编码键盘主要是用硬件来实现对键的识别,非编码键盘主要是由软件来实现键盘的识别。
全编码键盘由专门的芯片实现识键及输出相应的编码,一般还具有去抖动和多键、窜键等保护电路,这种键盘使用方便,硬件开销大,一般的小型嵌入式应用系统较少采用。
非编码键盘按连接方式可分为独立式和矩阵式两种,其它工作都主要由软件完成。
由于其经济实用,较多地应用于单片机系统中(本学习板也采用非编码键盘)。
2、按键的输入原理在单片机应用系统中,通常使用机械触点式按键开关,其主要功能是把机械上的通断转换成为电气上的逻辑关系。
也就是说,它能提供标准的TTL 逻辑电平,以便与通用数字系统的逻辑电平相容.此外,除了复位按键有专门的复位电路及专一的复位功能外,其它按键都是以开关状态来设置控制功能或输入数据。
当所设置的功能键或数字键按下时,计算机应用系统应完成该按键所设定的功能。
因此,键信息输入是与软件结构密切相关的过程。
对于一组键或一个键盘,通过接口电路与单片机相连. 单片机可以采用查询或中断方式了解有无按键输入并检查是哪一个按键按下,若有键按下则跳至相应的键盘处理程序处去执行,若无键按下则继续执行其他程序。
I/O端口输出1的端口与输出0的端口对接的时候会检验出原来的端口是0第一个,这个是错误程序#include<reg52.h>void delay1ms(unsigned int i) //延时函数unsigned char j;while(i--)for(j=0;j<115;j++) //1ms基准延时程序void main()while(1)P1=0xf0; //建立初始状态,每一行赋值0,每一列赋予1unsigned char s[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//数码管灯unsigned int l; //分别代表作列与行unsigned int r;if(P1!=0xf0) //检验有没有按键被按下delay1ms(15); //避免前沿抖动,延时大约15msswitch(P1) //检验有没有键盘被按下{ //如果按下了就检验是哪一列被按下了case 0x70: //p1^7被按下l=4;case 0xB0: //p1^6被按下l=3;case 0xD0: //p1^5被按下l=2;case 0xE0: //p1^4被按下l=1;default:break;P1=0xf; 、//每一列赋予1,每一行赋予0switch(P1) //检验哪一行的按键被按下case 0xE: //p1^0被按下r=1;case 0xD: //p1^2被按下r=2;case 0xB: //p1^3被按下r=3;case 0x7:r=4; //p1^4被按下default:break;//已经知道哪一个按键被按下r=r*l; //得到的数在数值上等于要显示的数目P1=s8[r] //数码管亮delay1ms(15); //避免后延抖动错误的地方在于P1=0xf; 、//每一列赋予1,每一行赋予0switch(P1) //检验哪一行的按键被按下这是因为如果没有再次判断当P1!=0XF的时候,就可能出现没有符合case之中的情况而直接运行default这种情况。
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;unsigned char key; unsigned char i,j;void main(void) {while(1){P3=0xff;P3_4=0;temp=P3;temp=temp & 0x0f; if (temp!=0x0f) {for(i=50;i>0;i--)for(j=200;j>0;j--); temp=P3;temp=temp & 0x0f; if (temp!=0x0f) {temp=P3;temp=temp & 0x0f; switch(temp){case 0x0e:key=7;break;case 0x0d:key=8;break;case 0x0b:key=9;break;case 0x07:key=10;break;}temp=P3;P1_0=~P1_0;P0=table[key]; temp=temp & 0x0f; while(temp!=0x0f) {temp=P3;temp=temp & 0x0f; }}}P3=0xff;P3_5=0;temp=P3;temp=temp & 0x0f; if (temp!=0x0f) {for(i=50;i>0;i--)for(j=200;j>0;j--); temp=P3;temp=temp & 0x0f; if (temp!=0x0f) {temp=P3;temp=temp & 0x0f; switch(temp){case 0x0e:key=4;break;case 0x0d:key=5;break;case 0x0b:key=6;break;case 0x07:key=11;break;}temp=P3;P1_0=~P1_0;P0=table[key]; temp=temp & 0x0f; while(temp!=0x0f) {temp=P3;temp=temp & 0x0f; }}}P3=0xff;P3_6=0;temp=P3;temp=temp & 0x0f; if (temp!=0x0f) {for(i=50;i>0;i--)for(j=200;j>0;j--); temp=P3;temp=temp & 0x0f; if (temp!=0x0f) {temp=P3;temp=temp & 0x0f; switch(temp){case 0x0e:key=1;break;case 0x0d:key=2;break;case 0x0b:key=3;break;case 0x07:key=12;break;}temp=P3;P1_0=~P1_0;P0=table[key]; temp=temp & 0x0f; while(temp!=0x0f) {temp=P3;temp=temp & 0x0f; }}}P3=0xff;P3_7=0;temp=P3;temp=temp & 0x0f; if (temp!=0x0f) {for(i=50;i>0;i--)for(j=200;j>0;j--); temp=P3;temp=temp & 0x0f; if (temp!=0x0f) {temp=P3;temp=temp & 0x0f; switch(temp){case 0x0e:key=0;break;case 0x0d:key=13;break;case 0x0b:key=14;break;case 0x07:key=15;break;}temp=P3;P1_0=~P1_0;P0=table[key]; temp=temp & 0x0f; while(temp!=0x0f) {temp=P3;temp=temp & 0x0f;} } } } }。
s t m控制乘矩阵键盘程序带松手检测精编
W O R D版
IBM system office room 【A0816H-A0912AAAHH-GX8Q8-GNTHHJ8】
/*本文件的函数,主要实现矩阵键盘的功能。
矩阵键盘使用PA0到PA7引脚,其中,PA0到PA3固定为推挽输出,PA4到PA7固定为
下拉输入。
即,无键按下时,对应PA4到PA7为0,有键按下时,PA4到PA7中,对应的引脚为高。
此程序有一点要注意:要用到的IO口,必须是PX0-PX7,,不能是其他连续的数字。
如果非要改。
如:已经没有连续的0-7的IO口,需要在几个地方修改,请注意!!
此程序带有松手检测。
*/
void InitKey(void) //初始化矩阵键盘要使用的GPIO口。
{
GPIO_InitTypeDef GPIOStru;
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);
}
int key(void) //实现矩阵键盘。
返回值为,各按键的键值,此键值由用户自己定义。
{
int KeyVal=0; //keyVal为最后返回的键值。
u16 WriteVal=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的值进行判断,以输出不同的键值。
{
case 0x0010: KeyVal=15; break;
case 0x0020: KeyVal=11; break;
case 0x0040: KeyVal=7; break;
case 0x0080: KeyVal=3; break;
}
GPIO_Write(GPIOA,(GPIOA->ODR & 0xfff0 | 0x2)); //让PA3到PA0输出二进制的0010.
switch(GPIOA->IDR & 0x00f0) //对PA4到PA7的值进行判断,以输出不同的键值。
{
case 0x0010: KeyVal=14; break;
case 0x0020: KeyVal=10; break;
case 0x0040: KeyVal=6; break;
case 0x0080: KeyVal=2; break;
}
GPIO_Write(GPIOA,(GPIOA->ODR & 0xfff0 | 0x4)); //让PA3到PA0输出二进制的0100.
switch(GPIOA->IDR & 0x00f0) //对PA4到PA7的值进行判断,以输出不同的键值。
{
case 0x0010: KeyVal=13; break;
case 0x0020: KeyVal=9; break;
case 0x0040: KeyVal=5; break;
case 0x0080: KeyVal=1; break;
}
GPIO_Write(GPIOA,(GPIOA->ODR & 0xfff0 | 0x8)); //让PA3到PA0输出二进制的1000.
switch(GPIOA->IDR & 0x00f0) //对PA4到PA7的值进行判断,以输出不同的键值。
{
case 0x0010: KeyVal=12; break;
case 0x0020: KeyVal=8; break;
case 0x0040: KeyVal=4; break;
case 0x0080: KeyVal=0; break;
}
return KeyVal;
}。