完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
矩阵键盘简介
再通过列操作模块: #define KEY_CLO0_OUT_LOW GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_RESET) #define KEY_CLO1_OUT_LOW GPIO_WriteBit(GPIOB,GPIO_Pin_13,Bit_RESET) #define KEY_CLO2_OUT_LOW GPIO_WriteBit(GPIOB,GPIO_Pin_14,Bit_RESET) #define KEY_CLO3_OUT_LOW GPIO_WriteBit(GPIOB,GPIO_Pin_15,Bit_RESET) #define KEY_CLO0_OUT_HIGH GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_SET) #define KEY_CLO1_OUT_HIGH GPIO_WriteBit(GPIOB,GPIO_Pin_13,Bit_SET) #define KEY_CLO2_OUT_HIGH GPIO_WriteBit(GPIOB,GPIO_Pin_14,Bit_SET) #define KEY_CLO3_OUT_HIGH GPIO_WriteBit(GPIOB,GPIO_Pin_15,Bit_SET) 来进行列扫描。 端口的配置 介绍完矩阵键盘的扫描原理了我们该通过keli来实现我们想要的功能啦,首先我们要进行的就是对我们所需要的端口进行配置,如下: //端口的配置 void key_init(){ GPIO_InitTypeDef GPIO_InitStruture; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //打开PB时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); //打开PE时钟 //定义PB12、PB13、PB14、PB15为推挽输出 GPIO_InitStruture.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruture.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15; GPIO_InitStruture.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitStruture); //定义PD8、PD9、PD10、PD11为上拉输入 分别定义为四行 GPIO_InitStruture.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStruture.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11; GPIO_Init(GPIOD,&GPIO_InitStruture); } 相关函数的编写 配置完我们所需要的端口,接下来我们就应该编写相关函数啦。 行扫描函数: //如果为1,代表没有按键被按下,如果为0,代表有按键被按下 char KEY_ROW_SCAN(void) { //读出行扫描状态 Key_row[0] = GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_8)<<3; Key_row[0] = Key_row[0] | (GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_9)<<2); Key_row[0] = Key_row[0] | (GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_10)<<1); Key_row[0] = Key_row[0] | (GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_11)); if(Key_row[0] != 0x0f) //不是1111,代表肯定有一个0行 { delay_ms(10); //消抖 if(Key_row[0] != 0x0f) //0111 1011 1101 1110 { //printf("Key_Row_DATA = 0x%xrn",Key_row[0]); switch(Key_row[0]) { case 0x07: //0111 判断为该列第1行的按键按下 return 1; case 0x0b: //1011 判断为该列第2行的按键按下 return 2; case 0x0d: //1101 判断为该列第3行的按键按下 return 3; case 0x0e: //1110 判断为该列第4行的按键按下 return 4; default : return 0; } } else return 0; } else return 0; } 按键扫描函数: char KEY_SCAN(void) { char Key_Num=0; //1-16对应的按键数 char key_row_num=0; //行扫描结果记录 KEY_CLO0_OUT_LOW; if( (key_row_num=KEY_ROW_SCAN()) != 0 ) { while(KEY_ROW_SCAN() != 0); //消抖 Key_Num = 0 + key_row_num; } KEY_CLO0_OUT_HIGH; KEY_CLO1_OUT_LOW; if( (key_row_num=KEY_ROW_SCAN()) != 0 ) { while(KEY_ROW_SCAN() != 0); Key_Num = 4 + key_row_num; } KEY_CLO1_OUT_HIGH; KEY_CLO2_OUT_LOW; if( (key_row_num=KEY_ROW_SCAN()) != 0 ) { while(KEY_ROW_SCAN() != 0); Key_Num = 8 + key_row_num; } KEY_CLO2_OUT_HIGH; KEY_CLO3_OUT_LOW; if( (key_row_num=KEY_ROW_SCAN()) != 0 ) { while(KEY_ROW_SCAN() != 0); Key_Num = 12 + key_row_num; } KEY_CLO3_OUT_HIGH; return Key_Num; } 主函数与其他 主函数: #include "stm32f10x.h" #include "delay.h" #include "led.h" #include "key16.h" #include "stdio.h" #include "usart.h" int main(void) { vu8 key=0; char key_confirm; led_init(); delay_init(); key_init(); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); uart_init(115200); while(1) { key_confirm = KEY_SCAN(); if(key_confirm>0&&key_confirm<17){ printf("Key_NUM = %d rn",key_confirm); //按下1-16个按键的操作 printf("= = = = = = = = = = = rn"); } } } key.c: #include "key16.h" #include "delay.h" uint8_t Key_row[1]={0xff}; //定义一个数组,存放行扫描状态 //端口的配置 void key_init(){ GPIO_InitTypeDef GPIO_InitStruture; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //打开PB时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); //打开PE时钟 //定义PB12、PB13、PB14、PB15为推挽输出 GPIO_InitStruture.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruture.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15; GPIO_InitStruture.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitStruture); //定义PD8、PD9、PD10、PD11为上拉输入 分别定义为四行 GPIO_InitStruture.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStruture.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11; GPIO_Init(GPIOD,&GPIO_InitStruture); } /*** *函数名:KEY_ROW_SCAN *功 能:按键行扫描 *返回值:1~4,对应1~4行按键位置 */ //如果为1,代表没有按键被按下,如果为0,代表有按键被按下 char KEY_ROW_SCAN(void) { //读出行扫描状态 Key_row[0] = GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_8)<<3; Key_row[0] = Key_row[0] | (GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_9)<<2); Key_row[0] = Key_row[0] | (GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_10)<<1); Key_row[0] = Key_row[0] | (GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_11)); if(Key_row[0] != 0x0f) //不是1111,代表肯定有一个0行 { delay_ms(10); //消抖 if(Key_row[0] != 0x0f) //0111 1011 1101 1110 { //printf("Key_Row_DATA = 0x%xrn",Key_row[0]); switch(Key_row[0]) { case 0x07: //0111 判断为该列第1行的按键按下 return 1; case 0x0b: //1011 判断为该列第2行的按键按下 return 2; case 0x0d: //1101 判断为该列第3行的按键按下 return 3; case 0x0e: //1110 判断为该列第4行的按键按下 return 4; default : return 0; } } else return 0; } else return 0; } /*** *函数名:KEY_SCAN *功 能:4*4按键扫描 *返回值:0~16,对应16个按键 */ char KEY_SCAN(void) { char Key_Num=0; //1-16对应的按键数 char key_row_num=0; //行扫描结果记录 KEY_CLO0_OUT_LOW; if( (key_row_num=KEY_ROW_SCAN()) != 0 ) { while(KEY_ROW_SCAN() != 0); //消抖 Key_Num = 0 + key_row_num; } KEY_CLO0_OUT_HIGH; KEY_CLO1_OUT_LOW; if( (key_row_num=KEY_ROW_SCAN()) != 0 ) { while(KEY_ROW_SCAN() != 0); Key_Num = 4 + key_row_num; //printf("Key_Clo_2rn"); } KEY_CLO1_OUT_HIGH; KEY_CLO2_OUT_LOW; if( (key_row_num=KEY_ROW_SCAN()) != 0 ) { while(KEY_ROW_SCAN() != 0); Key_Num = 8 + key_row_num; //printf("Key_Clo_3rn"); } KEY_CLO2_OUT_HIGH; KEY_CLO3_OUT_LOW; if( (key_row_num=KEY_ROW_SCAN()) != 0 ) { while(KEY_ROW_SCAN() != 0); Key_Num = 12 + key_row_num; } KEY_CLO3_OUT_HIGH; return Key_Num; } key.h: #ifndef _KEY16_H #define _KEY16_H #include "sys.h" #include "stm32f10x.h" #include void key_init(); char KEY_SCAN(void); char KEY_ROW_SCAN(void); void HW_KEY_FUNCTION(void); #define KEY_CLO0_OUT_LOW GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_RESET) #define KEY_CLO1_OUT_LOW GPIO_WriteBit(GPIOB,GPIO_Pin_13,Bit_RESET) #define KEY_CLO2_OUT_LOW GPIO_WriteBit(GPIOB,GPIO_Pin_14,Bit_RESET) #define KEY_CLO3_OUT_LOW GPIO_WriteBit(GPIOB,GPIO_Pin_15,Bit_RESET) #define KEY_CLO0_OUT_HIGH GPIO_WriteBit(GPIOB,GPIO_Pin_12,Bit_SET) #define KEY_CLO1_OUT_HIGH GPIO_WriteBit(GPIOB,GPIO_Pin_13,Bit_SET) #define KEY_CLO2_OUT_HIGH GPIO_WriteBit(GPIOB,GPIO_Pin_14,Bit_SET) #define KEY_CLO3_OUT_HIGH GPIO_WriteBit(GPIOB,GPIO_Pin_15,Bit_SET) #endif
好啦,所有准备工作都完成啦!!又到了我们激动人心的时刻啦!! 运行成功图如下: over。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1907 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1678 浏览 1 评论
1171 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
770 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1730 浏览 2 评论
1970浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
806浏览 4评论
stm32f4下spi+dma读取数据不对是什么原因导致的?
254浏览 3评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
623浏览 3评论
634浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-23 07:51 , Processed in 0.689713 second(s), Total 44, Slave 39 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号