51单片机、独立按键的认识与编程

一、基本知识

1. 按键分类与输入原理

按键按照结构原理科分为两类,一类是触点式开关按键,如机械式开关、导电橡胶式开关灯;另一类是无触点式开关按键,如电气式按键,磁感应按键等。前者造价低,后者寿命长。目前,微机系统中最常见的是触点式开关按键。

在单片机应用系统中,除了复位按键有专门的复位电路及专一的复位功能外,其他按键都是以开关状态来设置控制功能或输入数据的。当所设置的功能键或数字键按下时,计算机应用系统应完成该按键所设定的功能,键信息输入时与软件结构密切相关的过程。

对于一组键或一个键盘,总有一个接口电路与CPU相连。CPU可以采用查询或中断方式了解有无将按键输入,并检查是哪一个按键按下,将该键号送入累加器,然后通过跳转指令转入执行该键的功能程序,执行完成后再返回主程序。

2. 按键结构与特点

微机键盘通常使用机械触点式按键开关,其主要功能式把机械上的通断转换为电气上的逻辑关系。也就是说,它能提供标准的TTL逻辑电平,以便于通用数字系统的逻辑电平相容。机械式按键再按下或释放时,由于机械弹性作用的影响,通常伴随有一定的时间触点机械抖动,然后其触点才稳定下来。

图1-按键抖动

其抖动过程如图1所示,抖动时间的长短与开关的机械特性有关,一般为5-10ms。在触点抖动期间检测按键的通与断,可能导致判断出错,即按键一次按下或释放错误的被认为是多次操作,这种情况是不允许出现的。为了克服按键触点机械抖动所致的检测误判,必须采取消抖措施。按键较少时,可采用硬件消抖;按键较多式,采用软件消抖。

3. 独立按键与矩阵键盘

(1)独立按键

单片机控制系统中,如果只需要几个功能键,此时,可采用独立式按键结构。

独立按键式直接用I/O口线构成的单个按键电路,其特点式每个按键单独占用一根I/O口线,每个按键的工作不会影响其他I/O口线的状态。独立按键的典型应用如图所示。独立式按键电路配置灵活,软件结构简单,但每个按键必须占用一个I/O口线,因此,在按键较多时,I/O口线浪费较大,不宜采用。独立按键如图2所示。

图2-独立按键

独立按键的软件常采用查询式结构。先逐位查询与I/O口线的输入状态,如某一根I/O口线输入为低电平,则可确认该I/O口线所对应的按键已按下,然后,再转向该键的功能处理程序。

(2) 关于上拉电阻

单片机按键一般通过配备上拉电阻来实现输入端高低电平的切换。

图3-上拉电阻

4条输入线接到单片机的IO口上,当按键K1按下时,+5V通过电阻R1然后再通过按键K1最终进入GND形成一条通路,那么这条线路的全部电压都加到了R1这个电阻上,KeyIn1这个引脚就是个低电平。当松开按键后,线路断开,就不会有电流通过,那么KeyIn1和+5V就应该是等电位,是一个高电平。我们就可以通过KeyIn1这个IO口的高低电平来判断是否有按键按下。

三、独立按键实例编程

1.说明

以普中科技51单片机开发板为例

图4为独立按键电路图 8个按键分别对应JP5的八个引脚,所有按键统一接地,按键之间互不影响,JP5中包含上拉电阻。当按键松开时,对应引脚输入1;当按键按下时,对应引脚输入0。

图5为流水灯电路图 8个LED灯接地共阴,当引脚输出1时,LED灯亮;当引脚输出0时,LED灯灭。

图4-独立按键
图5-流水灯

2.代码实现

(1) 无消抖的8个引脚控制8个LED灯
#include <reg51.h>
#define Key P0    //P0接独立按键电路引脚
#define Led P2    //P2接LED流水灯电路引脚
int main()
{
    unsigned char i;
    P2=0x00;    //初始化流水灯全灭
    
    while(1)
    {
        //动态扫描八个按键
        for(i=0;i<8;i++)
        {
            if( 0 == (Key&(1<<i)) ) Led|=1<<i;    //按键按下
            else Led&=~(1<<i);    //按键弹起
        }
    }
    return 0;
}

(2) 通过按键控制单个数码管计数并作消抖处理

具体要求:
  • 数码管初始化为0,按下按键增加对应的数,例如按下Key1则增加1,按下Key2则增加2
  • Key8用于清零
  • 超出9时,要做越界处理
  • 消抖
  • 按键抬起检测 按一次只加一次
//printNum.h头文件
#define Led P2     //P2口控制单个数码管
#define state 1    //此处是共阳数码管 所以置1
void printNum(int i)
{
    //0123456789AbCDEF
    unsigned char num[16]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
    if(state==1) Led=num[i];        //Common yang
    else Led=~num[i];       //Common yin
}
void delay_ms(unsigned int i)
{
    unsigned int temp=i*100;
    while(temp--) ;
}
#include <reg51.h>
#include "printNum.h"
#define Key P0

int main()
{
    unsigned char i;
    unsigned char count=0;
    while(1)
    {
        printNum(count);
        for(i=0;i<7;i++)    //动态检测8个按键
        {
            if( 0==(Key&(1<<i)) )       //判断按键是否按下 
            {
                delay_ms(150);          //消抖
                if( 0==(Key&(1<<i)) )   
                    count+=i+1;         //累加上对应的数
                
                if(count>9) count%=10;  //防止越界
                
                printNum(count);        //实时更新数字
                while( !(Key&(1<<i)) ) ;  //按键抬起检测
            }
        }   
        if( 0 == (Key&(1<<7))) count=0;  //最后一个键用于清零
    }
}

(3)通过按键控制多个数码管计数

具体要求:
  • 功能:数码管初始化为0,按下按键增加对应的数,例如按下Key1则增加1,按下Key2则增加2……但是按下Key8需清零
  • 使用38译码器对COM口进行控制 节省I/O口
  • P1的三个引脚控制38译码器,其他引脚上的值不允许被改动
  • P2控制数码管段码端的给值
  • P0控制检测按键的输入
  • 按键要消抖 抬起要检测 边界要检测
#define Led P2
#define state 0
void printNum(int i)
{
    //0123456789AbCDEF
    unsigned char num[16]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
    if(state==1) Led=num[i];        //Common yang
    else Led=~num[i];       //Common yin
}
void delay_ms(unsigned int i)
{
    unsigned int temp=i*100;
    while(temp--) ;
}
#include <reg51.h>
#include "printNum.h"
#define Key P0
#define LED_PLACE P1

unsigned char screenNum[8]={0,0,0,0,0,0,0,0};

int main()
{
    
    unsigned char i;
    unsigned char j;
    unsigned long count=0;
    unsigned long temp=0;
    while(1)
    {
        LED_PLACE &= 0xf8;  //Clear PLACE.0-2
        if(count>99999999) count=0;     //deal with the range
        temp=count;
        for(i=0;i<8;i++)    //transfer long to arr
        {
            screenNum[7-i]=temp%10;
            temp/=10;
        }       
        for(i=0;i<8;i++)    //give nums to screen
        {
            printNum(screenNum[i]);
            j=100; 
            while(j--) ;
            Led = 0x0;      //remove the double image
            LED_PLACE+=1;   //control the place
        }
        
        for(i=0;i<7;i++)      //scan the press keys
        {
            if( 0==(Key&(1<<i)) ) 
            {
                delay_ms(150);
                if( 0==(Key&(1<<i)) )   
                    count+=i+1;
                
                while( !(Key&(1<<i)) ) ;
            }
        }   
        if( 0 == (Key&(1<<7))) count=0;    //key8 to clear all
        
    }
}

不足:按下按键时,数码管全部熄灭,这是由于掉进按键检测的死循环中,无法扫描动态数码管。改进方法,等待学习中断和定时器。

实验现象

更新:

(3) 通过中断来控制按钮增加数码管显示

连线方式:

  • P2接J12控制动态数码管段码端
  • P1.0-2接J6-三八译码器 控制动态数码管COM端
  • P3.2接JP5-K1 INT0控制按键1
#define Led P2
#define state 0
void printNum(int i)
{
    //0123456789AbCDEF
    unsigned char num[16]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
    if(state==1) Led=num[i];        //Common yang
    else Led=~num[i];       //Common yin
}
void delay_ms(unsigned int i)
{
    unsigned int temp=i*100;
    while(temp--) ;
}
#include <reg51.h>
#include "printNum.h"
#define LED_PLACE P1

unsigned char screenNum[8]={0,0,0,0,0,0,0,0};
unsigned long count=0;

void exint0() interrupt 0   // P3.2
{
    count++;
}

void initDevice()
{
    IT0=1;
    EX0=1;
    EA=1;
}
int main()
{
    
    unsigned char i;
    unsigned char j;
    
    unsigned long temp=0;
    
    initDevice();
    
    while(1)
    {
        LED_PLACE &= 0xf8;  //Clear PLACE.0-2
        if(count>99999999) count=0;     //deal with the range of dital
        temp=count;
        for(i=0;i<8;i++)    //transfer long to arr
        {
            screenNum[7-i]=temp%10;
            temp/=10;
        }       
        for(i=0;i<8;i++)    //give nums to screen
        {
            printNum(screenNum[i]);
            j=100; 
            while(j--) ;
            Led = 0x0;      //remove the double image
            LED_PLACE+=1;   //control the place
        }
    }
}
实验接线

参考资料:

http://www.51hei.com/bbs/dpj-19896-1.html ——单片机论坛
http://blog.csdn.net/fanyuqa/article/details/48036529 ——CSDN fanyuqa博客

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容

  • 前言 抛开工作,以电子爱好者的身份,单片机玩多了都会想着在单片机的外围设备玩出一些花样来。这其中首先想到的就是“升...
    淡定的H羊阅读 62,400评论 16 56
  • Arduino Due有14个数字I/O,6个模拟I/O,一个复位开关,一个ICSP下载口,7-12v电源供电。 ...
    麦牛2013阅读 3,180评论 0 8
  • 1、嵌入式系统的定义 (1)定义:以应用为中心,以计算机技术为基础,软硬件可裁剪,适应应用系统对功能、可靠性、成本...
    荣卓然阅读 1,745评论 0 5
  • 什么是嵌入式 IEEE(Institute of Electrical and Electronics Engin...
    Leon_Geo阅读 3,606评论 1 20
  • 一直盼着会下雨、淅淅沥沥、点点击落、本来、应当是很有情怀的、可想到雨渍花落、红散香凋、就有几份凄迷、更有几份感伤了...
    陈琳琳阅读 150评论 0 0