迷惑不解的按键识别与数码管电路

2020-01-16 18:25发布

正在研究如下一个电路:
ledkeys.JPG (121.35 KB, 下载次数: 0) 下载附件 2014-1-11 19:43 上传

单片机是贴片44脚的STC89C54, PIN30-P37即P0.7~P0.0, PIN43即P1.3, PIN18~P21即P2.0~P2.3,
LED是四位数码管,


PIN21-PIN18位码输出,实测均接高电平时,一般理解:
PIN43被电阻R48下拉,当按键按下时应该是晶体管导通,PIN43应为高电平。

由位码扫描与PIN43的电位,就可以得知是哪个按键按下。
但是,实际是这样的:

未按键时PIN43的电压是0.7V,而二极管D1-D4的正极均为0.65V,负极为0.58V,而按下按钮后二极管正极不变,负极为1.4V左右。

按理如果三极管导通的话,EC压降0.7,二极管压降0.7,PIN43的电压应该是3.6V左右。
实际情况只能判断是不导通。

但这为何?而且二极管的正负端电压变化因何而起呢?

请高手帮忙分析一下。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
22条回答
downtoearth
1楼-- · 2020-01-18 15:39
mcu_lover 发表于 2014-3-1 09:19
一样要消抖,连续几次检测到按下,就确定按下了。

不知是不是年纪大,脑筋不是怎么灵。还是对单片机没有什么天分。想了很久,也写了两次,都得不到想要的效果!
程序还很类聚。现在都不知再怎样下手。可以贴上个例程参考下吗?或者是一个框架都可以!
mcu_lover
2楼-- · 2020-01-18 20:52
downtoearth 发表于 2014-3-5 07:17
不知是不是年纪大,脑筋不是怎么灵。还是对单片机没有什么天分。想了很久,也写了两次,都得不到想要的效 ...

伪代码如下,应该比较清晰。

#define KEY_S1     0x01;
#define KEY_S2     0x02;
#define KEY_S3     0x04;
#define KEY_S4     0x08;

uint8 g_u8KeyValue = KEY_NULL;


//5ms 定时中断
//共4个数码管,全部扫描完需要20ms, 帧率为50,可以稳定显示了
void Timer_5ms_Int(void)
{
    static uint8 s_u8ScanBits = 0;

    //消隐
    PIN18 = 1;
    PIN19 = 1;
    PIN20 = 1;
    PIN21 = 1;

   //首先送段码数据
   PIN30~PIN37  = dispBuffer[s_u8ScanBits ]
    switch(s_u8ScanBits )
    {
         case 0:
              //扫描第一个数码管
              PIN21 = 0;
              
              //检测按键S1
              if(PIN43 == 1)
              {
                    g_u8KeyValue  |= KEY_S1 ;
              }
              else
              {
                    g_u8KeyValue  &= ~KEY_S1 ;            
              }
         break;

         case 1:
              //扫描第二个数码管
              PIN20 = 0;
              
              //检测按键S2
              if(PIN43 == 1)
              {
                    g_u8KeyValue  |= KEY_S2 ;
              }
              else
              {
                    g_u8KeyValue  &= ~KEY_S2 ;            
              }
         break;

         case 2:
              //扫描第三个数码管
              PIN19 = 0;
              
              //检测按键S3
              if(PIN43 == 1)
              {
                    g_u8KeyValue  |= KEY_S3 ;
              }
              else
              {
                    g_u8KeyValue  &= ~KEY_S3 ;            
              }
         break;

         case 3:
              //扫描第四个数码管
              PIN18 = 0;
              
              //检测按键S4
              if(PIN43 == 1)
              {
                    g_u8KeyValue  |= KEY_S4 ;
              }
              else
              {
                    g_u8KeyValue  &= ~KEY_S4 ;            
              }
         break;
    }

    s_u8ScanBits ++;
    if(s_u8ScanBits >3)
    {
        s_u8ScanBits  = 0;
    }
}
上面这个函数在中断中执行之后g_u8KeyValue   这个变量就会保持对应按下按键的键值。剩下的消抖就用状态机方式就好了。
yanyinzhong
3楼-- · 2020-01-19 00:04
当作5个数码管就好了,分5次扫,4次扫数码管,一次扫按键
downtoearth
4楼-- · 2020-01-19 02:58
mcu_lover 发表于 2014-3-5 08:49
伪代码如下,应该比较清晰。

#define KEY_S1     0x01;

虽然未完全明白,但已经调通了。那个或运算,是不是可以支持两个按键同时按下而用的。
如果不是为什么不用直接等于呢?
mcu_lover
5楼-- · 2020-01-19 06:19
 精彩回答 2  元偷偷看……
mvip
6楼-- · 2020-01-19 07:33
这样设计很不错,可以省点口线

一周热门 更多>