按键数码管显示复用后冲突问题

2020-01-23 14:42发布

用的51单片机,附电路图。

按键KEY与数码管COM端是复用的。

现在可以知道,把数码管的数据输出端设置为高阻输入。
按键即(COM)端,设置为标准IO口,可以检测到按键输入。

数码管显示时,
数码管的数据输出端设置为推挽输出。
按键即(COM)端,同时要设置为推挽才可以显示正常,

数码管显示用的是定时器中断显示。(6ms)。
按键在主循环,扫描输入(100ms)扫描1次。

用了按键程序,LED显示不正常。
用了LED显示程序,按键程序不正常。

不知道为什么?有没有人指一下点? KEY_COM.jpg (320.99 KB, 下载次数: 1) 下载附件 按键数码管复用电路 2013-5-15 08:40 上传
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
45条回答
wenking99
1楼-- · 2020-01-27 01:31
进入Display_Led()函数时,首先调用Get_Key()函数,然后执行Display_Led()函数其它内容.

while ( 1 )
        {
                WDT_action();//喂狗
                if ( g_time_5MS_Fg )//5ms数码管显示
                {
                        g_time_5MS_Fg = 0;
                        
                        g_key_scan_count++;
                        
                        if ( g_key_scan_count >= 20 )//100ms
                        {
                                g_key_scan_count = 0;
                                key = Get_Key ( );                       
                        }
                         Display_Led();/
                }
我觉得这样子做,显示和按键都是分开的。为什么还按键还是没有检测到?
wenking99
2楼-- · 2020-01-27 01:35
while ( 1 )
        {
                WDT_action();//喂狗
                if ( g_time_5MS_Fg )//5ms数码管显示
                {
                        g_time_5MS_Fg = 0;
                        
                        g_key_scan_count++;                        
                     
                         Display_Led();//
                          if ( g_key_scan_count >= 20 )//100ms扫描一次按键
                         {
                                g_key_scan_count = 0;
                                key = Get_Key ( );        //这里要连续扫描两次才能输出键值                  
                                key = Get_Key ( );        //这里要连续扫描两次才能输出键值   
                         }
                }
}

但是上面会出现一个问题。按下时4个数码管会闪,长按会不停闪,频率大概是1秒闪一次。
不知道为什么要连续扫描两次按键才有数据输出,
而且数码管会闪烁。
wenking99
3楼-- · 2020-01-27 03:58
 精彩回答 2  元偷偷看……
wenking99
4楼-- · 2020-01-27 04:14
进一步发现,只要在按键检测前加一个延时1us就可以正常按键,LED显示也正常了。

void delay_us ( BYTE time )
{
        BYTE i;
        for (i=0; i<time; i++)
        {
                ;
        }
}

Byte Get_Key ( void )
{
        BYTE byKey = 0;

        P1M0 |= 0xfc;    //数码管数据端高阻输入
        P1M1 &= ~0xfc;        
        P2M0 |= 0x06;   ///数码管数据端高阻输入
        P2M1 &= ~0x06;               

        P2M0 &= ~0x20;;        //数码管公共端设置为标准IO口,即按键输入端
        P2M1 &= ~0x20
        P3M0 &= ~0x1c;                //数码管公共端设置为标准IO口,即按键输入端
        P3M1 &= ~0x1c;
        P2 |= 0X20;              //设置按键输入引脚为高电平
        P3 |= 0X1C;             //设置按键输入引脚为高电平
        
       delay_us(1);             //延时1uS再读引脚电平。
        
        if ( P25 == 0 )//KEY_MENU按键按下
        {
              UartSendByte(1);        //测试
              byKey = 1;
        }
        return byKey;
}
canback
5楼-- · 2020-01-27 06:55
wenking99 发表于 2013-5-17 14:58
我不是说没有驱动。一般情况下,要点亮数码管,公共端要加三极管等驱动电路。
这个电路没有什么三极管放大 ...

接数码管阳极的管脚才需要设置成推挽输出,数码管阴极的,默认的输出就可以了。
你的是共阴数码管,不需要设置成推挽输出,程序里也就没这么多PxM0,PxM1的操作了。

xiaobendan001
6楼-- · 2020-01-27 11:51
wenking99 发表于 2013-5-17 19:32
进一步发现,只要在按键检测前加一个延时1us就可以正常按键,LED显示也正常了。

void delay_us ( BYTE tim ...

你用多少频率的晶振?
还是那个问题,没仔细看PDF文件,加延时的问题,在PDF文件里面有提及。
要踏实,不要浮躁!

一周热门 更多>