搜索
bottom↓
回复: 22

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

[复制链接]

出0入0汤圆

发表于 2014-1-11 20:01:20 | 显示全部楼层 |阅读模式
正在研究如下一个电路:


单片机是贴片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左右。
实际情况只能判断是不导通。

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

请高手帮忙分析一下。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

如果想吃一顿饺子,就得从冰箱里取出肉,剁馅儿,倒面粉、揉面、醒面,擀成皮儿,下锅……
一整个繁琐流程,就是为了出锅时那一嘴滚烫流油的热饺子。

如果这个过程,禁不住饿,零食下肚了,饺子出锅时也就不香了……《非诚勿扰3》

出0入264汤圆

发表于 2014-1-11 20:16:57 | 显示全部楼层
想复杂了。
就是在扫描数码管时候,顺便读一下相应的按键是否按下,没有按下为低电平,按下之后为高电平。其它时间均不扫描按键。

出0入0汤圆

 楼主| 发表于 2014-1-11 22:07:15 | 显示全部楼层
实际是:按键按下后,PIN43并未得到想象中的高电平。

出0入0汤圆

发表于 2014-1-11 22:39:16 | 显示全部楼层
mrok 发表于 2014-1-11 22:07
实际是:按键按下后,PIN43并未得到想象中的高电平。

扫描速度快,用示波器看就可以了.

出0入0汤圆

发表于 2014-2-28 18:04:45 | 显示全部楼层
请教一下,这种连接的,按键,单击,长按,连击。的算法。状态机好像不可以。

出0入0汤圆

发表于 2014-3-1 07:02:06 | 显示全部楼层
本帖最后由 downtoearth 于 2014-3-1 07:10 编辑
mcu_lover 发表于 2014-1-11 20:16
想复杂了。
就是在扫描数码管时候,顺便读一下相应的按键是否按下,没有按下为低电平,按下之后为高电平。 ...


请教一下,这种连接的,按键,单击,长按,连击。的算法或者思路。状态机好像不可以。

出0入264汤圆

发表于 2014-3-1 08:22:24 | 显示全部楼层
downtoearth 发表于 2014-3-1 07:02
请教一下,这种连接的,按键,单击,长按,连击。的算法或者思路。状态机好像不可以。 ...

当然可以。按键键值获取是最底层的部分。只要能可靠检测到按下与抬起。后面的单击长击,连击都可以用状态机解决,与常用的按键一致。

出0入0汤圆

发表于 2014-3-1 08:53:38 | 显示全部楼层
mcu_lover 发表于 2014-3-1 08:22
当然可以。按键键值获取是最底层的部分。只要能可靠检测到按下与抬起。后面的单击长击,连击都可以用状态 ...

哦原来状态机是可以的,但现在就是不知怎样能可靠检测按下和抬起。就一串方波,不知用不用消抖。望指教!

出0入264汤圆

发表于 2014-3-1 09:19:56 | 显示全部楼层
downtoearth 发表于 2014-3-1 08:53
哦原来状态机是可以的,但现在就是不知怎样能可靠检测按下和抬起。就一串方波,不知用不用消抖。望指教! ...

一样要消抖,连续几次检测到按下,就确定按下了。

出0入0汤圆

发表于 2014-3-1 09:29:34 | 显示全部楼层
mcu_lover 发表于 2014-3-1 09:19
一样要消抖,连续几次检测到按下,就确定按下了。

哦,待我想想。

出0入0汤圆

发表于 2014-3-1 09:37:36 | 显示全部楼层
显示和扫键是分开的。
点亮数码管时,根据显示内容不一样,C1~C4拉低。
显示完毕后,把C1~C4依次拉高,然后读取PIN43。如果读到高电平,说明对应的按键被按下。

出0入0汤圆

发表于 2014-3-1 15:41:16 | 显示全部楼层
gentlerain 发表于 2014-3-1 09:37
显示和扫键是分开的。
点亮数码管时,根据显示内容不一样,C1~C4拉低。
显示完毕后,把C1~C4依次拉高,然后 ...

这个明显是接共阳数码管的,为什么显示时,是拉低C1~C4。应该是扫一个数码管读一个相应的按键,
不会是显示和扫键分开,我想是说错了吧!

出0入0汤圆

发表于 2014-3-1 21:02:29 | 显示全部楼层
downtoearth 发表于 2014-3-1 15:41
这个明显是接共阳数码管的,为什么显示时,是拉低C1~C4。应该是扫一个数码管读一个相应的按键,
不会是显 ...

喔,是的,的确是看错了。

出0入0汤圆

发表于 2014-3-5 07:17:57 | 显示全部楼层
mcu_lover 发表于 2014-3-1 09:19
一样要消抖,连续几次检测到按下,就确定按下了。

不知是不是年纪大,脑筋不是怎么灵。还是对单片机没有什么天分。想了很久,也写了两次,都得不到想要的效果!
程序还很类聚。现在都不知再怎样下手。可以贴上个例程参考下吗?或者是一个框架都可以!

出0入264汤圆

发表于 2014-3-5 08:49:44 | 显示全部楼层
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   这个变量就会保持对应按下按键的键值。剩下的消抖就用状态机方式就好了。

出0入0汤圆

发表于 2014-3-5 09:28:28 | 显示全部楼层
当作5个数码管就好了,分5次扫,4次扫数码管,一次扫按键

出0入0汤圆

发表于 2014-3-7 07:39:54 | 显示全部楼层
mcu_lover 发表于 2014-3-5 08:49
伪代码如下,应该比较清晰。

#define KEY_S1     0x01;

虽然未完全明白,但已经调通了。那个或运算,是不是可以支持两个按键同时按下而用的。
如果不是为什么不用直接等于呢?

出0入264汤圆

发表于 2014-3-7 08:06:01 | 显示全部楼层
downtoearth 发表于 2014-3-7 07:39
虽然未完全明白,但已经调通了。那个或运算,是不是可以支持两个按键同时按下而用的。
如果不是为什么不 ...

可以作为同时按下使用,一个按键对应一个BIT。

出0入0汤圆

发表于 2014-3-7 08:58:14 | 显示全部楼层
这样设计很不错,可以省点口线

出0入0汤圆

发表于 2014-3-8 04:05:23 | 显示全部楼层
本帖最后由 downtoearth 于 2014-3-8 04:10 编辑
mcu_lover 发表于 2014-3-7 08:06
可以作为同时按下使用,一个按键对应一个BIT。


嗯!我再想问问DS18B20不受中断干扰的驱动应该怎样写。关中断可以稳定读数据,但数码管就会闪烁。
DS18B20好多人都用汇编解决这个问题,但我不懂汇编,我相信C都应该可以的。

出0入0汤圆

发表于 2014-3-8 10:34:59 | 显示全部楼层
很经典的按键扫描.
1820类的单线器件可以在关闭中断的时候发送一个BIT,之后就恢复中断,就不会对其他部分有干扰了;
我现在用得较多的按键电路是直接在数码段上串入一直电阻后通过按键接地,估计你会有点晕,不过可以减低硬件开销

出0入0汤圆

发表于 2017-3-23 17:26:28 | 显示全部楼层
学习一下,数码管和按键公用

出0入0汤圆

发表于 2017-3-23 17:56:08 | 显示全部楼层
MARK一下,明天再细看。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-28 17:41

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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