电工学习网

 找回密码
 立即注册

单片机最小系统电路解析

2015-1-12 10:34| 编辑:电工学习网| 查看: 32285| 评论: 2


利用这种方法,就可以避免通过直接延时按键消抖占用CPU时间,而是转化成了一种按键状态判定而非按键过程判断,我们只对当前按键的连续16ms8次状态进行判断,而不再关心它在这16ms内都做了什么事情,我们来看看这个程序怎么写。
#include 
 
sbit  KEY1 = P2^4;
sbit  KEY2 = P2^5;
sbit  KEY3 = P2^6;
sbit  KEY4 = P2^7;
 
sbit  ADDR0 = P1^0;
sbit  ADDR1 = P1^1;
sbit  ADDR2 = P1^2;
sbit  ADDR3 = P1^3;
sbit  ENLED = P1^4;
 
unsigned char code LedChar[] = {
    0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
    0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8e
};
 
bit KeySta = 1;  //当前按键状态
 
void main(void)
{
    bit backup = 1;    //按键值备份,保存前一次的值
    unsigned char counter = 0;  //计数器记录按键按下的次数
    
    //选择最右边的数码管进行显示
    P0 = LedChar[counter];
    ADDR0 = 0;
    ADDR1 = 0;
    ADDR2 = 0;
    ADDR3 = 1;
    ENLED = 0;
 
    //选中第一行按键以进行扫描
    P2 = 0xF7;
    
    //配置T0工作在模式1,定时2ms
    TMOD = 0x01;
    TH0 = 0xF8;
    TL0 = 0xCD;
    TR0 = 1;
    ET0 = 1;
    EA = 1;
 
    while(1)
    {
        if (KeySta != backup)  //当前值与前一次值不相等说明此时按键有动作
        {
            if (backup == 0)   //如果前一次的值为0,则说明当前状态是由0变为1,即按键弹起
            {
                counter++;     //计数器+1
                if (counter >= 10)
                {              //只用1个数码管显示,所以记到10就清零重新开始
                    counter = 0;
                }
                P0 = LedChar[counter];  //计数值显示到数码管上
            }
            backup = KeySta;   //更新备份为当前值,以备进行下次比较
        }
    }
}
 
void InterruptTimer0() interrupt 1
{
    static unsigned char keybuf = 0xFF;  //按键扫描缓冲区,保存一段时间内的扫描值
    
    TH0 = 0xF8;  //溢出后进入中断重新赋值
    TL0 = 0xCD;
    
    keybuf = (keybuf << 1) | KEY4;  //只取KEY4为例,缓冲区左移一位,并将当前扫描值移入最低位
    if (keybuf == 0x00)
    { //当连续8次扫描值都为0,即16ms内都只检测到按下状态时,可认为按键已按下
        KeySta = 0;       //按键状态值为按下
    }
    else if (keybuf == 0xFF)
    { //当连续8次扫描值都为1,即16ms内都只检测到弹起状态时,可认为按键已弹起
        KeySta = 1;      //按键状态值为弹起
    }
    else
    {}  //其它情况下则说明按键状态尚未稳定,则不对KeySta变量值进行更新
}
这个算法是我们在工程中经常使用按键所总结的一个比较好的方法,介绍给大家,今后都可以用这种方法消抖了。当然,按键消抖也还有其它的方法,程序实现更是多种多样,大家也可以再多考虑下其它的算法,拓展下思路。这个程序有一个新知识点,就是bit类型的变量,这个在标准C语言里边是没有的。51单片机有一种特殊的变量类型就是bit型,比如unsigned char型是定义了一个无符号的8位的数据,它占用一个字节(Byte)的内存,而bit型是1位数据,只占用1个位(bit)的内存,用法和标准C中其他的基本数据类型是一致的。它的优点就是节省内存空间,8bit型变量才相当于1char型变量所占用的空间。虽然它只有01两个值,但也已经可以表示很多东西了,比如:按键的按下和弹起、LED灯的亮和灭、三极管的导通与关断、开关的闭合与断开,联想一下已经学过的内容,它是不是能用最小的内存代价来完成很多工作呢?

看过《单片机最小系统电路解析》的人还看了以下文章:

发表评论

最新评论

引用 游客 2016-3-6 18:57
图二应该是27M无源晶振
引用 游客 2015-9-3 08:06
后面六页看不见

查看全部评论(2)

  • 实时时钟芯片DS1302
  • 8255的控制字
  • 单片机点亮led灯程序详解
  • 单片机引脚功能定义
  • 单片机数码管显示原理
  • RS485通信和Modbus协议

电工学习网 ( )

GMT+8, 2023-4-5 16:02

Powered by © 2011-2022 www.shop-samurai.com 版权所有 免责声明 不良信息举报

技术驱动未来! 电工学习网—专业电工基础知识电工技术学习网站。

栏目导航: 工控家园 | 三菱plc | 西门子plc | 欧姆龙plc | plc视频教程

返回顶部