基于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;
                 }
         }
}

------------恢复内容结束------------

原文地址:https://www.cnblogs.com/action0/p/12668897.html

时间: 2024-10-14 18:33:23

基于51单片机的独立按键和矩阵按键用法的相关文章

基于51单片机的万年历(算法实现)

基于51单片机的万年历,用到了单片机独立键盘.数码管.LED灯模块实现. 想要简单还是DS1302好用. 1 /************************************************** 2 3 作者:纟彖氵戋 博客:http://www.cnblogs.com/yllinux/ 4 5 时间:2017年6月7日 6 7 目标:利用单片机独立键盘.数码管.LED灯模块实现万年历(算法实现) 8 9 ************************************

[原创]基于51单片机的红外遥控课程设计

[注]: 一眨眼,大学接近尾声,具有找工作需要,所以把大学做的电子设计“劣作”放上来.希望考研失意,还能赶上“好工作”的春招班车.如果大伙有什么工作推荐也可以联系我哦,因为一年考研少接触了这方面,所以难免有些生疏.但请相信我!给我机会我会很认真学的! 邮箱:[email protected] 转载请注明出处呀! 基于51单片机的红外遥控课程设计 目录 第一章 设计简介... 3 第二章 系统方案... 3 一.设计方案对比... 3 二.方案设计... 4 第三章 硬件设计... 5 一.红外遥

电子时钟万年历+51单片机+1602液晶屏+DS1302+DS18B20+按键

这次课程设计要完成的是制作一个基于51单片机的电子时钟的万年历(protues仿真),需要用到1602液晶屏+DS1302+DS18B20+按键等模块.各个的模块就不在一一介绍,直接讲解这个系统的功能,首先是四个按键,第一个按键是选中需要修改时间位置,在按一次选中下一个,依次类推,第二个按键是对数值进行加一,第三个按键对数值进行减一,第四个按键确认. 先放仿真图 然后是代码: main.c #include <REG52.H> #include <intrins.h> #defin

基于51单片机DS18B20测温LCD1602显示可设时设温调时的项目

一.前言 1.基于51单片机DS18B20测温LCD1602显示可设时设温调时的项目包括用Keil软件编写单片机C语言程序和用Proteus软件仿真单片机外围电路 2.基于51单片机DS18B20测温LCD1602显示可设时设温调时的项目构思 (1).声明程序变量思维导图 (2).程序子函数思维导图 (3).程序主函数思维导图 二.基于51单片机DS18B20测温LCD1602显示可设时设温调时的项目的Keil软件编写的单片机C语言程序 1 #include<reg52.h>//声明51单片机

基于51单片机的12864驱动

/**************dis_12864.h***************/ #include <reg52.h> #ifndef __DIS_12864_H__ #define __DIS_12864_H__ #define uchar unsigned char #define uint  unsigned int /*12864端口定义*/ #define LCD_data  P0             //数据口 sbit LCD_RS  =  P1^0;          

基于51单片机的温度控制系统毕设

分享一下单片机毕设课程计参考资料33个,献给大四的朋友,毕业设计就不用愁了,如果有什么不懂的地方可以加群大家一起交流:813238832资料下载的地址:https://bbs.usoftchina.com/thread-208012-1-1.html 1.CDMA通信系统中的接入信道部分进行仿真与分析2.USB接口设计3.毕业设计(论文)OFDM通信系统基带数据4.电气工程系毕业设计开题报告5.电信运营商收入保障系统设计与实现6.基于51单片机的16×16点阵(滚动显示)7.基于51单片机的LE

51单片机:独立按键与矩阵按键控制数码管

一,独立按键注意一下几点 >按下的时候,电压被拉低,所以IO口要传低电平( 0x0 ) >按下的时候要消除抖动 ( 延时10ms ),在判断,是否还是低电平,再做业务处理 下面这段程序,就是通过一个独立按键连接到p1口,控制静态数码管的 一段 进行亮和灭的切换. #include <reg52.h> sbit key_control = P1^0; sbit led = P0^0; typedef unsigned char u8; typedef unsigned int u16

单片机独立按键与矩阵按键

独立按键 首先既然是检测输入,对于当然要使能上拉电阻,来检测变化.因为除了P0口外,P2,P3,P4都是内置上拉电阻的准双向IO口,作为输入前需要拉为高电平. 当有按键按下,致使单片机的某个引脚接地,变为低电平时,我们就认为这个按键按下了.当按键松开后,由于输入不会锁存,所以此时拉高的引脚回归到高电平. 独立按键的内部原理. 独立按键的4个引脚中,两两为一组.每一组的2个引脚是连在一起的,当按键按键时,2个组又连接了,也就是4个脚都连接一起了. 按键的很重要注意点就是消除抖动,消抖.因为人按下按

基于51单片机的无线测温系统

本51项目基于STC89C52MCU,温度传感器为DS18B20,显示模块用的是LCD1602,无线模块用的是Nodemcu. 项目用到的编程语言:C,C++,Lua. 实现思路是这样,DS18B20测温,然后数据串行传送给51单片机,然后51通过串口将数据传送给Nodemcu,Nodemcu通过其WIFI模块将数据发送给上位机,上位机上的程序是用Qt编写的GUI.(这里无线传输采用的是无连接的UDP协议) 1.DS18B20温度测量模块 DS18B20是单总线器件,所以时序要求非常严格,程序编