基于51单片机的独立按键和矩阵按键用法
------------恢复内容开始------------
主要实现如图所示的功能
将主函数以外的函数全部放在qiyu.h文件中
1 //qiyu.h 2 #define KEY_PORT P1 3 #define led P2 4 #define unchar unsigned char 5 #define uint unsigned int 6 7 sbit Buz = P1^5; 8 sbit LED = P2^0; 9 sbit K1 = P3^0; 10 sbit K2 = P3^1; 11 sbit K3 = P3^2; 12 sbit K4 = P3^3; 13 14 char tzsta,msta,val=0; 15 int seccnt,temp,m=0,j,b; 16 17 18 void ini()//定时器 19 { 20 seccnt=0; 21 msta=tzsta=0; 22 TMOD=0x01; 23 TH0=0xFF; 24 TL0=0x9C; 25 TR0=1; //开启定时器0 26 27 } 28 29 void delay(int p) 30 { 31 while(p--); 32 } 33 void keyscan()//独立按键 34 { 35 if(K1==0) 36 { 37 delay(5); 38 if(K1==0) 39 { 40 msta=1; 41 } 42 } 43 if(K2==0) 44 { 45 delay(5); 46 if(K2==0) 47 { 48 msta=2; 49 } 50 } 51 if(K3==0) 52 { 53 delay(5); 54 if(K3==0) 55 { 56 msta=3; 57 } 58 } 59 if(K4==0) 60 { 61 delay(5); 62 if(K4==0) 63 { 64 msta=4; 65 } 66 } 67 } 68 69 char KeyScan1()//矩阵按键 70 { 71 KEY_PORT = 0x0f; // P1.0-1.3输出高电平,P1.4-P1.7输出低电平 72 if (KEY_PORT != 0x0f) // 读取KEY_PORT看是否有按键按下 73 { 74 delay(10); // 延时消抖 75 if (KEY_PORT != 0x0f) // 确认确实有按键按下 76 { 77 // 先确定按键发生在第几列 78 switch (KEY_PORT) 79 { 80 case 0x07 : val = 1; break; 81 case 0x0b : val = 2; break; 82 case 0x0d : val = 3; break; 83 case 0x0e : val = 4; break; 84 default : break; 85 } 86 87 // 再确定按键发生在第几行 88 KEY_PORT = 0xf0; 89 switch (KEY_PORT) 90 { 91 case 0x70: val = val + 0; break; 92 case 0xb0: val = val + 4; break; 93 case 0xd0: val = val + 8; break; 94 case 0xe0: val = val + 12; break; 95 } 96 return val; 97 } 98 } 99 return 0; 100 } 101 102 void fmq(int a)//蜂鸣器功能 103 { 104 while(a) 105 { 106 Buz=0; 107 delay(5); 108 Buz=1; 109 delay(5); 110 a--; 111 } 112 }
执行独立按键的程序放在dulianjian.h的文件中
1 //dulianjian.h 2 void work0()//蜂鸣器和灯 3 { 4 if(m<=500) 5 { 6 Buz = !Buz; 7 } 8 if(m>5000) 9 { 10 led=0xff; 11 } 12 if(m>=10000) 13 { 14 LED = 0; 15 m = 0; 16 } 17 } 18 //----------------------- 19 void work1() 20 { 21 static int s=50000; 22 23 if(m%500==0) 24 { 25 LED=0; 26 fmq(500); 27 delay(s=s-1000); 28 LED=1; 29 } 30 } 31 //---------------------- 32 void work2()//停止 33 { 34 LED=1; 35 Buz=0; 36 } 37 void work3() 38 { 39 40 }
将矩阵按键的执行代码放在juzhenganjian.h中,同时借用math.h的pow函数来解决移位现象
也可借助https://www.cnblogs.com/action0/p/12642089.html中的思路来写,可大范围的简化代码。
要注意的是,借用第二个方法,要符合端口输入的方式。至于这个,有空再写。
1 //juzhenganjian.h 2 3 4 void work4()//按键1--1个空格 5 { 6 if(m>200) 7 { 8 led=0xff; 9 temp=~led; 10 } 11 if(m>=32000) 12 { 13 for(b=0;b<7;b+=2)//奇数补充 14 { 15 temp+=pow(2,b); 16 led=~temp; 17 delay(40000); 18 } 19 20 21 m=0; 22 } 23 24 } 25 26 void work5()//2--2个空格 27 { 28 if(m>200) 29 { 30 led=0xff; 31 temp=~led; 32 } 33 if(m>=32000) 34 { 35 for(b=0;b<8;b+=3)//奇数补充 36 { 37 temp+=pow(2,b); 38 led=~temp; 39 delay(40000); 40 } 41 for(b=1;b<=7;b+=3)//o数补充 42 { 43 temp+=pow(2,b); 44 led=~temp; 45 delay(40000); 46 } 47 for(b=2;b<7;b+=3)//奇数补充 48 { 49 temp+=pow(2,b); 50 led=~temp; 51 delay(40000); 52 } 53 54 m=0; 55 } 56 } 57 58 void work6()//3--3个空格 59 { 60 if(m>200) 61 { 62 led=0xff; 63 temp=~led; 64 } 65 if(m>=32000) 66 { 67 for(b=0;b<7;b+=4) 68 { 69 temp+=pow(2,b); 70 led=~temp; 71 delay(40000); 72 } 73 m=0; 74 } 75 76 } 77 78 void work7()//4--衍生物 79 { 80 if(m<500) 81 { 82 led=0xff; 83 led=~temp; 84 } 85 if(m%1000==0) 86 { 87 temp+=pow(4,j); 88 led=~temp; 89 } 90 if(m>=10000) 91 { 92 j++; 93 m=0; 94 } 95 } 96 97 void work8()//5--4个空格 98 { 99 if(m>200) 100 { 101 led=0xff; 102 temp=~led; 103 } 104 if(m>=32000) 105 { 106 for(b=0;b<7;b+=5) 107 { 108 temp+=pow(2,b); 109 led=~temp; 110 delay(40000); 111 } 112 113 for(b=2;b<8;b+=5) 114 { 115 temp+=pow(2,b); 116 led=~temp; 117 delay(40000); 118 } 119 for(b=4;b<8;b+=5) 120 { 121 temp+=pow(2,b); 122 led=~temp; 123 delay(40000); 124 } 125 for(b=1;b<8;b+=5) 126 { 127 temp+=pow(2,b); 128 led=~temp; 129 delay(40000); 130 } 131 for(b=3;b<8;b+=5) 132 { 133 temp+=pow(2,b); 134 led=~temp; 135 delay(40000); 136 } 137 m=0; 138 } 139 } 140 141 void work9()//6--5个空格 142 { 143 if(m>200) 144 { 145 led=0xff; 146 temp=~led; 147 } 148 if(m>=32000) 149 { 150 for(b=0;b<7;b+=6) 151 { 152 temp+=pow(2,b); 153 led=~temp; 154 delay(40000); 155 } 156 157 for(b=4;b<8;b+=6) 158 { 159 temp+=pow(2,b); 160 led=~temp; 161 delay(40000); 162 } 163 for(b=2;b<8;b+=6) 164 { 165 temp+=pow(2,b); 166 led=~temp; 167 delay(40000); 168 } 169 m=0; 170 } 171 } 172 void work10()//7--6个空格 173 { 174 if(m>200) 175 { 176 led=0xff; 177 temp=~led; 178 } 179 if(m>=32000) 180 { 181 for(b=0;b<=7;b+=7) 182 { 183 temp+=pow(2,b); 184 led=~temp; 185 delay(40000); 186 } 187 for(b=6;b>0;b--) 188 { 189 temp+=pow(2,b); 190 led=~temp; 191 delay(40000); 192 } 193 m=0; 194 } 195 } 196 197 void work11()//8--衍生物 198 { 199 led=0XFF; 200 for(j=7;j>0;j--) 201 { 202 led=led-pow(2,j); 203 delay(10000); 204 } 205 } 206 207 void work12()//9--7个空格 208 { 209 led=0xfe; 210 } 211 212 void work13()//10--8个空格 213 { 214 if(m>200) 215 { 216 led=0xff; 217 temp=~led; 218 } 219 if(m>=32000) 220 { 221 for(b=0;b<=7;b++) 222 { 223 temp+=pow(2,b); 224 led=~temp; 225 delay(40000); 226 } 227 m=0; 228 } 229 } 230 231 void work14()//11--9个空格 232 { 233 if(m>200) 234 { 235 led=0xff; 236 temp=~led; 237 } 238 if(m>=32000) 239 { 240 for(b=7;b>=0;b--) 241 { 242 temp+=pow(2,b); 243 led=~temp; 244 delay(40000); 245 } 246 m=0; 247 } 248 } 249 250 void work15()//12----10个空格时:衍生物 251 { 252 if(m>200) 253 { 254 led=0xff; 255 temp=~led; 256 } 257 if(m>=32000) 258 { 259 for(b=0;b<7;b+=3) 260 { 261 temp+=pow(2,b); 262 led=~temp; 263 delay(40000); 264 } 265 266 for(b=1;b<8;b+=3) 267 { 268 temp+=pow(2,b); 269 led=~temp; 270 delay(40000); 271 } 272 for(b=2;b<8;b+=3) 273 { 274 temp+=pow(2,b); 275 led=~temp; 276 delay(40000); 277 } 278 m=0; 279 } 280 } 281 282 void work16()//13:衍生物 283 { 284 if(m>200) 285 { 286 led=0xff; 287 temp=~led; 288 } 289 if(m>=32000) 290 { 291 for(b=0;b<7;b+=2) 292 { 293 temp+=pow(2,b); 294 led=~temp; 295 delay(40000); 296 } 297 m=0; 298 } 299 } 300 301 void work17()//14 302 { 303 led=0x00; 304 } 305 306 void work18()//15 307 { 308 309 } 310 311 void work19()//16 312 { 313 314 }
随后放进main.c的代码中引用它们
//main.c #include <reg52.h> #include <intrins.h> #include <math.h> #include "qiyu.h" #include "dulianjian.h" #include "juzhenganjian.h" void main() { ini();//初始化 while(1)//闭环 { while(TF0==0);//启动主循环 TL0=0x9C; TH0=0xFF; TF0=0; keyscan(); // 键扫描 KeyScan1(); m = m+1; switch(msta) { case 1: work0(); //工作状态0 break; case 2: work1();// 工作状态1 break; case 3: work2(); //工作状态2 break; case 4: work3(); break; default: break; } switch(val) { case 1: work4(); //工作状态0 break; case 2: work5();// 工作状态1 break; case 3: work6(); //工作状态2 break; case 4: work7(); break; case 5: work8(); break; case 6: work9(); break; case 7: work10(); break; case 8: work11(); break; case 9: work12(); break; case 10: work13(); break; case 11: work14(); break; case 12: work15(); break; case 13: work16(); break; case 14: work17(); break; case 15: work18(); break; case 16: work19(); break; default: break; } } }
------------恢复内容结束------------