热度 19
2012-3-18 14:45
5052 次阅读|
2 个评论
//write by dragonbao 2011-9-16. 这是硬件上的键盘规划 // | 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 output GPIO_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 input GPIO_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;i4;i++) { switch(i) //扫描信号产生 { case 0: GPIOE-BSRR = 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); //正常返回值为1~16 } //键盘扫描主程序 uint8_t Keyboard(void) { uint8_t key_temp; //暂存键值的变量 key_temp=Is_Key_PressOn(); //判断是否有键闭合 // PORTC=key_temp; 调试过程中使用,正常运行时没用可以删除 if (key_temp==PRESS_INVALID) //判断该次扫描中是否有键按下 return(PRESS_INVALID); //没有闭合则建立无效标志 else delay_nus(100); //闭合则延时 key_temp=Find_Key_PressOn(key_temp,((uint8_t)GPIOE-IDR | 0x83)); //找到闭合键 if (key_temp==PRESS_INVALID) return(key_temp); //若延时前后键值不相等则返回无效标志 else key_temp=Calc_Key_PressOn(key_temp); //有效则计算键值 while((((uint8_t)GPIOE-IDR)|0x83)!=0xff)//等待键放。。。看实际情况使用 { delay_nus(10); } return(key_temp); //返回键值 } 。。。。。。。 有更好建议或意见的请不吝指出。。。。