STM32矩阵键盘实现方法收集.doc_第1页
STM32矩阵键盘实现方法收集.doc_第2页
STM32矩阵键盘实现方法收集.doc_第3页
STM32矩阵键盘实现方法收集.doc_第4页
STM32矩阵键盘实现方法收集.doc_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

STM32用矩阵键盘,不带外部中断,可以多个按键同时按下C代码: STM32用矩阵键盘,不带外部中断,可以多个按键同时按下 /*矩阵键盘.h文件*/#ifndef _COMMON_H #define _COMMON_H #include stm32f10x.h /* 4*4矩阵键盘 */ void keyboard_init(void); void update_key(void); extern unsigned char key44;#endif /*矩阵键盘.c文件*/#include common.hstruct io_port GPIO_TypeDef *GPIO_x; unsigned short GPIO_pin; static struct io_port key_output4 = GPIOD, GPIO_Pin_0, GPIOD, GPIO_Pin_1,GPIOD, GPIO_Pin_2, GPIOD, GPIO_Pin_3;static struct io_port key_input4 = GPIOD, GPIO_Pin_4, GPIOD, GPIO_Pin_5,GPIOD, GPIO_Pin_6, GPIOD, GPIO_Pin_7;unsigned char key44;void keyboard_init(void) GPIO_InitTypeDef GPIO_InitStructure;unsigned char i;/* 键盘行扫描输出线 输出高电平 */* PA0 PA1 PA2 PA3 输出*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOD, &GPIO_InitStructure);/* 键盘列扫描输入线 键被按时输入高电平 放开输入低电平 */* PA4 PA5 PA6 PA7 输入*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOD, &GPIO_InitStructure);for(i = 0; i 4; i+) GPIO_SetBits(key_outputi.GPIO_x, key_outputi.GPIO_pin);void update_key(void)unsigned char i, j;for(i = 0; i 4; i+) /i是输出口,依次置低电平 GPIO_ResetBits(key_outputi.GPIO_x, key_outputi.GPIO_pin); for(j = 0; j 4; j+) /j是输入口,当键按下时导通被置为低电平 if(GPIO_ReadInputDataBit(key_inputj.GPIO_x, key_inputj.GPIO_pin) = 0) keyij = 1; else keyij = 0; GPIO_SetBits(key_outputi.GPIO_x, key_outputi.GPIO_pin);stm32 矩阵键盘这是硬件上的键盘规划/ | 1 | 2 | 3 | 4 | -line 1 PE6 / - / | 5 | 6 | 7 | 8 | -line 2 PE5 / - / | 9 | 10| 11| 12| -line 3 PE4 / - / | 13| 14| 15| 16| -line 4 PE3 / - / | 17| 18| 19| 20| -line 5 PE2 / - / | | | | / col1 col2 col3 col4 / PE0 PB5 PB8 PB9 /_/参考了下基于avr的矩阵键盘程序,耐着性子移植到符合上面硬件规划的stm32板子上。volatile uint8_t key_flag = 0;void key_init(void)RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;/key outputGPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_Init(GPIOE,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_9;GPIO_Init(GPIOB,&GPIO_InitStructure);/key inputGPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;/上拉输入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6;GPIO_Init(GPIOE,&GPIO_InitStructure);/判断是否有键按下函数,对键盘进行一次扫描/返回键盘接口状态,有键按下时返回键值;没有键按下返回无效标志位uint8_t Is_Key_PressOn(void)volatile uint8_t i,ScanCode;for(i=0;iBSRR = 0x00010000;/PE0 = 0;GPIOB-BSRR = 0x00000320;/PB5 = 1; PB8 = 1; PB9 = 1;key_flag = 1;break;case 1:GPIOE-BSRR = 0x00000001;/PE0 = 1;GPIOB-BSRR = 0x00200300;/PB5 = 0; PB8 = 1; PB9 = 1;key_flag = 2;break;case 2:GPIOE-BSRR = 0x00000001;/PE0 = 1;GPIOB-BSRR = 0x01000220;/PB5 = 1; PB8 = 0; PB9 = 1;key_flag = 3;break;case 3:GPIOE-BSRR = 0x00000001;/PE0 = 1;GPIOB-BSRR = 0x02000120;/PB5 = 1; PB8 = 1; PB9 = 0;key_flag = 4;break;default: key_flag = 0; break;if(uint8_t)GPIOE-IDR)|0x83)!=0xff)return (uint8_t)GPIOE-IDR | 0x83);return(PRESS_INVALID);/找到闭合键,判断延时前后两次键值是否相同,如果相同则返回键值uint8_t Find_Key_PressOn(uint8_t KeyCode_before,uint8_t KeyCode_after)if(KeyCode_before=KeyCode_after) return(KeyCode_after);else return(PRESS_INVALID);/计算键值,根据返回的键值计算相应的返回值uint8_t Calc_Key_PressOn(uint8_t KeyCode)uint8_t TempNum;switch(KeyCode)case 0xBF:if(1=key_flag)TempNum = 1;break;else if(2=key_flag)TempNum = 2;break;else if(3=key_flag)TempNum = 3;break;else if(4=key_flag)TempNum = 4;break;else break;case 0xDF:if(1=key_flag)TempNum = 5;break;else if(2=key_flag)TempNum = 6;break;else if(3=key_flag)TempNum = 7;break;else if(4=key_flag)TempNum = 8;break;else break;case 0xEF:if(1=key_flag)TempNum = 9;break;else if(2=key_flag)TempNum = 10;break;else if(3=key_flag)TempNum = 11;break;else if(4=key_flag)TempNum = 12;break;else break;case 0xF7:if(1=key_flag)TempNum = 13;break;else if(2=key_flag)TempNum = 14;break;else if(3=key_flag)TempNum = 15;break;else if(4=key_flag)TempNum = 16;break;else break;case 0xFB:if(1=key_flag)TempNum = 17;break;else if(2=key_flag)TempNum = 18;break;else if(3=key_flag)TempNum = 19;break;else if(4=key_flag)TempNum = 20;break;else break;default : TempNum=0;break; /发生错误时返回,无效标志return(TempNum); /正常返回值为116/键盘扫描主程序uint8_t Keyboard(void)uint8_t key_temp; /暂存键值的变量key_temp=Is_Key_PressOn(); /判断是否有键闭合/ PORTC=key_temp; 调试过程中使用,正常运行时没用可以删除if (key_temp=PRESS_INVALID) /判断该次扫描中是否有键按下return(PRESS_INVALID); /没有闭合则建立无效标志elsedelay_nus(100); /闭合则延时key_temp=Find_Key_PressOn(key_temp,(uint8_t)GPIOE-IDR | 0x83); /找到闭合键if (key_temp=PRESS_INVALID)return(key_temp); /若延时前后键值不相等则返回无效标志elsekey_temp=Calc_Key_PressOn(key_temp); /有效则计算键值while(uint8_t)GPIOE-IDR)|0x83)!=0xff)/等待键放。看实际情况使用delay_nus(10);return(key_temp); /返回键值。梦之旅同学松鼠1.0学习笔记(三)之矩阵键盘 这几天事情比较多,所以就一直没有更新,呵呵,今天早上没课,把之前写好代码整理一下,顺便说下思路,发上来,供大家参考参考。 首先,本矩阵键盘硬件连接如下: 思路: 我的思路如下,首先,把纵向三线设置为推挽输出,然后把横向三线设置为下拉输入,然后读取横向三线的值,如果有接口的读数为1,说明有按键按下了,把该值与0x07相与后放到scana,然后左移4位放到result中,这之后把横向三线设置为推挽输出,纵向三线设置为下拉输入,然后读取纵向三线的值,把相应的键值保存到scanb中,然后通过移位使得低四位表示的是相应的按键所在横向的值,然后与result相或放到result的低四位,这样得到的result高四位就是按键所在纵向的值,低四位就是按键所在横向的值,由此就可以检测到那个按键被按下了。 效果:按下相应的键盘,四个led灯会显示各种不同的状态,hoho,一共有9种状态。 #include stm32f10x_lib.hvoid RCC_Configuration(void);void GPIO_Configuration(void);void NVIC_Configuration(void);void delay(void);u8 KEY_GPIO_Scanning(void);int main(void)#ifdef DEBUG debug();#endifRCC_Configuration();/配置系统时钟NVIC_Configuration(); /配置 NVIC 和 Vector Table GPIO_Configuration(); /使用的GPIO口 /主循环 while (1) /循环扫描按键 按键按下时 对应的LED亮 switch ( KEY_GPIO_Scanning() ) case(0x18): GPIO_SetBits(GPIOB, GPIO_Pin_12); GPIO_ResetBits(GPIOB, GPIO_Pin_13); GPIO_ResetBits(GPIOB, GPIO_Pin_14); GPIO_ResetBits(GPIOB, GPIO_Pin_15); break; case(0x12): GPIO_ResetBits(GPIOB, GPIO_Pin_12); GPIO_SetBits(GPIOB, GPIO_Pin_13); GPIO_ResetBits(GPIOB, GPIO_Pin_14); GPIO_ResetBits(GPIOB, GPIO_Pin_15); break; case(0x14): GPIO_SetBits(GPIOB, GPIO_Pin_12); GPIO_SetBits(GPIOB, GPIO_Pin_13); GPIO_ResetBits(GPIOB, GPIO_Pin_14); GPIO_ResetBits(GPIOB, GPIO_Pin_15); break; case(0x28): GPIO_ResetBits(GPIOB, GPIO_Pin_12); GPIO_ResetBits(GPIOB, GPIO_Pin_13); GPIO_SetBits(GPIOB, GPIO_Pin_14); GPIO_ResetBits(GPIOB, GPIO_Pin_15); break; case(0x24): GPIO_SetBits(GPIOB, GPIO_Pin_12); GPIO_ResetBits(GPIOB, GPIO_Pin_13); GPIO_SetBits(GPIOB, GPIO_Pin_14); GPIO_ResetBits(GPIOB, GPIO_Pin_15); break; case(0x48): GPIO_SetBits(GPIOB, GPIO_Pin_12); GPIO_SetBits(GPIOB, GPIO_Pin_13); GPIO_SetBits(GPIOB, GPIO_Pin_14); GPIO_ResetBits(GPIOB, GPIO_Pin_15); break; case(0x42): GPIO_ResetBits(GPIOB, GPIO_Pin_12); GPIO_ResetBits(GPIOB, GPIO_Pin_13); GPIO_ResetBits(GPIOB, GPIO_Pin_14); GPIO_SetBits(GPIOB, GPIO_Pin_15); break; case(0x44): GPIO_SetBits(GPIOB, GPIO_Pin_12); GPIO_ResetBits(GPIOB, GPIO_Pin_13); GPIO_ResetBits(GPIOB, GPIO_Pin_14); GPIO_SetBits(GPIOB, GPIO_Pin_15); break; case(0x22): GPIO_SetBits(GPIOB, GPIO_Pin_12); GPIO_SetBits(GPIOB, GPIO_Pin_13); GPIO_SetBits(GPIOB, GPIO_Pin_14); GPIO_SetBits(GPIOB, GPIO_Pin_15); break; void RCC_Configuration(void) ErrorStatus HSEStartUpStatus; RCC_DeInit(); /将外设 RCC寄存器重设为缺省值 RCC_HSEConfig(RCC_HSE_ON); /设置外部高速晶振(HSE) HSEStartUpStatus = RCC_WaitForHSEStartUp();/等待 HSE 起振 if(HSEStartUpStatus = SUCCESS) FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);/预取指缓存使能 FLASH_SetLatency(FLASH_Latency_2);/设置代码延时值 FLASH_Latency_2 2 延时周期 RCC_HCLKConfig(RCC_SYSCLK_Div1); /设置 AHB 时钟(HCLK) RCC_SYSCLK_Div1 AHB 时钟 = 系统时钟 RCC_PCLK2Config(RCC_HCLK_Div2);/设置高速 AHB 时钟(PCLK2) RCC_HCLK_Div2 APB1 时钟 = HCLK / 2 RCC_PCLK1Config(RCC_HCLK_Div2); /设置低速 AHB 时钟(PCLK1)RCC_HCLK_Div2 APB1 时钟 = HCLK / 2 RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); / PLLCLK = 8MHz * 9 = 72 MHz 设置 PLL 时钟源及倍频系数 RCC_PLLCmd(ENABLE);/使能或者失能 PLL while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) = RESET) /等待指定的 RCC 标志位设置成功 等待PLL初始化成功 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);/设置系统时钟(SYSCLK) 设置PLL为系统时钟源 while(RCC_GetSYSCLKSource() != 0x08) /等待PLL成功用作于系统时钟的时钟源 0x00:HSI 作为系统时钟 0x04:HSE作为系统时钟 0x08:PLL作为系统时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);/使能或者失能 APB2 外设时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); void GPIO_Configuration(void) GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15 ; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /LED端口设置为 推挽输出 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_Init(GPIOB, &GPIO_InitStructure); /键盘 横向 三线 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 ; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; GPIO_Init(GPIOA, &GPIO_InitStructure); /键盘 纵向 三线 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); void GPIO_Reconfiguration(void) GPIO_InitTypeDef GPIO_InitStructure; /键盘 横向 三线 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 ; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); /键盘 纵向 三线 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; GPIO_Init(GPIOB, &GPIO_InitStructure); /* Function Name : KEY_GPIO_Scanning* Description : 依次扫描4个按键 使用一个u8变量的低4位存储扫描结果* Input : None* Output : None* Return : 扫描的结果 有效数据是低4位*/u8 KEY_GPIO_Scanning(void)u8 result;u8 scana; /单个按键扫描变量 u8 scanb; /四个按键总的情况变量 scan_sum低四位的每一位对应一个按键

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论