51单片机4X4矩阵键盘驱动与应用程序(C语言)

发布者:ww313618最新更新时间:2016-09-08 来源: eefocus关键字:51单片机  矩阵键盘 手机看文章 扫描二维码
随时随地手机看文章
1、keydrive.c
#include
#include
/*
程序功能:  本程序用于测试4X4矩阵键盘驱动;
 
程序算法:
每2MS检测一次按键的状态,若连续8次检测都为相同,
说明现在是一个稳定的状态,否就是干扰不与理采 ;
按键有三种状态:1、按下 2、松开 3、干扰或抖动;
其中前两种都是稳态,后一种为抖动。
接着若判断按键的状态是否改变,
若改变--》判断原来的状态是否为松开---是--说明
           现在按键为按下,那么就把键值算出来;---返回0;
        若改变--》判断原来的状态是否为松开---否--说明
            现在按键为松开,那么就把键值返回;
 
*/
 
/*
矩阵键盘硬件引脚连接关系
*/
/*
 keyin4 ----- P2^7;
 keyin3 -----  P2^6;
keyin2 -----  P2^5;
 keyin1 -----  P2^4;
keyout1 -----  P2^3;
 keyout2 -----  P2^2;
 keyout3 -----  P2^1;
 keyout4 -----  P2^0; 
*/
 
/*
定义外部变量
*///lcd1602显示数组
unsigned char  keynum[]="keynum:k   ";
 
//键值查询数组
                         //k1,k2,k3,k4,k5,k6,k7,k8,
unsigned char code keytabel[]={0xe7,0xd7,0xb7,0x77,0xeb,0xdb,0xbb,0x7b,
 //k9,k10,k11,k12,k13,k14,k15,k16,
     0xed,0xdd,0xbd,0x7d,0xee,0xde,0xbe,0x7e};
 
unsigned char status1; 
 
/*
外部函数声明
*/ 
extern bit Flag2Ms;  //2ms到标志  键盘驱动中要用到这个外部变量
extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
 
/*
函数功能:N毫秒延时
*/
void DelayMs(unsigned int ms)
{
unsigned int i,j;
for(i=0;i
for(j=0;j<113;j++);
 
}
/*
函数功能:矩阵键盘扫描
          在该函数只是判断按键的状态,即按下还是弹起;设置按键状态标置位;
 
算法:采用状态机的机制
 
*/
void keyscan()
{
static unsigned char num1,keyon_num,num2; //设置为局部静态变量
/*
num1---保存P2口状态
num2---保存次数 ,每次时间为2ms;
keyon_num----保存按下次数  
*/
if(Flag2Ms==1)  //2MS时间到
{
Flag2Ms=0;
num2++;
P2 = 0xf0;
   num1=P2;
    if(num1!=0xf0)
      keyon_num++;
if(num2==8) //若连续8次检测都为同一个状态说明按键是一个稳定的状态;
{ //否则就是一个干扰,或者说是一次抖动; 时间为16MS;
num2=0;
if(keyon_num==8)
   status1=1;  //按键已按下
else if(keyon_num==0)
   status1=0;  //按键已弹起
else 
   status1=2;  //按键无效,是干扰
keyon_num=0;    // 一定要复位该值;
}
 
/*
函数功能:获取键值
算法: 先判断按键的状态是否改变,若改变--》判断原来的状态是否为松开---是--说明
      现在按键为按下,那么就把键值算出来;---返回0;
   若改变--》判断原来的状态是否为松开---否--说明
      现在按键为松开,那么就把键值返回;
   若按键的状态没有变化,就返回0;
*/
unsigned char getkey()
{
static unsigned char backstatus=0;  //原来按键的状态,初始设为0,即松开状态;
static unsigned char temp,num3; //定义两个局部静态变量;
if((backstatus!=status1)&&(status1!=2))
{
if(backstatus==0) //若原来状态为松开,就求出键值,但返回0;
{
  P2=0xf0;
  num3=P2;
  temp=num3;
  P2 = 0x0f;
  num3=P2; 
  temp =temp|num3;
  backstatus=status1;   //备份按键状态
  return 0;
}
   backstatus=0;  //若原来状态为按下,说明现在为松开
   return temp;  //返回键值;
}
return 0;    //若状态没有改变,则返回0;
 
 
 
 /*
 函数功能:按键功能处理函数
           在该函数中,收到按键后,就把相关的键值通过LCD1602显示;
   并通过串口显示:keynum:kxx” xx为按k1-k16; 
 */
void key_functoin(unsigned char keynum1)
{
unsigned char i;
 if(keynum1!=0)   //有键按下并松手
{   
for(i=0;i<16;i++)  // 循环查表,获取按键编号
   {
    if(keynum1==keytabel[i])
break;
   }   
keynum[8]=(i+1)/10+0x30;  //把编号转换成字符放到显示数 组中;
keynum[9]=(i+1)%10+0x30;
TI=1; //把按键值发送到串口; 
printf("%s",keynum);    //在串口上显示“keynum:kxx” xx为按k1-k16;
while(TI!=1);    //每次发送完毕,要手动清TI标志; 
TI=0;
LcdShowStr(0,0,keynum); //1602显示按键编号
 
 
2、keytest.c
#include
#include
/*
程序功能:  本程序用于测试4X4矩阵键盘;
当按下按键后,在LCD1602上显示出按下的键号如:K1 K2.... K16;
同时把键值通过串口发送到口上显示; 
在串口上显示“keynum:kxx” xx为按k1-k16;
程序用到的资源:1、定时器T0、T1  2、P2口 3、LCD1602 4、串行口  
程序作者:王庐山 
程序编制日期:2015年3月13日
地址:湖北工业职业技术学院电子工程系电子创新中心
注意:在本程序中,把键盘相关的处理函数都写在键盘驱动中;
      使用模块化编程;本程序在金沙滩开发板上测试通过。
*/
 
 
//宏定义
#define TH0_NUM 1000  //便于程序的移植;
#define TL0_NUM 1000
 
bit Flag2Ms;  //2ms到标志
unsigned char code demo[]="key_4x4 " ;
unsigned char code demo1[]="scaning..." ;
/*
外部函数声明
*/ 
extern void InitLcd1602();
extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
extern void ConfigUART(unsigned int baud);
extern void DelayMs(unsigned int ms);
extern void keyscan();
extern unsigned char getkey();
extern void key_functoin(unsigned char keynum1);
 
//内部函数声明
void InitTimer0();
 
 
/*
主程序
*/
void main()
{
InitTimer0();  //定时0初始化
ConfigUART(9600);  //串口初始化
InitLcd1602();  //1602初始化
LcdShowStr(0,0,demo); // 显示字符串
LcdShowStr(0,1,demo1); // 显示字符串
while(1)
{
keyscan(); //按键扫描
key_functoin(getkey());//根据获取的键,进行相关的处理;
}
}
 
/*
函数功能:定时器0初始化,设定每1MS中断一次
*/
 
void InitTimer0()
{
TMOD &=0xf0;  //这种操作模式,不会破坏寄存器的其它设置;
TMOD |=0x01;    //方式1,16位定时器
TH0/=(65536-TH0_NUM)/256;
TL0=(65536-TL0_NUM)%256;
EA=1;
ET0=1;
TR0=1; 
}
/*
函数功能:定时器0中断服务程序
*/
void Timer0_Interrupt()  interrupt 1
{
  static unsigned char i;
TH0=(65536-TH0_NUM)/256;
TL0=(65536-TL0_NUM)%256;
i++;
if(i>2)
{
i=0;
Flag2Ms=1;
}
}

关键字:51单片机  矩阵键盘 引用地址:51单片机4X4矩阵键盘驱动与应用程序(C语言)

上一篇:51单片机长按键测试程序
下一篇:直流电机正反转及调速控制

推荐阅读最新更新时间:2024-03-16 15:08

嵌入式学习笔记1——51单片机之预备知识
1. TTL电平:高+5V(有电) 低0V(没电)。 2. RS232电平: 计算机串口 高-12V 低+12V, 所以单片机与计算机通信时要加电平转换芯片max232。 3. 概念:C51就是开发51单片机的C语言。 4. C51的数据类型扩展定义(即除了C中int 、char等之外): (1) sfr:特殊功能寄存器声明(一般情况编程时用不到) (2) sfr16:sfr的16位数据声明(一般情况编程时用不到) (3) sbit: 特殊功能位声明 (4) bit: 位变量声明 例:sfr SCON = 0x98; sfr16 T2 = 0xCC; sbit OV =PSW^2; sbit l
[单片机]
51单片机软件抗干扰的技术误区
单片机 中存在这样一种广泛流传的误解:在MCS-51系列单片机中,只要用指令使程序从起始地址开始执行,就可以复位单片机,摆脱干扰。通过一个简单的实验,揭示了软件复位的可靠方法。   有的单片机(如8098)有专门的复位指令,某些增强型MCS-51系统单片机虽然没有复位指令,但片内集成了WATCHDOG电路,故抗干扰也不成问题。而普及型MCS-51系列单片机(如8031和8032)既然无复位指令,又不带硬件WATCHDOS,如果没有外接硬件WATCHDOG电路,就必须采用软件抗干扰技术。常用的软件抗干扰技术有:软件陷阱、指令冗余、软件WATCHDOG等,它们的作用是在系统受干扰时能及时发现,再用软件的方法使系统复位。所谓软件复位
[单片机]
51单片机-LED部分(2)
8个发光管由上至下间隔1s流动,其中每个管亮500ms,灭500ms,亮时蜂鸣器响,灭时关闭蜂鸣器,一直重复下去。 C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include #include #define uchar unsigned char uchar x, temp; sbit buzzer = P2 ^ 3; void delayms(uchar z); void main() { temp = 0xfe; while(1) {
[单片机]
一种基于51单片机控制的数字视频混合器
近几年,数字电视技术发展很快,数字视频混合器可以将两路或多数数字视频信号按照一定的算法混合成一路或多路数字视频信号。作为数字视频信号的基本处理单元,该混合器在数字电视节目的编辑制作和播控传输系统中具有举足轻重的作用。 本文介绍的基于单片机控制的数字视频键控混合器具有以下特点:内含两级串联的键控混合器,可以在主信号中键两入两路附加数字信号,如时钟台标或各种字幕标识;可以远程遥控,也可现场按键控制;可以随时更新和保存系统配置,改变系统功能和技术参数;该系统稳定可靠,对掉电、死机等异常现象有自复位能力。 整个系统包括硬件和软件两部分,硬件包括数字混合部分和单片机控制部分。 1 数字混合部分 输入的数字信号有背景信号、键控信号和填
[单片机]
51单片机多机通信电路图及C语言程序
多机通信电路图 此处,U1作为主机,U2为从机1,U3为从机2。 多机通信C语言程序 (1)主机程序 #include #include #define _SUCC_ 0x0f//数据传送成功 #define _ERR_ 0xf0//数据传送失败 unsigned charTable ={0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39}; unsigned char Buff ; //数据缓冲区 unsigned char temp=0xff; sbit KEY1=P1^6; sbit KEY2=P1^7; //unsigned char addr; //延时1ms函数 void de
[单片机]
<font color='red'>51单片机</font>多机通信电路图及C语言程序
51单片机之定时器/计数器应用实例(方式0、1、2、3)
硬件:STC89C52RC 开发工具:Keil uVision4 对于刚接触单片机的同学来说可能会对定时器/计数器的应用很蒙圈,特别是初值的计算和各种定时方式的选择。下面希望能给你带来一个清晰的思路。 定时器:一般用于软件计时,给定时器设置一个时间,时间到了系统停止当前的工作跳转到事先定义好的定时器中断函数里,函数里可以做一些周期性的事情。 计数器:一般用于检测外来脉冲信号,给计数器设置一个次数,次数到了系统停止当前的工作跳转到事先定义好的计数器中断函数里,函数里做相应的事情。 先说一下相关的寄存器,也可以直接跳过,看后面的实例分析。 配置定时器或者计数器就是对相应的寄存器进行赋值,下面是相关的寄存器描述:
[单片机]
<font color='red'>51单片机</font>之定时器/计数器应用实例(方式0、1、2、3)
8051单片机的寄存器是什么样的
CPU中使用寄存器来临时存储信息,这些信息可以是要处理的数据,也可以是指向要获取的数据的地址。在8051单片机中,有一种数据类型是8位,从MSB(最高有效位)D7到LSB(最低有效位)D0。对于8 位数据类型,任何大于 8 位的数据类型都必须在处理之前分成 8 位块。 8051中使用最广泛的寄存器是 A(累加器)、B、R0-R7、DPTR(数据指针)和 PC(程序计数器)。所有这些寄存器都是 8 位的,除了 DPTR和 PC。 一、8051中的存储寄存器 我们将在这里讨论以下类型的存储寄存器: 1.累加器; 2.寄存器; 3.B寄存器; 4.数据指针 (DPTR); 5.程序计数器 (PC); 6.堆栈指针 (SP)。 (
[单片机]
80<font color='red'>51单片机</font>的寄存器是什么样的
基于8051单片机和SC1128芯片实现病房呼叫系统的设计
传统的病房呼叫系统普遍采用有线式,不仅布线安装繁琐、维护不便、利用率低,而且实时性差。虽然无线式呼叫系统没有布线问题,但它的可靠性差,而且无线电波会干扰其它医疗仪器设备,目前大多数医院不采用无线呼叫系统。 随着电力载波技术的发展,应用低压电力线作为传输媒质,采用扩频、数字编码、单片机控制等技术实现病房呼叫已成为可能。本文运用电力载波技术设计了一种病房呼叫系统。 1 病房呼叫系统的基本要求 临床求助呼叫是传送临床信息的重要手段,病房呼叫系统是病人请求值班医生或护士进行诊断或护理的紧急呼叫工具,可将病人的请求快速传送给值班医生或护士, 并在值班室的监控中心电脑上留下准确完整的记录,是提高医院和病室护理水平的必备设备之一。呼叫系
[单片机]
基于80<font color='red'>51单片机</font>和SC1128芯片实现病房呼叫系统的设计
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved