找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2963|回复: 2
打印 上一主题 下一主题
收起左侧

51单片机的按键和数码管思路

[复制链接]
跳转到指定楼层
楼主
ID:142320 发表于 2017-8-1 13:44 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
大家好,这段时间又重新在学习51单片机,单片机这东东真的是要一直学,一直做项目才行,之前做按键和数码管显示的时候,实际也只是了解了一点皮毛,再次深入学习后才体会到,要搞好这东东,真的要不同的思路去扩展。先简单说一下我的开发板硬件,数码管采用两片74HC573 来实现,段选P26,位选P27,采用共阳数码管,在P0口送对应数来实现数码管的显示;
四个独立按键P32,P33,P34,P35,LED发光管有八个,P10--P17,发光管在输出低电平时点亮,

那么关于按键和数码管的显示,网上也有很多例子了。
第一类:关于延时的程序,如果采用延时消抖动,那么有可能按下后显示不灵等,那么我建议用LED的显示来抵消这个延时的做法,但一般项目的开法都不会用延时来消抖,在这里只是提供一个思路。
sbit KEY1 = P3^2;   //假定P3^2代表KEY1键,按下为0
if(!KEY1 )  //表明有键按下
{
   // Delayms(10);   一般情况下我们都用Delay  10ms 来消抖
  为了程序的效率,和显示等,我们这里可以用数码管显示的时间来抵消,
  ledscan();    //数码管一般也以10MS 100HZ无闪烁设计的。
   if(!KEY1 )   
   {
         while(!KEY1)       //释放消抖
        {
                KEY1 = 1;       //先输出高电平
                ledscan();       //在等待的这个时间来显示
        }
       // fun1();     这里是我们按键按下的功能程序
   }
}


第二类,我们直接以10MS定时器查询来实现,也可以采用定时器2MS,多读数几次,比如8次以上都是,则实现按键确认
unsigned char KeySta[1] =    //该定义属于全局变量
{
  0xff
};
//下面定义在定时器查询程序里面
static unsigned char Keybuf[1] =  //按键扫描缓冲区,保存一段时间内的扫描值
   {
          0xFF
   };
   Keybuf[0] = (Keybuf[0]<< 1) | KEY1;   //KEY1 循环8次
   if( Keybuf[0] ==0)  //连续8次都是0
  {
     KeySta[0] =  0 ;      //0表示有按下
  }
   else if( Keybuf[0] ==1)   ///连续8次都是1
  {
     KeySta[0] =  1 ;   
  }
  else   //未稳定状态,则不管他,这里是为了程序的完整性
  {


  }
}


第三类:采用状态机的写法
状态机也是按10MS定时中断去确认按键状态,以使程序简化
unsigned char keycode = 0;           //这个是全局变量,表示按键代码
//下面在定时中断10MS到的函数中实现
static unsigned char Key_state = 0;
unsigned char Keypress = 0xff;        //未按下为0xff;
P3 = 0xff;
Keypress &= P3


switch(Key_state )
  {
    case 0:
                if(Keypress!=0xff)//表示有键按下
                {
                      Key_state  = 1;//进入S1
                 }
    break;
   case 1:
              if(Keypress!=0xff)      //表示确认有键按下
               {
                     Key_state  = 2;//进入S1
                     if( !KEY )
                     {
                             keycode = 0x01;   //假如说我们KEY1按下的代码是0x01
                     }
              }
              else
             {
                     Key_state = 0;  //误动作,返回0
             }
   break;
  case 2:
              if(Keypress==0xff)      //释放
             {
                    switch(keycode)
                    {
                         case 0x01:    //按键KEY1的功能函数
                         break;
                         default:
                         break;
                     }
                    Key_state = 0; //如果有长按,则可以进入长按的状态等等。
              }
            else   //等待释放
             {
                    Key_state = 2;
             }
     default:
     break;
  }
当然为了减轻定时中断的负担,关于按键功能的程序可在主程序中去执行,在此不再详述。

第四次:新型的TRG的写法
核心算法如下:
unsigned char Trg;
unsigned char Cont;
void KeyRead( void )
{
    unsigned char ReadData =P3^0xff;            // 1
    Trg = ReadData & (ReadData ^Cont);       // 2
    Cont = ReadData;                                          // 3
}
在定时中断函数里每10MS去检测一次按键情况,并执行。



评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:222844 发表于 2017-8-1 16:44 | 只看该作者
学习一下,感觉不错

评分

参与人数 1黑币 +40 收起 理由
admin + 40 赞一个!

查看全部评分

回复

使用道具 举报

板凳
ID:223861 发表于 2017-8-1 20:04 | 只看该作者
学习一下,感觉不错
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表