STM32用矩阵键盘,不带外部中断,可以多个按键同时按下C代码:STM32用矩阵键盘,不带外部中断,可以多个按键同时按下/**************矩阵键盘.h文件*********************************/#ifndef__COMMON_H#define__COMMON_H#includestm32f10x.h/*4*4矩阵键盘*/voidkeyboard_init(void);voidupdate_key(void);externunsignedcharkey[4][4];#endif/**************矩阵键盘.c文件*****************************/#includecommon.hstructio_port{GPIO_TypeDef*GPIO_x;unsignedshortGPIO_pin;};staticstructio_portkey_output[4]={{GPIOD,GPIO_Pin_0},{GPIOD,GPIO_Pin_1},{GPIOD,GPIO_Pin_2},{GPIOD,GPIO_Pin_3}};staticstructio_portkey_input[4]={{GPIOD,GPIO_Pin_4},{GPIOD,GPIO_Pin_5},{GPIOD,GPIO_Pin_6},{GPIOD,GPIO_Pin_7}};unsignedcharkey[4][4];voidkeyboard_init(void){GPIO_InitTypeDefGPIO_InitStructure;unsignedchari;/*键盘行扫描输出线输出高电平*//*PA0PA1PA2PA3输出*/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);/*键盘列扫描输入线键被按时输入高电平放开输入低电平*//*PA4PA5PA6PA7输入*/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;i4;i++){GPIO_SetBits(key_output[i].GPIO_x,key_output[i].GPIO_pin);}}voidupdate_key(void){unsignedchari,j;for(i=0;i4;i++)//i是输出口,依次置低电平{GPIO_ResetBits(key_output[i].GPIO_x,key_output[i].GPIO_pin);for(j=0;j4;j++)//j是输入口,当键按下时导通被置为低电平{if(GPIO_ReadInputDataBit(key_input[j].GPIO_x,key_input[j].GPIO_pin)==0){key[i][j]=1;}else{key[i][j]=0;}}GPIO_SetBits(key_output[i].GPIO_x,key_output[i].GPIO_pin);}}stm32矩阵键盘这是硬件上的键盘规划//|1|2|3|4|---line1PE6////---------------------------////|5|6|7|8|---line2PE5////---------------------------////|9|10|11|12|---line3PE4////---------------------------////|13|14|15|16|---line4PE3////---------------------------////|17|18|19|20|---line5PE2////---------------------------////||||////col1col2col3col4////PE0PB5PB8PB9////_________________________________________________//参考了下基于avr的矩阵键盘程序,耐着性子移植到符合上面硬件规划的stm32板子上。volatileuint8_tkey_flag=0;voidkey_init(void){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOB,ENABLE);GPIO_InitTypeDefGPIO_InitStructure;//keyoutputGPIO_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);//keyinputGPIO_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_tIs_Key_PressOn(void){volatileuint8_ti,ScanCode;for(i=0;i4;i++){switch(i)//扫描信号产生{case0:GPIOE-BSRR=0x00010000;//PE0=0;GPIOB-BSRR=0x00000320;//PB5=1;PB8=1;PB9=1;key_flag=1;break;case1:GPIOE-BSRR=0x00000001;//PE0=1;GPIOB-BSRR=0x00200300;//PB5=0;PB8=1;PB9=1;key_flag=2;break;case2:GPIOE-BSRR=0x00000001;//PE0=1;GPIOB-BSRR=0x01000220;//PB5=1;PB8=0;PB9=1;key_flag=3;break;case3: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_tFind_Key_PressOn(uint8_tKeyCode_before,uint8_tKeyCode_after){if(KeyCode_before==KeyCode_after)return(KeyCode_after);elsereturn(PRESS_INVALID);}//计算键值,根据返回的键值计算相应的返回值uint8_tCalc_Key_PressOn(uint8_tKeyCode){uint8_tTempNum;switch(KeyCode){case0xBF:if(1==key_flag){TempNum=1;break;}elseif(2==key_flag){TempNum=2;break;}elseif(3==key_flag){TempNum=3;break;}elseif(4==key_flag){TempNum=4;break;}elsebreak;case0xDF:if(1==key_flag){TempNum=5;break;}elseif(2==key_flag){TempNum=6;break;}elseif(3==key_flag){TempNum=7;break;}elseif(4==key_flag){TempNum=8;break;}elsebreak;case0xEF:if(1==key_flag){TempNum=9;break;}elseif(2==key_flag){TempNum=10;break;}elseif(3==key_flag){TempNum=11;break;}elseif(4==key_flag){TempNum=12;break;}elsebreak;case0xF7:if(1==key_flag){TempNum=13;break;}elseif(2==key_flag){TempNum=14;break;}elseif(3==key_flag){TempNum=15;break;}elseif(4==key_flag){TempNum=16;break;}elsebreak;case0xFB:if(1==key_flag){TempNum=17;break;}elseif(2==key_flag){TempNum=18;break;}elseif(3==key_flag){TempNum=19;break;}elseif(4==key_flag){TempNum=20;break;}elsebreak;default:TempNum=0;break;//发生错误时返回,无效标志}return(TempNum);//正常返回值为1~16}//键盘扫描主程序uint8_tKeyboard(void){uint8_tkey_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学习笔记(三)之矩阵键盘这几天事情比较多,所以就一直没有更新,呵呵,今天早上没课,把之前写好代码整理一