一、前言
?
一般来说使用IO作为设备的按键输入就够用了 ,但是我就是想实现制作的按键键盘就像按实际键盘的某些按键一样,这样在上位机处理就容易很多,直接调用键盘类函数就可以了。
而且自己根据需求可以自定义按键数量,按键功能,我这里制作一个小数字键盘,增加了Delete按键,使用的是红轴机械按键,效果如下
?
二、环境
?stm32f1
keil
window10?
三、正文
我画的原理图如下
pcb
核心程序
#include "stm32f10x.h"
#include "led.h"
#include "key.h"
#include "sys.h"
#include "delay.h"
#include <stdio.h>
#include "string.h"
#include "usb_lib.h"
#include "hw_config.h"
#include "usb_pwr.h"
//键盘配置按键
BUTTON_STATE key_all[232]=
{
0,0,0,0, //0 00 //Fn键的偏移位置
0,0,0,0, //1 01 Keyboard ErrorRollOver
0,0,0,0, //2 02 Keyboard POSTFail
0,0,0,0, //3 03 Keyboard ErrorUndefined
0,0,0,0, //4 04 Keyboard a and A
0,0,0,0, //5 05 Keyboard b and B
0,0,0,0, //6 06 Keyboard c and C
0,0,0,0, //7 07 Keyboard d and D
0,0,0,0, //8 08 Keyboard e and E
0,0,0,0, //9 09 Keyboard f and F
0,0,0,0, //10 0A Keyboard g and G
0,0,0,0, //11 0B Keyboard h and H
0,0,0,0, //12 0C Keyboard i and I
0,0,0,0, //13 0D Keyboard j and J
0,0,0,0, //14 0E Keyboard k and K
0,0,0,0, //15 0F Keyboard l and L
0,0,0,0, //16 10 Keyboard m and M
0,0,0,0, //17 11 Keyboard n and N
0,0,0,0, //18 12 Keyboard o and O
0,0,0,0, //19 13 Keyboard p and P
0,0,0,0, //20 14 Keyboard q and Q
0,0,0,0, //21 15 Keyboard r and R
0,0,0,0, //22 16 Keyboard s and S
0,0,0,0, //23 17 Keyboard t and T
0,0,0,0, //24 18 Keyboard u and U
0,0,0,0, //25 19 Keyboard v and V
0,0,0,0, //26 1A Keyboard w and W
0,0,0,0, //27 1B Keyboard x and X
0,0,0,0, //28 1C Keyboard y and Y
0,0,0,0, //29 1D Keyboard z and Z
0,GPIOA,GPIO_Pin_7,0, //30 1E Keyboard 1 and !
0,GPIOB,GPIO_Pin_1,0, //31 1F Keyboard 2 and @
0,GPIOB,GPIO_Pin_13,0, //32 20 Keyboard 3 and #
0,GPIOA,GPIO_Pin_6,0, //33 21 Keyboard 4 and $
0,GPIOB,GPIO_Pin_0,0, //34 22 Keyboard 5 and %
0,GPIOB,GPIO_Pin_12,0, //35 23 Keyboard 6 and ^
0,GPIOA,GPIO_Pin_5,0, //36 24 Keyboard 7 and &
0,GPIOC,GPIO_Pin_5,0, //37 25 Keyboard 8 and *
0,GPIOB,GPIO_Pin_11,0, //38 26 Keyboard 9 and (
0,GPIOC,GPIO_Pin_4,0, //39 27 Keyboard 0 and )
0,GPIOB,GPIO_Pin_14,0, //40 28 Keyboard Return (ENTER)
0,0,0,0, //41 29 Keyboard ESCAPE
0,GPIOA,GPIO_Pin_0,0, //42 2A Keyboard DELETE (Backspace)
0,0,0,0, //43 2B Keyboard Tab
0,0,0,0, //44 2C Keyboard Spacebar
0,0,0,0, //45 2D Keyboard - and (underscore)
0,0,0,0, //46 2E Keyboard = and +
0,0,0,0, //47 2F Keyboard [ and {
0,0,0,0, //48 30 Keyboard ] and }
0,0,0,0, //49 31 Keyboard \ and |
0,0,0,0, //50 32 Keyboard Non-US # and ~
0,0,0,0, //51 33 Keyboard ; and :
0,0,0,0, //52 34 Keyboard ‘ and “
0,0,0,0, //53 35 Keyboard Grave Accent and Tilde
0,0,0,0, //54 36 Keyboard, and <
0,GPIOB,GPIO_Pin_10,0, //55 37 Keyboard . and >
0,0,0,0, //56 38 Keyboard / and ?
0,0,0,0, //57 39 Keyboard Caps Lock
0,0,0,0, //58 3A Keyboard F1
0,0,0,0, //59 3B Keyboard F2
0,0,0,0, //60 3C Keyboard F3
0,0,0,0, //61 3D Keyboard F4
0,0,0,0, //62 3E Keyboard F5
0,0,0,0, //63 3F Keyboard F6
0,0,0,0, //64 40 Keyboard F7
0,0,0,0, //65 41 Keyboard F8
0,0,0,0, //66 42 Keyboard F9
0,0,0,0, //67 43 Keyboard F10
0,0,0,0, //68 44 Keyboard F11
0,0,0,0, //69 45 Keyboard F12
0,0,0,0, //70 46 Keyboard PrintScree n
0,0,0,0, //71 47 Keyboard Scroll Lock
0,0,0,0, //72 48 Keyboard Pause
0,0,0,0, //73 49 Keyboard Insert
0,0,0,0, //74 4A Keyboard Home
0,0,0,0, //75 4B Keyboard PageUp
0,0,0,0, //76 4C Keyboard Delete Forward
0,0,0,0, //77 4D Keyboard End
0,0,0,0, //78 4E Keyboard PageDown
0,0,0,0, //79 4F Keyboard RightArrow
0,0,0,0, //80 50 Keyboard LeftArrow
0,0,0,0, //81 51 Keyboard DownArrow
0,0,0,0, //82 52 Keyboard UpArrow
0,0,0,0, //83 53 Keypad Num Lock and Clear
0,GPIOA,GPIO_Pin_1,0, //84 54 Keypad /
0,GPIOA,GPIO_Pin_2,0, //85 55 Keypad *
0,GPIOA,GPIO_Pin_3,0, //86 56 Keypad -
0,GPIOA,GPIO_Pin_4,0, //87 57 Keypad +
0,0,0,0, //88 58 Keypad ENTER
0,0,0,0, //89 59 Keypad 1 and End
0,0,0,0, //90 5A Keypad 2 and Down Arrow
0,0,0,0, //91 5B Keypad 3 and PageDn
0,0,0,0, //92 5C Keypad 4 and Left Arrow
0,0,0,0, //93 5D Keypad 5
0,0,0,0, //94 5E Keypad 6 and Right Arrow
0,0,0,0, //95 5F Keypad 7 and Home
0,0,0,0, //96 60 Keypad 8 and Up Arrow
0,0,0,0, //97 61 Keypad 9 and PageUp
0,0,0,0, //98 62 Keypad 0 and Insert
0,0,0,0, //99 63 Keypad . and Delete
0,0,0,0, //100 64 Keyboard Non-US \ and | 3;
0,0,0,0, //101 65 Keyboard Application
0,0,0,0, //102 66 Keyboard Power
0,0,0,0, //103 67 Keypad =
0,0,0,0, //104 68 Keyboard F13
0,0,0,0, //105 69 Keyboard F14
0,0,0,0, //106 6A Keyboard F15
0,0,0,0, //107 6B Keyboard F16
0,0,0,0, //108 6C Keyboard F17
0,0,0,0, //109 6D Keyboard F18
0,0,0,0, //110 6E Keyboard F19
0,0,0,0, //111 6F Keyboard F20
0,0,0,0, //112 70 Keyboard F21
0,0,0,0, //113 71 Keyboard F22
0,0,0,0, //114 72 Keyboard F23
0,0,0,0, //115 73 Keyboard F24
0,0,0,0, //116 74 Keyboard Execute √
0,0,0,0, //117 75 Keyboard Help √
0,0,0,0, //118 76 Keyboard Menu √
0,0,0,0, //119 77 Keyboard Select √
0,0,0,0, //120 78 Keyboard Stop √
0,0,0,0, //121 79 Keyboard Again √
0,0,0,0, //122 7A Keyboard Undo √
0,0,0,0, //123 7B Keyboard Cut √
0,0,0,0, //124 7C Keyboard Copy √
0,0,0,0, //125 7D Keyboard Paste √
0,0,0,0, //126 7E Keyboard Find √
0,0,0,0, //127 7F Keyboard Mute √
0,0,0,0, //128 80 Keyboard Volume Up √
0,0,0,0, //129 81 Keyboard Volume Down √
0,0,0,0, //130 82 Keyboard Locking Caps Lock 12 √
0,0,0,0, //131 83 Keyboard Locking Num Lock 12 √
0,0,0,0, //132 84 Keyboard Locking Scroll Lock 12 √
0,0,0,0, //133 85 Keypad Comma 27 107
0,0,0,0, //134 86 Keypad Equal Sign 29
0,0,0,0, //135 87 Keyboard International1 15,28 56
0,0,0,0, //136 88 Keyboard International2 16
0,0,0,0, //137 89 Keyboard International3 17
0,0,0,0, //138 8A Keyboard International4 18
0,0,0,0, //139 8B Keyboard International5 19
0,0,0,0, //140 8C Keyboard International6 20
0,0,0,0, //141 8D Keyboard International7 21
0,0,0,0, //142 8E Keyboard International8 22
0,0,0,0, //143 8F Keyboard International9 22
0,0,0,0, //144 90 Keyboard LANG1 25
0,0,0,0, //145 91 Keyboard LANG2 26
0,0,0,0, //146 92 Keyboard LANG3 30
0,0,0,0, //147 93 Keyboard LANG4 31
0,0,0,0, //148 94 Keyboard LANG5 32
0,0,0,0, //149 95 Keyboard LANG6 8
0,0,0,0, //150 96 Keyboard LANG7 8
0,0,0,0, //151 97 Keyboard LANG8 8
0,0,0,0, //152 98 Keyboard LANG9 8
0,0,0,0, //153 99 Keyboard Alternate Erase 7
0,0,0,0, //154 9A Keyboard SysReq/Attention 1
0,0,0,0, //155 9B Keyboard Cancel
0,0,0,0, //156 9C Keyboard Clear
0,0,0,0, //157 9D Keyboard Prior
0,0,0,0, //158 9E Keyboard Return
0,0,0,0, //159 9F Keyboard Separator
0,0,0,0, //160 A0 Keyboard Out
0,0,0,0, //161 A1 Keyboard Oper
0,0,0,0, //162 A2 Keyboard Clear/Again
0,0,0,0, //163 A3 Keyboard CrSel/Props
0,0,0,0, //164 A4 Keyboard ExSel
0,0,0,0, //165 A5-CF Reserved
0,0,0,0, //166 A5-CF Reserved
0,0,0,0, //167 A5-CF Reserved
0,0,0,0, //168 A5-CF Reserved
0,0,0,0, //169 A5-CF Reserved
0,0,0,0, //170 A5-CF Reserved
0,0,0,0, //171 A5-CF Reserved
0,0,0,0, //172 A5-CF Reserved
0,0,0,0, //173 A5-CF Reserved
0,0,0,0, //174 A5-CF Reserved
0,0,0,0, //175 A5-CF Reserved
0,0,0,0, //176 Keypad 00
0,0,0,0, //177 Keypad 000
0,0,0,0, //178 Thousands Separator 33
0,0,0,0, //179 Decimal Separator 33
0,0,0,0, //180 Currency Unit 34
0,0,0,0, //181 Currency Sub-unit 34
0,0,0,0, //182 Keypad (
0,0,0,0, //183 Keypad )
0,0,0,0, //184 Keypad {
0,0,0,0, //185 Keypad }
0,0,0,0, //186 Keypad Tab
0,0,0,0, //187 Keypad Backspace
0,0,0,0, //188 Keypad A
0,0,0,0, //189 Keypad B
0,0,0,0, //190 Keypad C
0,0,0,0, //191 Keypad D
0,0,0,0, //192 Keypad E
0,0,0,0, //193 Keypad F
0,0,0,0, //194 Keypad XOR
0,0,0,0, //195 Keypad ^
0,0,0,0, //196 Keypad %
0,0,0,0, //197 Keypad <
0,0,0,0, //198 Keypad >
0,0,0,0, //199 Keypad &
0,0,0,0, //200 Keypad &&
0,0,0,0, //201 Keypad |
0,0,0,0, //202 Keypad ||
0,0,0,0, //203 Keypad :
0,0,0,0, //204 Keypad #
0,0,0,0, //205 Keypad Space
0,0,0,0, //206 Keypad @
0,0,0,0, //207 Keypad !
0,0,0,0, //208 Keypad Memory Store
0,0,0,0, //209 Keypad Memory Recall
0,0,0,0, //210 Keypad Memory Clear
0,0,0,0, //211 Keypad Memory Add
0,0,0,0, //212 Keypad Memory Subtract
0,0,0,0, //213 Keypad Memory Multiply
0,0,0,0, //214 Keypad Memory Divide
0,0,0,0, //215 Keypad +/-
0,0,0,0, //216 Keypad Clear
0,0,0,0, //217 Keypad Clear Entry
0,0,0,0, //218 Keypad Binary
0,0,0,0, //219 Keypad Octal
0,0,0,0, //220 Keypad Decimal
0,0,0,0, //221 Keypad Hexadecimal
0,0,0,0, //222 DE Reserved
0,0,0,0, //223 DF Reserved
0,0,0,0, //224 LeftControl
0,0,0,0, //225 LeftShift
0,0,0,0, //226 LeftAlt
0,0,0,0, //227 LeftGUI
0,0,0,0, //228 RightControl
0,0,0,0, //229 RightShift
0,0,0,0, //230 RightAlt
0,0,0,0, //231 RightGUI
};
u8 keys_index[232];
int keys_none0=0; //非零个数
//按键初始化函数
void KeyBoard_Init(void) //IO初始化
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOF|RCC_APB2Periph_GPIOG,ENABLE);//使能PORTA,PORTE时钟
for(int i = 0; i < sizeof(key_all)/sizeof(BUTTON_STATE); i++){
if(key_all[i].port==0||key_all[i].pin==0) continue;
GPIO_InitStructure.GPIO_Pin |= key_all[i].pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //设置成输入,默认下拉
//初始化index
keys_index[keys_none0]=i;
keys_none0++;
}
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIO
GPIO_Init(GPIOD, &GPIO_InitStructure);//初始化GPIO
GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIO
GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化GPIO
GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化GPIO
}
u8 keybuf[8]={0,0,0,0,0,0,0,0}; //按键发送缓存
int keybufp=2; //位置
void putkey(u32 key) //发现一个键按下
{
if(keybufp==8){//若已经超过6个了
memset(keybuf,0xff,8);//发送0xffff;
keybufp++;
return ;
}
else if(keybufp>8){
return ;
}
keybuf[keybufp++]=key;
}
u32 SYS_time=0;
void check_press(BUTTON_STATE *bts) //判断按键是否按下
{
if(bts->port==0||bts->pin==0){
return ;
}
if(GPIO_ReadInputDataBit(bts->port,bts->pin)==1){//判断按键是否按下
if(bts->tick==0){//上次未按下的按键tick次数增加
bts->tick++;
bts->state=0;//清除按下状态
LED0=0;
}
else{
bts->state=1;
LED0=1;
}
}
else{//若释放了
bts->tick=0;
bts->state=0;
LED0=0;
}
}
void key_scan(void) //100Hz
{
keybufp=2; //位置
memset(keybuf,0,8);
//首先轮询所有位置
for(int i = 0; i < keys_none0; i++)
check_press(key_all+keys_index[i]);
//去抖动
delay_ms(10);//去抖动
//再次轮询所有位置
for(int i = 0; i < keys_none0; i++)
check_press(key_all+keys_index[i]);
//特殊键直接置位
if(key_all[LeftControl].state) { keybuf[0] |= (1<<0); }
if(key_all[LeftShift].state) { keybuf[0] |= (1<<1); }
if(key_all[LeftAlt].state) { keybuf[0] |= (1<<2); }
if(key_all[LeftGUI].state) { keybuf[0] |= (1<<3); }
if(key_all[RightAlt].state) { keybuf[0] |= (1<<6); }
//普通键追加到buf
for(int i = 0; i < keys_none0; i++){
int j=keys_index[i];
if(key_all[j].state){
putkey(j);
}
}
UserToPMABufferCopy(keybuf, GetEPTxAddr(ENDP1), 8);
SetEPTxValid(ENDP1);
}
?程序框架简单清晰,不混乱,无其他乱起八糟的功能,只有usb键盘功能,易扩展
折腾了也有2个晚上,我的程序和板子工程文件如下:下载点这里,有意想不到的惊喜噢
四、结语
嘿嘿!
|