STM32 矩阵键盘控制

合集下载

stm32键盘扫描电路原理

stm32键盘扫描电路原理

stm32键盘扫描电路原理
STM32键盘扫描电路原理是通过使用STM32微控制器的GPIO(通用输入/输出)功能和外部硬件电路,实现对键盘的扫描和检测。

1. 首先需要将键盘的按键连接到STM32微控制器的GPIO引脚上。

可以使用矩阵排列的方式来连接多个按键。

2. 然后将STM32微控制器的GPIO设置为输入模式,需要扫描的按键对应的GPIO引脚设置为输入。

3. 在代码中,设置一个循环,依次对每一个按键进行扫描。

可以使用GPIO外部中断来触发按键的扫描。

4. 在每次扫描过程中,将某一个按键对应的GPIO引脚设置为高电平,并读取引脚的状态。

5. 如果读取到的引脚状态为高电平,则表示该按键被按下。

6. 根据读取到的按键状态,可以执行相应的操作。

需要注意的是,如果使用矩阵排列的方式连接多个按键,还需要使用GPIO引脚的输出模式来控制矩阵的行和列。

总之,STM32键盘扫描电路原理是通过STM32微控制器的GPIO和外部硬件电路,实现对键盘的扫描和检测。

stm32F103状态机矩阵键盘

stm32F103状态机矩阵键盘

stm32F103状态机矩阵键盘矩阵键盘程序,作为麦知club小车项目的一部分,从IAR 状态机应用修改而来。

IAR7.4+STM32CUBEMX调试通过。

键盘行4,列3,每条线都有10K上拉电阻。

改到4×4矩阵也很容易。

行线设置为输入,针脚为浮空;列线设置为开漏输出。

不支持长按和组合键,主要是我不会改。

在OS中使用20ms任务周期调用。

以下贴出代码。

keypad.h[cpp] view plain copy /* * * Name: keypad.h */ #ifndef KEYPAD_H #define KEYPAD_H #include"stm32f1xx_hal.h" #include "pinname.h" #definePORT_KEY GPIOD #define COLS(GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6) // 读pin//#define In(GPIO_Pin) (PORT_KEY->IDR &GPIO_Pin) #define In(GPIO_Pin)HAL_GPIO_ReadPin(PORT_KEY, GPIO_Pin) // 写1到Pin //#define High(GPIO_Pin) PORT_KEY->BSRR = GPIO_Pin #define High(GPIO_Pin) HAL_GPIO_WritePin(PORT_KEY, GPIO_Pin, GPIO_PIN_SET) // 写0到Pin //#defineLow(GPIO_Pin) PORT_KEY->BSRR = (uint32_t)GPIO_Pin << 16 #define Low(GPIO_Pin)HAL_GPIO_WritePin(PORT_KEY, GPIO_Pin,GPIO_PIN_RESET) /* * 0 1 2 3 * 4 5 67 * 8 9 10 11 * 12 13 14 15 */ typedef enum { Key_Up = 0x02, Key_Left = 0x03,Key_Right = 0x04, Key_Down = 0x08, Key_On = 0x09, Key_Mode = 0x0a, Key_None = 0xFF } KeyPressed; static const int row_count = 4; static const int col_count = 3; uint16_t bus_out(void); void Keypad(void); char AnyKey(void); char SameKey(void); char ScanKey(void); void FindKey(void); voidClearKey(void); void Read(void); /** Start the keypad interrupt routines */ void Start(void); /** Stop the keypad interrupt routines */ void Stop(void); void Cols_out(uint16_t v); void Scan_Keyboard(void); KeyPressed getKey(void); #endif // KEYPAD_Hkeypad.c[cpp] view plain copy /* * * Name: keypad.cpp * */#include "keypad.h" // State: char KeyState; // Bit pattern after each scan: char KeyCode; // Output value fromthe virtual 74HC922: KeyPressed KeyValue; // KeyDown is set if key is down: char KeyDown; // KeyNew is set every time a new key is down: char KeyNew; // 映射表char KeyTable[12][2]; // Pin of Row uint16_t _rows[] = {KEYx0, KEYx1, KEYx2, KEYx3}; uint16_t _cols[] = {KEYy0, KEYy1, KEYy2}; //构造函数voidKeypad(void) { Stop(); KeyState = 0; // 按键状态初始0 } //扫描键盘voidScan_Keyboard(void){ switch (KeyState) { case 0:{ if (AnyKey()) { char scankey = ScanKey(); if (scankey != 0xff) KeyCode = scankey; KeyState = 1; } break; } case 1: { if (SameKey()) { FindKey(); KeyState = 2; } else KeyState = 0; break; } case 2: { if (SameKey()) { } elseKeyState = 3; break; } case 3:{ if (SameKey()) { KeyState = 2; } else { ClearKey(); KeyState = 0; } break; } } // func end } // 有键按下char AnyKey(void) { //Start(); //拉低int r = -1; for (r = 0; r < row_count; r++) { if (In(_rows[r]) == 0) // In macro break; } //Stop(); //恢复if (!(0 <= r && r < row_count)) return 0; else return 1; } // 键按下,键值相同char SameKey(void) { // char KeyCode_new = KeyCode; char KeyCode_new = ScanKey(); if (KeyCode == KeyCode_new) return 1; else return 0; }// 扫描键char ScanKey(void) { /* 行扫描*/ int r = -1; for (r = 0; r < row_count; r++) { if (In(_rows[r]) == 0) // In macro break; } /* 若没有找到有效行,返回*/ if (!(0 <= r&& r < row_count)) { return0xff; } /* 列扫描,找出行上哪个被拉低*/ int c = -1; for (c = 0; c < col_count;c++) { // 轮流输出列线Cols_out(~(1<< c)); if (In(_rows[r]) == 0) //In macro break; } /* 给所有的列重新充电*/ Start(); /* 若没有找到有效列,返回*/ if (!(0 <= c && c < col_count)) return 0xff; return r * col_count + c; } // FindKey compares KeyCode to values in KeyTable. // If match, KeyValue, KeyDown and KeyNew are updated. void FindKey(void) { KeyValue = (KeyPressed)KeyCode; KeyDown = 1; KeyNew = 1; } void ClearKey(void){ KeyDown = 0; } KeyPressed getKey(void){ if(KeyNew) { KeyNew = 0; return KeyValue; } else return Key_None; } void Start(void) { /* 列输出0,拉低行*/PORT_KEY->BRR = COLS; } void Stop(void){ /* 列输出1,使行不被拉低*/PORT_KEY->BSRR = COLS; } // cols bus output void Cols_out(uint16_t v) { if ((v & 0x01) > 0) //0b001 High(_cols[0]); else Low(_cols[0]); if ((v & 0x02) > 0) //0b010 High(_cols[1]);else Low(_cols[1]); if ((v & 0x04) > 0) //0b100 High(_cols[2]); elseLow(_cols[2]);} 按键操作可以改到寄存器操作,提高速度。

stm32矩阵键盘原理

stm32矩阵键盘原理

STM32矩阵键盘原理详解引言矩阵键盘是一种常见的输入设备,广泛应用于电子产品中。

在STM32微控制器中,利用GPIO引脚实现矩阵键盘控制相对简单,本文将详细介绍STM32矩阵键盘的基本原理。

基本原理矩阵键盘由多个按键组成,通常采用行列式排列。

每个按键都由一个触点和一个按键外壳组成,触点一般为弹簧式结构,按下按键时触点接通,释放按键时触点断开。

矩阵键盘的连接方式矩阵键盘的每个按键都被分配一个行号和列号,通过行线和列线来连接按键和控制芯片。

STM32通过GPIO来控制行线和列线的电平,实现按键的扫描和检测。

在STM32中,行线和列线可以连接到不同的GPIO引脚上。

行线连接到输出引脚,列线连接到输入引脚。

这样,通过对行线的输出和对列线的输入,可以实现对矩阵键盘的扫描和检测。

矩阵键盘的扫描原理矩阵键盘的扫描原理可以简单描述为以下几个步骤:1.将所有行线设置为高电平,所有列线设置为输入模式。

2.逐个将行线设置为低电平,并同时检测列线引脚的电平状态。

3.如果某一列的输入引脚检测到低电平,表示该列对应的按键被按下。

4.通过行线和列线的对应关系,确定被按下的按键的行号和列号。

矩阵键盘的按键映射通过扫描后,可以得到被按下的按键的行号和列号,STM32可以根据行列号的映射关系将按键信息转化为相应的按键值。

通常,矩阵键盘的按键映射是通过二维数组来实现的。

数组的行号对应行线,列号对应列线。

数组中的元素对应按键的键值。

例如,要实现一个4x4的矩阵键盘,可以通过以下数组表示按键的映射关系:uint8_t keyMap[4][4] = {{ '1', '2', '3', 'A' },{ '4', '5', '6', 'B' },{ '7', '8', '9', 'C' },{ '*', '0', '#', 'D' }};通过行列号可以确定数组中的元素,从而得到按键的键值。

基于STM32控制的矩阵键盘的仿真设计

基于STM32控制的矩阵键盘的仿真设计

成绩课程论文题目:基于STM32控制的矩阵键盘的仿真设计课程名称: ARM 嵌入式系统学生姓名:张宇学生学号: 1314030140 系别:电子工程学院专业:通信工程年级: 2013级指导教师:权循忠电子工程学院制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矩阵键盘。

STM32_实用矩阵键盘

STM32_实用矩阵键盘

实用矩阵键盘程序// 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]);}。

基于STM32的矩阵键盘识别算法研究与实现

基于STM32的矩阵键盘识别算法研究与实现

基于STM32的矩阵键盘识别算法研究与实现
陈丙山;侯志伟;张永平;景江鹏
【期刊名称】《电子制作》
【年(卷),期】2024(32)5
【摘要】矩阵键盘作为电子设备和仪器装置的人机交互重要媒介,针对数字密码锁、临时存取柜、电梯控制器等多按键应用场景的实际需求,本文采用STM32F103C8
作为主控器,详细介绍了以行列扫描法、行列线反法识别5×4(5行4列)矩阵键盘的优化算法,并提出了以16位并行端口I2C扩展器PCA9555a为纽带的矩阵键盘识
别方法。

实验结果表明,本文识别方法稳定可靠、简洁清晰、通用性好以及效率更高,能够有效满足相关应用场景中对多按键识别的实际应用需求。

【总页数】4页(P96-99)
【作者】陈丙山;侯志伟;张永平;景江鹏
【作者单位】兰州石化职业技术大学电子电气工程学院
【正文语种】中文
【中图分类】TP3
【相关文献】
1.基于STM32芯片的Wi-Fi语音识别风扇控制系统的设计与实现
2.基于STM32
的口罩识别及无接触测温系统的实现3.基于CNN的水表指针读数识别及STM32
实现方案设计4.基于STM32的手写数字识别平台的设计与实现5.基于STM32的农业物联网病虫害图像识别算法研究
因版权原因,仅展示原文概要,查看原文内容请购买。

STM32中反转法矩阵短按键的应用 测试通过

STM32中反转法矩阵短按键的应用 测试通过

#include"stm32f10x.h"//反转法测矩阵按键void Delay(__IO uint32_t t);void RCC_Config(void);void GPIO_Config(void);uint32_t Key_Scan(void);void GPIO_RConfig(void);void LED_Config(void);void Delay_ms(__IO uint32_t time);void Time_Delay(void);void GPIO_SetBits_Row(void);void GPIO_ResetBits_Row(void);void GPIO_SetBits_Col(void);void GPIO_ResetBits_Col(void);GPIO_InitTypeDef GPIO_InitStructure;static __IO uint32_t TimingDelay=0;uint32_t num=0;uint8_t j,i; //PA6 PA7 PB7 PA5uint8_t key[4][4]={0x01,0x05,0x09,0x0d, //PE150x02,0x06,0x0a,0x0e, //PE140x03,0x07,0x0b,0x0f, //PE130x04,0x08,0x0c,0x10 }; //PE11struct IO_Port{GPIO_TypeDef *GPIO_X;unsigned short GPIO_Pin;};static struct IO_Port key_row[4]={{GPIOE,GPIO_Pin_15},{GPIOE,GPIO_Pin_14}, {GPIOE,GPIO_Pin_13},{GPIOE,GPIO_Pin_11}};static struct IO_Port key_col[4]={{GPIOA,GPIO_Pin_6},{GPIOA,GPIO_Pin_7},{GPIOB,GPIO_Pin_7},{GPIOA,GPIO_Pin_5}};int main(void){uint32_t key=0;RCC_Config();LED_Config();SysTick_Config(72000);while(1){key=Key_Scan();switch(key){case 0x01:GPIO_WriteBit(GPIOB,GPIO_Pin_5,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pi n_5)));break;case 0x02:GPIO_WriteBit(GPIOB,GPIO_Pin_5,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pi n_5)));break;case 0x03:GPIO_WriteBit(GPIOB,GPIO_Pin_5,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pi n_5)));break;case 0x04:GPIO_WriteBit(GPIOB,GPIO_Pin_5,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pi n_5)));break;case 0x05:GPIO_WriteBit(GPIOB,GPIO_Pin_5,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pi n_5)));break;case 0x06:GPIO_WriteBit(GPIOB,GPIO_Pin_5,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pi n_5)));break;case 0x07:GPIO_WriteBit(GPIOB,GPIO_Pin_5,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pi n_5)));break;case 0x08:GPIO_WriteBit(GPIOB,GPIO_Pin_5,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pi n_5)));break;case 0x09:GPIO_WriteBit(GPIOB,GPIO_Pin_5,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pi n_5)));break;case 0x0a:GPIO_WriteBit(GPIOB,GPIO_Pin_5,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pi n_5)));break;case 0x0b:GPIO_WriteBit(GPIOB,GPIO_Pin_5,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pi n_5)));break;case 0x0c:GPIO_WriteBit(GPIOB,GPIO_Pin_5,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pi n_5)));break;case 0x0d:GPIO_WriteBit(GPIOB,GPIO_Pin_5,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pi n_5)));break;case 0x0e:GPIO_WriteBit(GPIOB,GPIO_Pin_5,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pi n_5)));break;case 0x0f:GPIO_WriteBit(GPIOB,GPIO_Pin_5,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pi n_5)));break;case 0x10:GPIO_WriteBit(GPIOB,GPIO_Pin_5,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pi n_5)));break;default:break;}}}void GPIO_SetBits_Row(void){uint8_t i;for(i=0;i<4;i++){GPIO_SetBits(key_row[i].GPIO_X,key_row[i].GPIO_Pin);}}void GPIO_ResetBits_Row(void){uint8_t i;for(i=0;i<4;i++){GPIO_ResetBits(key_row[i].GPIO_X,key_row[i].GPIO_Pin);}}void GPIO_SetBits_Col(void){uint8_t i;for(i=0;i<4;i++){GPIO_SetBits(key_col[i].GPIO_X,key_col[i].GPIO_Pin);}}void GPIO_ResetBits_Col(void){uint8_t i;for(i=0;i<4;i++){GPIO_ResetBits(key_col[i].GPIO_X,key_col[i].GPIO_Pin);}}//反转法按键先让行输出低电平列输出高电平然后读列的状态如果为低电平//反转按键即列输出低电平行输出高电平依次检测行的输出如果为低电平则相应按键按下uint32_t Key_Scan(void){num=0;GPIO_Config();GPIO_ResetBits_Row();GPIO_SetBits_Col();for(i=0;i<4;i++){if(GPIO_ReadInputDataBit(key_col[i].GPIO_X,key_col[i].GPIO_Pin)==0){Delay(90000);if(GPIO_ReadInputDataBit(key_col[i].GPIO_X,key_col[i].GPIO_Pin)==0);GPIO_RConfig();GPIO_ResetBits_Col();GPIO_SetBits_Row();for(j=0;j<4;j++){if(GPIO_ReadInputDataBit(key_row[j].GPIO_X,key_row[j].GPIO_Pin)==0){while(GPIO_ReadInputDataBit(key_row[j].GPIO_X,key_row[j].GPIO_Pin)==0);num=key[j][i];}}}}return num;}void RCC_Config(void){SystemInit();RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB 2Periph_GPIOC|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOE|RCC_APB2Periph_AFIO,ENABLE);}void GPIO_RConfig(void){GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;GPIO_Init(GPIOB,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;GPIO_Init(GPIOE,&GPIO_InitStructure);}void GPIO_Config(void){GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOE,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;GPIO_Init(GPIOA,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;GPIO_Init(GPIOB,&GPIO_InitStructure);}void LED_Config(void){GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitStructure);GPIO_ResetBits(GPIOB,GPIO_Pin_5);}void Delay(__IO uint32_t t){uint32_t T=90000;while(T--);while(t--);}void Delay_ms(__IO uint32_t time){TimingDelay=time;while(TimingDelay!=0);}void Time_Delay(void){if(TimingDelay!=0){TimingDelay--;}}。

stm32矩阵按键扫描

stm32矩阵按键扫描

原理图各位大侠,这是我写的矩阵按键扫描程序,大家可以参考参考思维是和一般的按键扫描一样的,欢迎大家吐槽。

说明:微处理器:STM32F103VET6,开发软件:IAR for ARM。

(本来想复制文本文档的,发现代码层次感全变了,而且看着不舒服,所以采用截图的方式)其中需要注意的是:1、HKey是利用位带定义然后宏定义的,如下:PEin(n)利位带宏定义,(如果不明白可以百度一下stm32 位带操作)。

2、此函数是利用定时器设置30ms进行一次中断,而按键扫描的时间则由KeyScanEn确定3、关于KeyHData=HKey 编译器一直报警告,(但是程序跑起来为发现问题,不知道有没有什么潜在的风险)为了安全起见,大家可以直接去读寄存器也行4、按键消抖是利用计数器的方式,(说白了就是需要检测到两次后再处理)。

5、关于Delay(1)函数,试过不用也行,这里是置输入脚后马上检测输出感觉应该给点反应时间。

6、此函数只取出了键值,判断的话需要在另外的函数,最好不在中断函数里来做判断。

思路:1、首先置行线全为高,然后检测HEKEY这四位是不是全为0(当然,先要把这四个脚设置为下拉输入),如果不全是0,侧说明有按键按下。

2、然后依次将PE12-PE15置高进行扫描,(将一位置高后,然后检测输入引脚,如果输入引脚不是0x00,则说明按键在此行。

如若不是则循环置下一个引脚为高再判断),因为是循环扫描,此时循环次数就说明了在第几行。

所以键值=列键值(读取的键值)+ 循环的次数(行键值)。

3、取出按键的键值依次是:0x11 0x21 0x41 0x810x12 0x22 0x42 0x820x13 0x23 0x43 0x830x14 0x24 0x44 0x844、从上面的键值表可以看出:键值的后四位说明了按键的行数,键值的前四位则说明了按键所在的列数。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

// 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; //关闭JTAG
GPIOA->CRL&=0XFFFF0000;
GPIOA->CRL|=0X00003333; //PA0~PA3 推挽输出
GPIOA->CRL&=0X0000FFFF; //PA4~PA7 输入
GPIOA->CRL|=0X44440000; //PA4~PA7默认上拉
GPIOA->ODR&=~KEY_X ; //PA0~PA3置0
if(((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置0
if((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;
else
return (Key_Tab[i][j]);
}。

相关文档
最新文档