找回密码
 立即注册

QQ登录

只需一步,快速开始

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

用30个按键来控制5个电平输出,单片机程序哪里出错了?

[复制链接]
跳转到指定楼层
楼主
各位大神:我用30个按键来控制5个电平输出,每个按键对应一个电平,1号键对应0xfe,2号键对应0xfd,以此类推,按键按下后恢复按键延时10ms输出全部为高电平,现在出现第一次按键总是输0xfe,按其他按键总是会把前面按过按键的信息带上,要第二次才输出正确。请哪位大神帮我看看程序如下

单片机源程序:
#include <reg52.h>
#define uchar unsigned char
uchar code tab[]={0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,
                        0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0,0xef,
                  0xee,0xed,0xec,0xeb,0xea,0xfe9,0xe8,0xe7,
                  0xe6,0xe5,0xe4,0xeb3,0xe2,0xe1,0xeff};//输出二进制库
                         //输出为11110 11101 到00001
uchar temp,num,n1;
void display();
keyscan();
void delay(uchar z)
{
uchar x,y;
for(x=z;x>0;x--)
  for(y=100;y>0;y--);
}
keyscan()    //矩阵键盘扫描程序
{
P1=0xfe;
if(P2!=0xff)
{
  delay(10);
  if(P2!=0xff)
  {
   temp=P2;
   switch(temp)
     {
      case 0x7f : num=31;break;
      case 0xbf : num=30;break;
      case 0xdf : num=29;break;
      case 0xef : num=28;break;
      case 0xf7 : num=27;break;
      case 0xfb : num=26;break;
            case 0xfd : num=25;break;
            case 0xfe : num=24;break;
     }
   while(temp!=0xff)
      {
      temp=P2;
      display();
      }
   }
}
delay(10);
P1=0xfd;
if(P2!=0xff)
{
  delay(10);
  if(P2!=0xff)
  {
   temp=P2;
   switch(temp)
      {
       case 0x7f : num=23;break;
       case 0xbf : num=22;break;
       case 0xdf : num=21;break;
       case 0xef : num=20;break;
       case 0xf7 : num=19;break;
       case 0xfb : num=18;break;
             case 0xfd : num=17;break;
       case 0xfe : num=16;break;
      }
       while(temp!=0xff)
       {
        temp=P2;
        display();
       }
    }
}
delay(10);
P1=0xfb;
if(P2!=0xff)
{
  delay(10);
  if(P2!=0xff)
  {
   temp=P2;
   switch(temp)
     {
       case 0x7f : num=15;break;
       case 0xbf : num=14;break;
       case 0xdf : num=13;break;
       case 0xef : num=12;break;
       case 0xf7 : num=11;break;
       case 0xfb : num=10;break;
             case 0xfd : num=9;break;
       case 0xfe : num=8;break;  
      }
   while(temp!=0xff)
      {
       temp=P2;
       display();
      }
    }
}
delay(10);
P1=0xf7;
if(P2!=0xff)
{
  delay(10);
  if(P2!=0xff)
  {
   temp=P2;
   switch(temp)
      {
        case 0x7f : num=7;break;
        case 0xbf : num=6;break;
        case 0xdf : num=5;break;
        case 0xef : num=4;break;
        case 0xf7 : num=3;break;
        case 0xfb : num=2;break;
              case 0xfd : num=1;break;
        case 0xfe : num=0;break;
       }
        while(temp!=0xff)
        {
         temp=P2;
         display();
        }
    }
  }
delay(10);
return num;     
}      
void display()
{
     {
                 P0=tab[n1];
           }
  }
void main()
        {
while(1)
         {
   n1=num;
         P0=0xff;//使输出全部为高电平
         keyscan();
   }
}


test.rar (77.03 KB, 下载次数: 7)

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

使用道具 举报

沙发
ID:466164 发表于 2019-3-13 20:11 | 只看该作者
消隐,如果端口有锁存清锁存。
回复

使用道具 举报

板凳
ID:480410 发表于 2019-3-14 09:54 | 只看该作者
7358655 发表于 2019-3-13 20:11
消隐,如果端口有锁存清锁存。

谢谢,修改试试
回复

使用道具 举报

地板
ID:490652 发表于 2019-3-14 13:41 | 只看该作者
变换查询口线前,置P2 = 0xFF ,这样再查才能消除之前的
回复

使用道具 举报

5#
ID:213173 发表于 2019-3-14 13:51 | 只看该作者
本帖最后由 wulin 于 2019-3-15 07:38 编辑

你的显示程序和数组写的都有问题,4*8矩阵键盘扫描程序也繁琐,不是很清楚你的用途,
给你改了一下,不影响P1高4位另做他用,直接用P0短暂显示键值1~32,经仿真无误。你可
以按需自行修改。



  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. /*
  6. uchar code tab[]={0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,
  7.                   0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0,0xef,
  8.                   0xee,0xed,0xec,0xeb,0xea,0xfe9,0xe8,0xe7,
  9.                   0xe6,0xe5,0xe4,0xeb3,0xe2,0xe1,0xeff};//输出二进制库
  10.                   //输出为11110 11101 到00001
  11. */
  12. uint  temp=0;//计数变量
  13. uchar key=0xff;//键值变量
  14. bit key_yes=0;//

  15. //void display();
  16. //void keyscan();
  17. /*
  18. void delay(uchar z)
  19. {
  20.         uchar x,y;
  21.         for(x=z;x>0;x--)
  22.                 for(y=100;y>0;y--);
  23. }*/
  24. void keyscan()    //4*8矩阵键盘扫描程序
  25. {
  26.         static bit sign=0;                        //按键自锁标志
  27.         static uint count=0;                //消抖计数变量        
  28.         uint num,num1;
  29.         P1|=0x0f;//保持P1高4位不变,操作低4位1111
  30.         P1&=0xf0;//保持P1高4位不变,操作低4位0000
  31.         P2=0xff;//P2全高
  32.         num=(P1&0x00)<<8|P2;
  33.         if(num!=0x00ff)//判断有键按下
  34.         {
  35.                 if((++count>=250)&&(sign==0))//消抖与判断自锁
  36.                 {
  37.                         sign=1;                        //按键自锁标志置1
  38.                         P1|=0x0f;                //保持P1高4位不变,操作低4位1111                        
  39.                         P2=0x00;                        //P2全低
  40.                         num1=(P1&0x0f)<<8|P2;
  41.                         num|=num1;
  42.                         switch(num)
  43.                         {
  44.                                 case 0x0efe: key= 1; break;
  45.                                 case 0x0efd: key= 2; break;
  46.                                 case 0x0efb: key= 3; break;
  47.                                 case 0x0ef7: key= 4; break;
  48.                                 case 0x0eef: key= 5; break;
  49.                                 case 0x0edf: key= 6; break;
  50.                                 case 0x0ebf: key= 7; break;
  51.                                 case 0x0e7f: key= 8; break;
  52.                                 case 0x0dfe: key= 9; break;
  53.                                 case 0x0dfd: key=10; break;
  54.                                 case 0x0dfb: key=11; break;
  55.                                 case 0x0df7: key=12; break;
  56.                                 case 0x0def: key=13; break;
  57.                                 case 0x0ddf: key=14; break;
  58.                                 case 0x0dbf: key=15; break;
  59.                                 case 0x0d7f: key=16; break;
  60.                                 case 0x0bfe: key=17; break;
  61.                                 case 0x0bfd: key=18; break;
  62.                                 case 0x0bfb: key=19; break;
  63.                                 case 0x0bf7: key=20; break;
  64.                                 case 0x0bef: key=21; break;
  65.                                 case 0x0bdf: key=22; break;
  66.                                 case 0x0bbf: key=23; break;
  67.                                 case 0x0b7f: key=24; break;
  68.                                 case 0x07fe: key=25; break;
  69.                                 case 0x07fd: key=26; break;
  70.                                 case 0x07fb: key=27; break;
  71.                                 case 0x07f7: key=28; break;
  72.                                 case 0x07ef: key=29; break;
  73.                                 case 0x07df: key=30; break;
  74.                                 case 0x07bf: key=31; break;
  75.                                 case 0x077f: key=32; break;
  76.                         }
  77.                         key_yes=1;
  78.                 }
  79.         }
  80.         else                                                //键抬起
  81.         {
  82.                 sign=0;                                        //按键自锁标志清0
  83.                 count=0;                                //消抖计数清0
  84.         }
  85. }
  86. /*
  87. void display()
  88. {
  89.         {
  90.                 P0=tab[n1];
  91.         }
  92. }
  93. */
  94. void main()
  95. {
  96.         while(1)
  97.         {
  98.                 keyscan();
  99.                 if(key_yes==1)
  100.                 {
  101.                         P0=key;//读键值P0显示
  102.                         temp++;
  103.                         if(temp>=10000)//延时时间可调
  104.                         {
  105.                                 temp=0;
  106.                                 key_yes=0;
  107.                                 P0=0xff;
  108.                         }
  109.                 }
  110.         }
  111. }
复制代码




回复

使用道具 举报

6#
ID:480410 发表于 2019-3-14 21:03 | 只看该作者
感谢wulin,你的程序我稍作修改,已满足我的学习要求,我刚刚开始学习单片机,好多程序需要学习,你的这段程序还要消化一些时间。谢谢
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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