STM矩阵键盘程序
- 格式:docx
- 大小:70.43 KB
- 文档页数:8
/--------------------------------------------------------------------------------------矩阵键盘驱动文件: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控制的智能键盘摘要:本设计选择STM32为核心控制元件,设计了用4个IO 口实现4*4矩阵键盘,使用C 语言进行编程。
矩阵式键盘提高效率进行按键操作管理有效方法,它可以提高系统准确性,有利于资源的节约,降低对操作者本身素质的要求。
关键词:STM32 矩阵键盘 ARM 显示电路1 引言随着21世纪的到来,以前的单个端口连接的按键已经不能满足人们在大型或公共场合的需求。
电子信息行业将是人类社会的高科技行业之一,4*4矩阵键盘设计师当今社会中使用的最广的技术之一。
4*4矩阵式键盘采用STM32为核心,主要由矩阵式键盘电路、显示电路等组成,软件选用C 语言编程。
STM32将检测到的按键信号转换成数字量,显示于数码管上。
该系统灵活性强,易于操作,可靠性高,将会有更广阔的开发前景。
2 总体设计方案该智能键盘电路由ARM 最小系统,矩阵键盘电路和显示电路组成,在常规的4*4矩阵键盘的基础上,通过改进实现了用4个IO 口完成4*4矩阵键盘。
2.1 总体设计框图本电路主要由3大部分电路组成:矩阵键盘电路、ARM 最小系统电路、按键显示电路。
其中ATM 最小系统主要由复位电路和时钟电路组成。
电路复位后数码管显示字符“—” 表示没有按键,显示电路由STM32的PD0—PD7来控制数码管显示是哪个按键按下。
总体设计方框图,如图1所示。
图1总体设计方框图STM32矩阵键盘电路时钟电路复位电路按键显示电路3 智能键盘设计原理分析3.1 STM32复位和时钟电路设计此电路主要是复位电路和时钟电路两部分,其中复位电路采用按键手动复位和上电自动复位组合,电路如图2(右)所示:其中14脚为STM32的复位端。
时钟电路如图2(左)所示:晶振采用的是8MHz和32.786KHz,8MKz分别接STM32的12脚和13脚,32.786KHz分别接STM32的8脚和9脚。
图2STM复位和时钟电路设计3.2 矩阵键盘电路的设计该电路的四个端子分别接STM32的PB12—PB15,电路如图3所示。
矩阵键盘程序设计矩阵键盘程序设计概述矩阵键盘是一种常见的输入设备,常用于电子产品和计算机系统中。
它由多个按键组成,采用矩阵排列的方式连接到计算机系统中。
在本篇文章中,我们将讨论矩阵键盘的程序设计。
程序设计步骤步骤一:硬件连接,我们需要将矩阵键盘与计算机系统进行连接。
通常情况下,矩阵键盘的每一行和每一列都通过引脚与计算机系统中的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(\。
单片机c语言程序设计---矩阵式键盘实验报告课程名称:单片机c语言设计实验类型:设计型实验实验项目名称:矩阵式键盘实验一、实验目的和要求1.掌握矩阵式键盘结构2.掌握矩阵式键盘工作原理3.掌握矩阵式键盘的两种常用编程方法,即扫描法和反转法二、实验内容和原理实验1.矩阵式键盘实验功能:用数码管显示4*4矩阵式键盘的按键值,当K1按下后,数码管显示数字0,当K2按下后,显示为1,以此类推,当按下K16,显示F。
(1)硬件设计电路原理图如下仿真所需元器件(2)proteus仿真通过Keil编译后,利用protues软件进行仿真。
在protues ISIS 编译环境中绘制仿真电路图,将编译好的“xxx.hex”文件加入AT89C51。
启动仿真,观察仿真结果。
操作方完成矩阵式键盘实验。
具体包括绘制仿真电路图、编写c源程序(反转法和扫描法)、进行仿真并观察仿真结果,需要保存原理图截图,保存c源程序,总结观察的仿真结果。
完成思考题。
三、实验方法与实验步骤1.按照硬件设计在protues上按照所给硬件设计绘制电路图。
2.在keil上进行编译后生成“xxx.hex”文件。
3.编译好的“xxx.hex”文件加入AT89C51。
启动仿真,观察仿真结果。
四、实验结果与分析void Scan_line()//扫描行{Delay(10);//消抖switch ( P1 ){case 0x0e: i=1;break;case 0x0d: i=2;break;case 0x0b: i=3;break;case 0x07: i=4;break;default: i=0;//未按下break;}}void Scan_list()//扫描列{Delay(10);//消抖switch ( P1 ){case 0x70: j=1;break;case 0xb0: j=2;break;case 0xd0: j=3;break;case 0xe0: j=4;break;default: j=0;//未按下break;}}void Show_Key(){if( i != 0 && j != 0 ) P0=table[ ( i - 1 ) * 4 + j - 1 ];else P0=0xff;}五、讨论和心得。
/****************************************************************************** ** 实验名: 矩阵键盘实验* 使用的IO : 数码管使用P0,键盘使用P3.0、P3.1、P3.2、P3.3* 实验效果: 按矩阵键盘分别显示在数码管上面显示十六进制的0到F。
* 注意:******************************************************************************* /#include<reg51.h>#define GPIO_DIG P0#define GPIO_KEY P1unsigned char code DIG_CODE[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码unsigned char KeyValue;//用来存放读取到的键值void Delay10ms(); //延时10msvoid KeyDown(); //检测按键函数/****************************************************************************** ** 函数名: main* 函数功能: 主函数* 输入: 无* 输出: 无******************************************************************************* /void main(void){while(1){KeyDown();GPIO_DIG=~DIG_CODE[KeyValue];}}/****************************************************************************** ** 函数名: KeyDown* 函数功能: 检测有按键按下并读取键值* 输入: 无******************************************************************************* /void KeyDown(void){char a=0;GPIO_KEY=0x0f;if(GPIO_KEY!=0x0f)//读取按键是否按下{Delay10ms();//延时10ms进行消抖if(GPIO_KEY!=0x0f)//再次检测键盘是否按下{//测试列GPIO_KEY=0X0F;switch(GPIO_KEY){case(0X07): KeyValue=0;break;case(0X0b): KeyValue=1;break;case(0X0d): KeyValue=2;break;case(0X0e): KeyValue=3;break;}//测试行GPIO_KEY=0XF0;switch(GPIO_KEY){case(0X70): KeyValue=KeyValue;break;case(0Xb0): KeyValue=KeyValue+4;break;case(0Xd0): KeyValue=KeyValue+8;break;case(0Xe0): KeyValue=KeyValue+12;break;}while((a<50)&&(GPIO_KEY!=0xf0)) //检测按键松手检测{Delay10ms();a++;}}}}/****************************************************************************** ** 函数名: Delay10ms* 函数功能: 延时函数,延时10ms* 输入: 无******************************************************************************* /void Delay10ms(void) //误差0us{unsigned char a,b,c;for(c=1;c>0;c--)for(b=38;b>0;b--)for(a=130;a>0;a--);}。
实用矩阵键盘程序// PA0~PA3行控制线// PA4~PA7列控制线#include <stm32f10x_lib.h>#include "Delay.h"#include "key_4x4.h"#define KEY_X (0X0F << 0)#define KEY_Y (0XF0 << 0)unsigned char const Key_Tab[4][4]=//键盘编码表{{'D','C','B','A'},{'#','9','6','3'},{'0','8','5','2'},{'*','7','4','1'}};//没有得到键值返回0,否则返回相应的键值unsigned char Get_KeyValue(void){//使用线反转法u8 i=5,j=5;u16 temp1,temp2;RCC->APB2ENR|=1<<2; //使能PORTA时钟RCC->APB2ENR|=1<<0; //开启辅助时钟AFIO->MAPR&=0XF8FFFFFF; //清除MAPR的[26:24]AFIO->MAPR|=0X04000000; //关闭JTAGGPIOA->CRL&=0XFFFF0000;GPIOA->CRL|=0X00003333; //PA0~PA3 推挽输出GPIOA->CRL&=0X0000FFFF; //PA4~PA7 输入GPIOA->CRL|=0X44440000; //PA4~PA7默认上拉GPIOA->ODR&=~KEY_X ; //PA0~PA3置0if(((GPIOA->IDR >> 4) & 0X0F)<0x0f) // 读取PA12~PA15的值{delay_ms(70); //按键消抖if((GPIOA->IDR >>4 & 0x0f)<0x0f)temp1=(GPIOA->IDR >>4 & 0x0f);switch(temp1){case 0x0e:j=0;break;case 0x0d:j=1;break;case 0x0b:j=2;break;case 0x07:j=3;break;default:break;}}GPIOA->CRL&=0X0000FFFF;GPIOA->CRL|=0X33330000; //PA4~PA7 推挽输出GPIOA->CRL&=0XFFFF0000; //PA0~PA3 输入GPIOA->CRL|=0X00004444; //PA0~PA4 默认下拉GPIOA->ODR&=~KEY_Y; //PA4~PA7置0if((GPIOA->IDR & 0x0f)<0x0f){temp2=(GPIOA->IDR & 0x0f);switch(temp2){case 0x0e:i=0;break;case 0x0d:i=1;break;case 0x0b:i=2;break;case 0x07:i=3;break;default:break;}}if((i==5)||(j==5))return 0;elsereturn (Key_Tab[i][j]);}。
矩阵键盘程序流程图详细介绍推荐文章电脑键盘鼠标基础设置方法介绍热度:键盘功能使用方法详细介绍热度:键盘空格键的使用方法介绍热度:清洗键盘的方法介绍热度:电脑键盘基本知识及其功能详细介绍热度:[摘要]矩阵键盘是单片机外部设备中所使用的排布类似于矩阵的键盘组。
下面小编给大家介绍一下矩阵键盘程序流程图。
矩阵键盘是单片机外部设备中所使用的排布类似于矩阵的键盘组。
下面小编给大家介绍一下矩阵键盘程序流程图。
矩阵键盘的按键按N行M列排列,每个按键占据行列的一个交叉点,需要的I/0口数目是N+M,容许的最大按键数是N*M。
显然,矩阵键盘可以减少与单片机的1/0口和连线数,简化了结构,是一般单片机应用系统中常采用的键盘结构,正如上面PIC单片机RB端口电平变化中断方设计4*4矩阵键盘。
现介绍一种新型键盘的硬件和软件实原理,这里用同样的单片机同样的RB端口8条I/0绂可实现7*7=49个按键的键盘电路(下图),不同的是电路的设计采用到RBO口的外围接口中断(INT中断设为下降沿中断),而未采用前面提到的RB电平变化中断。
由下图可见,硬件部分分为两块:一块是普通键盘矩阵、电阻R8、R9和三极管Q组成,它们在电路中对NPN型三极管的基极构成“或”运算,对单片机进行初始化,除了RBO要求有中断功能外,其于的端口均设为高电平输出。
这样当有按键按下时三极管基极为正向导通状态,集电极由高变低,向单片机发出中断请求,从而启动键盘扫描程序。
在启动键扫描程序以前首先要对单片机进行初如化,包括中断、I/0口初始化。
下面的程序流程图是假定键盘电路也有按键按下时的键扫描程序流程图。
7*7矩阵键盘程序清单定义为PIC-KEY3.ASM,程序流程图如下图:以上是矩阵键盘程序流程图介绍。
单片机矩阵键盘的编程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 chars[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0 x86,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这种情况。
矩阵键盘程序设计矩阵键盘程序设计1.引言2.矩阵键盘的工作原理矩阵键盘由多行多列的按键组成,每个按键都与行线和列线相交。
当按下某一个按键时,行线和列线会形成一个闭合电路,通过这个闭合电路来传递按键的信号。
通过扫描行线和列线的状态,可以确定用户按下了哪个按键。
3.矩阵键盘的程序设计在程序设计中,需要初始化矩阵键盘的引脚配置,即将每个行线和列线连接到相应的引脚上。
然后,通过循环扫描行线和列线的状态,判断用户是否按下了某个按键。
一般情况下,矩阵键盘的扫描速度比较快,可以采用中断的方式来进行扫描,提高响应速度。
以下是一个简单的矩阵键盘程序设计示例:import RPi.GPIO as GPIO初始化引脚配置row_pins = [11, 13, 15, 16] 行引脚col_pins = [18, 22, 24, 26] 列引脚GPIO.setmode(GPIO.BOARD)设置行引脚为输出模式,列引脚为输入模式for pin in row_pins:GPIO.setup(pin, GPIO.OUT)for pin in col_pins:GPIO.setup(pin, GPIO.IN)循环扫描矩阵键盘while True:for row in row_pins:设置当前行引脚为低电平GPIO.output(row, GPIO.LOW)for col in col_pins:判断当前列引脚是否为高电平,即判断用户是否按下了某个按键if GPIO.input(col) == GPIO.HIGH:处理按键事件print(\。
键盘是单片机常用输入设备,在按键数量较多时,为了节省I/O口等单片机资源,一般采取扫描的方式来识别到底是哪一个键被按下。
即通过确定被按下的键处在哪一行哪一列来确定该键的位置,获取键值以启动相应的功能程序。
矩阵键盘的四列依次接到单片机的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中有一个为0for(row=0;row<4;row++) // 行检测{P1 = 0x0f; // 先将p1.4~P1.7置高P1 =~tmp1; // 使P1.4~p1.7中有一个为0tmp1*=2; // tmp1左移一位if ((P1 & 0x0f) < 0x0f)// 检测P1.0~P1.3中是否有一位为0,只要有,则说明此行有键按下,进入列检测{tmp2 = 0x01; // tmp2用于检测出哪一列为0for(col =0;col<4;col++) // 列检测{if((P1 & tmp2)==0x00)// 该列如果为低电平则可以判定为该列{key_val =key_Map[ row*4 +col ];// 获取键值,识别按键;key_Map为按键的定义表return; // 退出循环}tmp2*=2; // tmp2左移一位}}}} //结束。
程序效果:按下任意键,LED显示P0读回的数据其中4*4的矩阵键盘接P0口*/#incl ude<r eg52.h> //头文件u nsign ed ch ar ke y=0xf f; //定义一个变量用于存放按键值void read key(); //读按键子函数,获取键值vo id ma in() //主函数{whil e(1){ readk ey(); //读按键值if(key!=0xff) //判断是否有按键按下P2=~ke y;//这里取反:是因为LED为共阴,显示所按下的值}}v oid r eadke y() //读键盘子函数{P0=0x fe; //将第一列拉低,扫描是否有按键按下,第一列键值为:0,4,8,C ke y=P0; //读取键盘值if(ke y!=0x fe) //若key!=0xf e,说明有按键按下,则返回r eturn; //否则继续扫描下一列P0=0xfd;key=P0;i f(key!=0xf d)re turn;P0=0xfb;key=P0;if(key!=0xfb)ret urn;P0=0x f7;k ey=P0;if(key!=0xf7)retu rn;k ey=0x ff;}键盘扫描程序:从以上分析得到键盘扫描程序的流程图所示。
程序如下SCAN: MOVP1,#0FHMOVA,P1AN L A,#0FH CJN E A,#0FH,N EXT1SJ MP NE XT3 NEX T1: A CALLD20MSM OV A,#0EFHN EXT2: MOVR1,AMO V P1,AMOV A,P1 ANL A,#0FHCJNE A,#0FH,KC ODE;MO V A,R1SETBCRLC AJ C NEX T2NEXT3: MO V R0,#00HRE TKCODE: MOV B,#0FBH NEX T4: R RC AIN C B JCNEXT4M OV A,R1SWAP ANEXT5: RR C A INC BINCBINC BI NC BJC NEXT5NEXT6: MOV A,P1A NL A,#0FHCJ NE A,#0FH,NEXT6M OV R0,#0FF HRET <2>确定矩阵式键盘上何键被按下介绍一种“高低电平翻转法”。
矩阵键盘程序设计一、介绍矩阵键盘是一种常见的输入设备,通常由多个行和列组成。
每个键都和一个特定的行列交叉点相连,通过检测行和列的连接状态来判断按下的是哪个键。
本文档将介绍如何设计一个基于矩阵键盘的程序。
二、硬件要求为了实现矩阵键盘程序,我们需要以下硬件设备:1-矩阵键盘:包括行和列连接点,每个键与一个特定行列连接。
2-微控制器:用于检测行列的连接状态,并处理按键输入。
3-连接线:连接矩阵键盘和微控制器的电缆。
三、程序设计步骤设计一个矩阵键盘程序的基本步骤如下:1-初始化:设置微控制器的输入输出引脚,并配置矩阵键盘的行列连接点。
2-扫描键盘:循环扫描每个连接点,判断是否有按键按下。
3-按键处理:如果有按键按下,触发相应的事件或执行相应的操作。
4-循环:重复进行扫描和处理,实现实时响应。
四、初始化设置在程序的启动阶段,需要进行初始化设置以准备矩阵键盘的使用。
1-设置输入输出引脚:将微控制器上的引脚设置为输入或输出模式,以便连接矩阵键盘和其他设备。
2-配置连接点:设置行和列的连接点,将矩阵键盘的每个键与特定的行列连接。
五、扫描键盘扫描矩阵键盘是检测按键状态的关键步骤。
1-选定一行:将矩阵键盘的行连接点设置为高电平,其他行连接点设置为低电平。
2-读取列状态:读取每一列连接点的状态,判断是否有按键按下。
3-判断按键:根据读取到的列状态,确定按下的是哪个键。
可以使用一个矩阵或查找表来管理键和行列交叉点之间的对应关系。
六、按键处理一旦检测到按键按下,程序需要触发相应的事件或执行相应的操作。
1-事件处理:例如,如果按下的是数字键,则触发相应数字的事件。
2-操作执行:例如,如果按下的是功能键,则执行相应的功能。
七、附件本文档涉及的附件包括以下内容:1-矩阵键盘的电路图:详细描述了键盘的连接方式和连接点的布局。
2-微控制器的引脚分配表:列出了微控制器上各个引脚与矩阵键盘的连接方式。
八、法律名词及注释1-版权:对于矩阵键盘的设计,可能涉及版权保护的内容,需要遵守相关法律法规。
#include<reg52.h>#define uint unsigned int#define uchar unsigned charuchar code table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82 ,0xF8,0x80,0x90,0xff};//数码管段选sbit shu1=P3^0;//数码管位选sbit shu2=P3^1;//数码管位选uchar num;void delay(uint z)//延时函数{uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}uchar keyscan();//键盘扫描函数void main(){num=17;while(1){keyscan(); //键盘扫描if(num==17)//如果没有键按下{P2=table[10]; //数码管什么也不显示}else//有键按下{shu1=1;//打开数码管P2=table[(num-1)/10]; // 显示十位delay(7);//延时显示shu1=0;//关闭数码管shu2=1; //打开数码管P2=table[(num-1)%10]; // 显示个位delay(7);//延时显示shu2=0; //关闭数码管}}}uchar keyscan()//键盘扫描{P1=0xfe;while(P1!=0xfe) //第一行有键按下{delay(5);//延时消抖while(P1!=0xfe)//确实有键按下{switch(P1)//检测是哪个键按下{case 0xee:num=1;break;case 0xde:num=2;break;case 0xbe:num=3;break;case 0x7e:num=4;break;}while(P1!=0xfe);//松手检测}P1=0xfd;while(P1!=0xfd)//第二行有键按下{delay(5);//延时消抖while(P1!=0xfd)//确实有键按下{switch(P1)//检测是哪个键按下{case 0xed:num=5;break;case 0xdd:num=6;break;case 0xbd:num=7;break;case 0x7d:num=8;break;}while(P1!=0xfd) ;//松手检测}P1=0xfb;while(P1!=0xfb)//第三行有键按下{delay(5);//延时消抖while(P1!=0xfb)//确实有键按下{switch(P1)//检测是哪个键按下{case 0xeb:num=9;break;case 0xdb:num=10;break;case 0xbb:num=11;break;case 0x7b:num=12;break;}while(P1!=0xfb);//松手检测}}P1=0xf7;while(P1!=0xf7)//第四行有键按下{delay(5);//延时消抖while(P1!=0xf7)//确实有键按下{switch(P1)//检测是哪个键按下{case 0xe7:num=13;break;case 0xd7:num=14;break;case 0xb7:num=15;break;case 0x77:num=16;break;}while(P1!=0xf7);//松手检测}}return num;}。
矩阵键盘控制12864显示最经典程序#include //这个程序的功能:用4*4的矩阵键盘(接P3口)按键盘k1——k16中的任何一个键ki#include //12864液晶上显示数字i-1 (液晶数据口接P0)#define uint unsigned int//键盘扫描的思想是将行设置为低,列设置为高,来读取P3口的值,就能知道是哪个按键按下了#define uchar unsigned char#define LCDdata P0sbit E = P2^7;sbit RW = P2^6;sbit RS = P2^5;void init();void delayms(uint x);void displaykey();void write_com(uchar com);//写命令void write_data(uchar date);//写数据uchar temp;//--------------主函数-----------------void main(){init();// P3=0xfe;//P3=0xfd;//P3=0xfb;//P3=0xf7;while(1){displaykey();}}//-------------液晶初始化----------------void init(){write_com(0x01);write_com(0x02);write_com(0x06);write_com(0x0e);}//------------毫秒延时--------------- void delayms(uint x){uchar i;while(x--){for(i=0;i<120;i++);}}//------------写命令----------------- void write_com(uchar com){RS = 0;RW = 0;E = 0;LCDdata = com;E = 1;delayms(5);E = 0;}//-------------写数据------------------ void write_data(uchar date){RS = 1;RW = 0;E = 0;LCDdata = date;E = 1;delayms(5);E = 0;}//----void displaykey(){ //****************************判断第一行的键盘P3=0xfe; temp=P3; temp=temp&0xf0;while(temp!=0xf0)//判断是否有键盘按下为真有键盘按下{ delayms(50); temp=P3; temp=temp&0xf0;while(temp!=0xf0)//再次判断是否有键盘按下为真有键盘按下{ temp=P3;switch(temp){case0xee:write_com(0x80);write_data('0');write_com(0x81);write_data (' ');break;case0xde:write_com(0x80);write_data('1');write_com(0x81);write_data (' ');break;case0xbe:write_com(0x80);write_data('2');write_com(0x81);write_data (' ');break;case0x7e:write_com(0x80);write_data('3');write_com(0x81);write_data (' ');break;}break;//这个break很重要不能丢下,若丢下会这这个中退步出来}}//******************************判断第二行的键盘P3=0xfd; temp=P3; temp=temp&0xf0;while(temp!=0xf0){ delayms(50); temp=P3; temp=temp&0xf0;while(temp!=0xf0){ temp=P3;switch(temp){case0xed:write_com(0x80);write_data('4');write_com(0x81);write_data (' ');break;case0xdd:write_com(0x80);write_data('5');write_com(0x81);write_data (' ');break;case0xbd:write_com(0x80);write_data('6');write_com(0x81);write_data (' ');break;case0x7d:write_com(0x80);write_data('7');write_com(0x81);write_data (' ');break;} break;}}//******************************判断第三行的键盘P3=0xfb; temp=P3; temp=temp&0xf0;while(temp!=0xf0){ delayms(50); temp=P3; temp=temp&0xf0;while(temp!=0xf0){ temp=P3;switch(temp){case0xeb:write_com(0x80);write_data('8');write_com(0x81);write_data (' ');break;case0xdb:write_com(0x80);write_data('9');write_com(0x81);write_data (' ');break;case0xbb:write_com(0x80);write_data('1');write_com(0x81);write_ data('0');break;case0x7b:write_com(0x80);write_data('1');write_com(0x81);write_ data('1');break;}break;}}//******************************判断第四行的键盘P3=0xf7; temp=P3; temp=temp&0xf0;while(temp!=0xf0){ delayms(50); temp=P3; temp=temp&0xf0;while(temp!=0xf0){ temp=P3;switch(temp){case0xe7:write_com(0x80);write_data('1');write_com(0x81);write_ data('2');break;case0xd7:write_com(0x80);write_data('1');write_com(0x81);write_ data('3');break;case0xb7:write_com(0x80);write_data('1');write_com(0x81);write_ data('4');break;case0x77:write_com(0x80);write_data('1');write_com(0x81);write_ data('5');break;}break;}}}。
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 */ 写得不是很好,拿出来分享一下,希望大家能够提点建议!。
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--------------------------------------------------------------------------------------*/u8 Read_KeyValue(void){u8 KeyValue=0;if((GPIO_ReadInputData(GPIOA)&0xff)!=0x0f){Delay_ms(10);if((GPIO_ReadInputData(GPIOA)&0xff)!=0x0f){GPIO_SetBits(GPIOA, GPIO_Pin_0);GPIO_ResetBits(GPIOA, GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3);switch(GPIO_ReadInputData(GPIOA)&0xff){case 0x11: KeyValue = 1; break;case 0x21: KeyValue = 5; break;case 0x41: KeyValue = 9; break;case 0x81: KeyValue = 13;break;}GPIO_SetBits(GPIOA, GPIO_Pin_1);GPIO_ResetBits(GPIOA, GPIO_Pin_0 | GPIO_Pin_2 | GPIO_Pin_3);switch(GPIO_ReadInputData(GPIOA)&0xff){case 0x12: KeyValue = 2; break;case 0x22: KeyValue = 6; break;case 0x42: KeyValue = 10;break;case 0x82: KeyValue = 14;break;}GPIO_SetBits(GPIOA, GPIO_Pin_2);GPIO_ResetBits(GPIOA, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_3);switch(GPIO_ReadInputData(GPIOA)&0xff){case 0x14: KeyValue = 3; break;case 0x24: KeyValue = 7; break;case 0x44: KeyValue = 11;break;case 0x84: KeyValue = 15;break;}GPIO_SetBits(GPIOA, GPIO_Pin_3);GPIO_ResetBits(GPIOA, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2);switch(GPIO_ReadInputData(GPIOA)&0xff){case 0x18: KeyValue = 4; break;case 0x28: KeyValue = 8; break;case 0x48: KeyValue = 12;break;case 0x88: KeyValue = 16;break;}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);while((GPIO_ReadInputData(GPIOA)&0xff)!=0x0f);return KeyValue;}}return 0;}/*--------------------------------THE END--------------------------------------------*//*--------------------------------------------------------------------------------------* 矩阵键盘驱动* 文件:* 编写人: LiuHui* 描述:扫描4x4 矩阵键盘输入,并返回键值* 适用范围:驱动为库编写,适用于STM32F10x 系列单片机* 所用引脚: PA0-PA7* 编写时间: 2013 年11 月22 日* 版本:--------------------------------------------------------------------------------------*/#ifndef __KEYBOARD_H#define __KEYBOARD_Hvoid KeyBoard_Init(void);u8 Read_KeyValue(void);#endif/*----------------------------------THE END------------------------------------------*#include ""void KeyBoard_Init(void){GPIO_InitTypeDef GPIO_InitStructure;= GPIO_Pin_All;= GPIO_Speed_2MHz;= GPIO_Mode_Out_PP;GPIO_Init(GPIOA, &GPIO_InitStructure);= GPIO_Pin_All;= GPIO_Speed_2MHz;= GPIO_Mode_IPD;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_SetBits(GPIOB, GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6);GPIO_ResetBits(GPIOB, GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10);}//3?ê??ˉPA,PBvoid Delay_ms(int time){int i=0;while(time--){i=12000;while(i--);}}u8 Read_KeyValue(void){u8 KeyValue=1;if((GPIO_ReadInputData(GPIOB)&0xff)!=0x0f){Delay_ms(10);if((GPIO_ReadInputData(GPIOB)&0xff)!=0x0f){GPIO_SetBits(GPIOB, GPIO_Pin_3);GPIO_ResetBits(GPIOB, GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6); switch(GPIO_ReadInputData(GPIOB)&0xff){case 0x11: KeyValue = 7; break;case 0x21: KeyValue = 4; break;case 0x41: KeyValue = 1; break;case 0x81: KeyValue = 0; break;GPIO_SetBits(GPIOB, GPIO_Pin_4);GPIO_ResetBits(GPIOB, GPIO_Pin_3 | GPIO_Pin_5 | GPIO_Pin_6); switch(GPIO_ReadInputData(GPIOB)&0xff){case 0x12: KeyValue = 8; break;case 0x22: KeyValue = 5; break;case 0x42: KeyValue = 2; break;case 0x82: KeyValue = 0; break;}GPIO_SetBits(GPIOB, GPIO_Pin_5);GPIO_ResetBits(GPIOB, GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_6); switch(GPIO_ReadInputData(GPIOB)&0xff){case 0x14: KeyValue = 9; break;case 0x24: KeyValue = 6; break;case 0x44: KeyValue = 3; break;case 0x84: KeyValue = 0; break;}GPIO_SetBits(GPIOB, GPIO_Pin_6);GPIO_ResetBits(GPIOB, GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5); switch(GPIO_ReadInputData(GPIOB)&0xff){case 0x18: KeyValue = 0; break;case 0x28: KeyValue = 0; break;case 0x48: KeyValue = 0;break;case 0x88: KeyValue = 0;break;}GPIO_SetBits(GPIOB, GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6);GPIO_ResetBits(GPIOB, GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10);//while((GPIO_ReadInputData(GPIOB)&0xff)!=0x0f);return KeyValue;}}return 0;uint16_t table[]={0xEB,0x28,0xB3,0xBA,0x78,0xDA,0xDB,0xA8,0xFB,0xFA};int main(){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);KeyBoard_Init();int keyvalue=Read_KeyValue();GPIO_Write(GPIOA, table[keyvalue]);/*while(1){int i;for(i=0;i<10;i++){GPIO_Write(GPIOA, table[i]);Delay_ms(500);}}*//*u8 keyvalue;for(int i=0;;i++){KeyBoard_Init();keyvalue=Read_KeyValue();GPIO_Write(GPIOA,table[keyvalue]);Delay_ms(500);}*/}#include ""void KeyBoard_Init(void){GPIO_InitTypeDef GPIO_InitStructure;= GPIO_Pin_All;= GPIO_Speed_2MHz;= GPIO_Mode_Out_PP;GPIO_Init(GPIOA, &GPIO_InitStructure);= 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_Speed_2MHz;= GPIO_Mode_IPD;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_SetBits(GPIOB, GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 |GPIO_Pin_6);GPIO_ResetBits(GPIOB, GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 |GPIO_Pin_10);}void Delay_ms(int time){int i=0;while(time--){i=12000;while(i--);}}u8 Read_KeyValue(void){if((GPIO_ReadInputData(GPIOB)&0xff)!=0x73)//在这个程序下为什么无论是GPIO_ReadInputData(GPIOB)&0xff)!=0x73还是GPIO_ReadInputData(GPIOB)&0xff)==0x73都能往下运行,而在屏蔽Delay_ms(10)后则只能运行一种,是因为这个Delay_ms(10)对if里的判断有影响吗{Delay_ms(10);GPIO_Write(GPIOA,0x33);}return 0;}int main(){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);KeyBoard_Init();Read_KeyValue();}。