切换到宽版
  • 1761阅读
  • 17回复

[C51]关于15F104W的键盘扫描 [复制链接]

上一主题 下一主题
离线rock666
 

发帖
106
M币
212
专家
3
粉丝
9
只看楼主 倒序阅读 我要置顶 楼主  发表于: 2017-04-07
折腾了好久,看了好多例程都不成功,由于15F104W的IO只有6个(键盘扫描部分和例程有很大区别),
其实想要的功能很简单:2个按钮控制一个led输出,按下S1,led点亮;按下S2,led熄灭(由于功能特殊,不能用一个按钮循环控制led亮灭),我的程序贴出来,请高手赐教,谢谢了

#include<reg51.h>    //  包含 51单片机寄存器定义的头文件
sbit S1=P3^2;        //  
sbit S2=P3^1;
sbit led=P3^3;       //将 LED0 位定义为 P3.3引脚
unsigned char keyval;
/*************************************************
函数功能:延时约 30ms
**************************************************/
void delay(void)
{
   unsigned char i,j;
  for(i=0;i<100;i++)
    for(j=0;j<100;j++)
      ;
}
/*************************************************
函数功能:关闭所有 LED
**************************************************/
void stop(void)
{
led=1;
}
/*************************************************
函数功能:闪烁点亮 LED
**************************************************/
void flash(void)
{
  led=0;
}

/*************************************************
函数功能:键盘扫描子程序
**************************************************/
void key_scan(void)
{
if((P3&0x9c)!=0x9c)         //第一次检测到有键按下
         {
            delay30ms();   //延时 20ms再去检测
          if(S1==0)      //按键S1 被按下
           keyval=1;
            if(S2==0)      //按键S2 被按下
           keyval=2;
         }      
}

/*************************************************
函数功能:主函数
**************************************************/
void main(void)  //主函数
{
    keyval=0;              //按键值初始化为 0,什么也不做
   while(1)
     {
       key_scan();  
      switch(keyval)
      {
            case 1:stop();
                   break;
            case 2: flash();
                   break;
           }
        
   }
}
离线rock666

发帖
106
M币
212
专家
3
粉丝
9
只看该作者 1楼 发表于: 2017-04-07
我觉得问题很大程度出在键盘扫描部分,但是初学期间,实在不知问题点
离线xinhoujue

发帖
2538
M币
3438
专家
3
粉丝
37
只看该作者 2楼 发表于: 2017-04-07
多明显呀,逻辑错误!
离线djliubo

发帖
1110
M币
1419
专家
5
粉丝
19
只看该作者 3楼 发表于: 2017-04-07
if((P3&0x9c)!=0x9c)  0x9c=10011100
这语句是判断第3,4,5,8pin是否变化?

我没看过15F的pin地址,不确定这么理解对不对。
不过改成if((P3&0x03)!=0x03) 试试看?
离线rock666

发帖
106
M币
212
专家
3
粉丝
9
只看该作者 4楼 发表于: 2017-04-07
djliuboif((P3&0x9c)!=0x9c)  0x9c=10011100<br>这语句是判断第3,4,5,8pin是否变化?<br><br>我没看过15F的pin地址,不确定这么理解对不对。<br>不过改成if((P3&0x03)!=0x03) 试试看?<br>
      
谢谢你的指导,我马上实验一下
离线rock666

发帖
106
M币
212
专家
3
粉丝
9
只看该作者 5楼 发表于: 2017-04-07
还是不行啊,
15F104W,一共6个IO(P3^0~P3^5),现在P3^2和P3^3接按钮,P3^4接led。想实现的功能是:
上电时led关闭,按下P3^2,led亮起;按下P3^3,led熄灭;
离线wulin

发帖
429
M币
659
专家
5
粉丝
16
只看该作者 6楼 发表于: 2017-04-07
两个独立按键控制一个LED亮灭,为什么写这么复杂?I/O口是可以直接位操作的。在你原程序基础上删改。注:15F104W 是1T单片机

#include<reg51.h>    //  包含 51单片机寄存器定义的头文件
sbit S1=P3^2;        //  
sbit S2=P3^1;
sbit led=P3^3;       //将 LED0 位定义为 P3.3引脚
/*--------------------------------------
  1ms延时子程序(11.0592MHz 1T单片机)
---------------------------------------*/
void delay1ms(unsigned int k)    
{
    unsigned int i,j;
    for(i=k;i>0;i--)
        for(j=1150;j>0;j--);    //    12T单片机j=114
}

/***************************************
函数功能:主函数
***************************************/
void main(void)  //主函数
{  
   while(1)
    if(S1!=S2)         //第一次检测到有键按下
    {
        delay1ms(20);   //延时 20ms再去检测
        if(S1==0)      //按键S1 被按下
            led=0;
        if(S2==0)      //按键S2 被按下
            led=1;
    }      
}
[ 此帖被wulin在2017-04-07 09:00重新编辑 ]
本帖最近打赏记录:共2条打赏M币+2
离线snaker

发帖
802
M币
1546
专家
1
粉丝
23
只看该作者 7楼 发表于: 2017-04-07
直接检测IO口不就行了
if(S1==0)
    {
        ys(10);
        if(S1==0)
        {
            while(!S1);
            P3^4=0;        
        }
    }
离线rock666

发帖
106
M币
212
专家
3
粉丝
9
只看该作者 8楼 发表于: 2017-04-07
#include<reg51.h>    //  包含 51单片机寄存器定义的头文件
sbit S1=P3^3;        //  
sbit S2=P3^2;
//sbit led=P3^4;       //将 LED0 位定义为 P3.3引脚


/*************************************************
函数功能:主函数
**************************************************/
void main(void)  //主函数
{
    if((P3&0x0c)!=0x0c)         //第一次检测到有键按下
         {
          
          if(S1==0)      //按键S1 被按下
           P3=0x0c;
            if(S2==0)      //按键S2 被按下
           P3=0x1c;
           }
        
   }


去掉消抖后就可以了,唉,还是学艺不精啊
离线落叶风

发帖
1314
M币
3892
专家
196
粉丝
19505
只看该作者 9楼 发表于: 2017-04-07
看你的要求,我把我的写法贴出来供参考。
#include <STC15F104.h>
sbit S1=P3^2;        //  
sbit S2=P3^1;
sbit led=P3^3;       //将 LED0 位定义为 P3.3引脚
unsigned char oldkey;
void delay(unsigned int t) //长延时程序,延时t毫秒,STC 1T单片机11.0592M晶振I值为648,22.1I值为1298,12MI值为705。
{
     unsigned int i;
     while(t--)
       {
        for(i=705;i>0;i--);
       }
}

//***********************键盘扫描子程序。******************
//*********************************************************
unsigned char keyboard()//键盘扫描
{
      unsigned char keyboardj;
     keyboardj=0;
    if(S1==0)
      {
        delay(10);
          if(S1==0)
          {
              keyboardj=1;
          }
      }
      if(S2==0)
      {
        delay(10);
          if(S2==0)
          {
              keyboardj=2;
          }
      }
   return  keyboardj;
}
//************键盘控制子程序***************
void keydisphong()//主要功能是
{
   unsigned char keyyy;    
   keyyy=keyboard();    
     if (keyyy!=oldkey)
       {    
            if(keyyy==1) //
            {
              led=1;//关
            }
          if(keyyy==2) //
            {
              led=0;//开
            }                              
        }
  oldkey=keyyy;
}
void main()
{
    while(1)
    {
        keydisphong();    
   }
}
本帖最近打赏记录:共1条打赏M币+1
快速回复
限80 字节
温馨提示:所有技术区严禁灌水,“沙发”“顶”字样;禁止广告贴;以免被删除
 
上一个 下一个