1 typedef struct //定义任意IO初始化结构体
2 {
3 GPIO_TypeDef* GPIOX;
4 uint16_t GPIO_Pin;
5 }KHGPT[4]; //4*4
6
7 KHGPT KHPIN={
8 //只需要在下面填写横竖行的IO口和管脚 IO口和管脚都可以随意定义 无需在一个IO口 管脚也无需按顺序
9 {GPIOB,GPIO_Pin_15} ,{GPIOB,GPIO_Pin_14}, {GPIOB,GPIO_Pin_13},{GPIOB,GPIO_Pin_12}//row 横行
10 }; //这个数组中顺序即为按键行io的顺序
11
12 typedef struct
13 {
14 GPIO_TypeDef* GPIOX;
15 uint16_t GPIO_Pin;
16 }KLGPT[3]; //4*3
17
18 KLGPT KLPIN={
19 //只需要在下面填写横竖行的IO口和管脚 IO口和管脚都可以随意定义 无需在一个IO口 管脚也无需按顺序
20 {GPIOD,GPIO_Pin_8}, {GPIOD,GPIO_Pin_9}, {GPIOD,GPIO_Pin_10} //col 竖行
21 }; //这个数组中顺序即为按键列io的顺序
22
23 #define RCC_APB2_GPIOX RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOD//IO时钟
24 #define MAX_time 36000000 // 松手检测最大延时
25
26 void KEY_Init1(void) //按键io初始化函数
27 {
28 u8 i;
29 GPIO_InitTypeDef GPIO_InitStructure;
30 RCC_APB2PeriphClockCmd(RCC_APB2_GPIOX,ENABLE);//使能PORTC时钟
31 for(i=0;i<4;i++)
32
33 {
34 GPIO_InitStructure.GPIO_Pin = KHPIN[i].GPIO_Pin; //从行的数组取io
35 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置成推挽输出
36 GPIO_Init(KHPIN[i].GPIOX, &GPIO_InitStructure); //初始化行的io
37 GPIO_ResetBits(KHPIN[i].GPIOX,KHPIN[i].GPIO_Pin);
38 }
39
40 for(i=0;i<3;i++)
41 {
42 GPIO_InitStructure.GPIO_Pin = KLPIN[i].GPIO_Pin; //从列的数组取io
43 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
44 GPIO_Init(KLPIN[i].GPIOX, &GPIO_InitStructure); //初始化列io
45 }
46 }
47
48 u8 ReScan(GPIO_TypeDef* GPIOX,uint16_t colPin,u8 colIndex)
49 {
50 u8 i;
51 delay_ms(10); //消抖延时
52 for(i = 0;i<4;i++)
53 {
54 GPIO_SetBits(KHPIN[i].GPIOX,KHPIN[i].GPIO_Pin); //每个行置1
55 if((GPIO_ReadInputDataBit(GPIOX, colPin) == 1)) //如果列也变了 行的值就知道了 为 i
56 {
57 GPIO_ResetBits(KHPIN[i].GPIOX,KHPIN[i].GPIO_Pin); //行恢复 置0
58 return colIndex+i*3+1;//返回的数据 为1-12 对应3x4键盘的12个键
59 } //colIndex+i*4+1返回的数据 为1-16 对应4x4键盘的16个键
60 GPIO_ResetBits(KHPIN[i].GPIOX,KHPIN[i].GPIO_Pin); //行恢复 置0
61 }
62 return 0;
63 }
64 u8 KEY_Scan1(void)
65 {
66 u8 i,keyvalue;
67 u32 j=0;
68 for(i = 0;i<3;i++)
69 {
70 if(GPIO_ReadInputDataBit(KLPIN[i].GPIOX,KLPIN[i].GPIO_Pin) == 0)//检测列 列值为 i
71 {
72 keyvalue = ReScan(KLPIN[i].GPIOX,KLPIN[i].GPIO_Pin,i);//检测行 取键值
73 while(GPIO_ReadInputDataBit(KLPIN[i].GPIOX,KLPIN[i].GPIO_Pin) == 0)
74 while((GPIO_ReadInputDataBit(KLPIN[i].GPIOX,KLPIN[i].GPIO_Pin) == 0)&&(j<MAX_time))j++;//松手检测
75 return keyvalue;//返回键值
76 }
77 }
78 return 0;
79 }
80
81 void KEY_Value(void)//设置键值
82 {
83 u8 KEY=0;
84 KEY=KEY_Scan1(); //得到键值
85 if(KEY !=0 )
86 {
87 delay_ms(5);
88 BEEP_RUN(); //控制蜂鸣器
89 switch(KEY) //得到键值,分配功能
90 {
91 case S1:
92 OLED_ShowNum(0,0,1,4,12);//显示数字码值 1
93 OLED_Refresh_Gram(); //更新显示到OLED
94 break;
95 case S2:
96 OLED_ShowNum(0,0,2,4,12);//显示数字码值 2
97 OLED_Refresh_Gram(); //更新显示到OLED
98 break;
99 case S3:
100 OLED_ShowNum(0,0,3,4,12);//显示数字码值 3
101 OLED_Refresh_Gram(); //更新显示到OLED
102 break;
103 case S4:
104 OLED_ShowNum(0,0,4,4,12);//显示数字码值 4
105 OLED_Refresh_Gram(); //更新显示到OLED
106 break;
107 case S5:
108 OLED_ShowNum(0,0,5,4,12);
109 OLED_Refresh_Gram(); //更新显示到OLED
110 break;
111 case S6:
112 OLED_ShowNum(0,0,6,4,12);
113 OLED_Refresh_Gram(); //更新显示到OLED
114 break;
115 case S7:
116 OLED_ShowNum(0,0,7,4,12);
117 OLED_Refresh_Gram(); //更新显示到OLED
118 break;
119 case S8:
120 OLED_ShowNum(0,0,8,4,12);
121 OLED_Refresh_Gram(); //更新显示到OLED
122 break;
123 case S9:
124 OLED_ShowNum(0,0,9,4,12);//
125 OLED_Refresh_Gram(); //更新显示到OLED
126 break;
127 case S10:
128 LED1=1;
129 OLED_ShowString(18,0,"*",12);
130 OLED_Refresh_Gram(); //更新显示到OLED
131 break;
132 case S11:
133 OLED_ShowNum(0,0,0,4,12);
134 OLED_Refresh_Gram(); //更新显示到OLED
135 break;
136 case S12:
137 OLED_ShowString(18,0,"#",12); //显示字符串码值 #
138 OLED_Refresh_Gram(); //更新显示到OLED
139 break;
140 }
141 }
142 }