找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机程序 卡在K2按键可以进行模式加一这一步和K3的模式减一这一步

[复制链接]
跳转到指定楼层
楼主
我的问题就卡在K2按键可以进行模式加一这一步和K3的模式减一这一步,我不知道到这里我应该如何将我之前编好的那八个模式导进去,因为我把它们都封装成函数,请大佬们给点提示,孩子真的写不出来了。没有任何思路

单片机源程序如下:
#include <reg52.h>

#define uchar unsigned  char
#define uint unsigned int
sbit key0=P0^0;
sbit key1=P0^1;
sbit key2=P0^2;
sbit key3=P0^3;
uchar code table0[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//LED从低位往高位移
uchar code table1[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//LED从高位往低位移
uchar code table2[]={0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00};//LED从1个亮到8个都点亮(从低位往高位)
uchar code table3[]={0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01,0x00};//LED从1个亮到8个都点亮(从高位往低位)
uchar code table4[]={0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff};//LED从8个全亮到一个都不亮(从低位往高位)
uchar code table5[]={0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff};//LED从8个全亮到一个都不亮(从高位往低位)
uchar code table6[]={0xfe,0xfc,0xfa,0xf6,0xee,0xde,0xbe,0x7e};//LED从低位往高位移(最低位始终为0)
uchar code table7[]={0x7f,0x3f,0x5f,0x6f,0x77,0x7b,0x7d,0x7e};//LED从高位往低位移(最高位始终为0)
uchar keyflag=0;//按键标志位
void keyscan();//按键检测函数
uchar i,j,a;
void delayms(uint xms);


void disp0()  //状态0 全亮
{    P1=0x00;
    delayms(500);   
}


void disp1()                        //状态1 低位到高位依次亮
{
                for(i=0;i<8;i++)
                {
                P1=table0[ i];
                delayms(500);
                }
            P1=0xff;
                 
}
void disp2() //状态2  LED从高位到低位依次亮
{  P1=0xff;
for(i=0;i<8;i++)
  {        P1=table1[ i];
        delayms(500);
  }
           
}
void disp3()  // 状态3 LED闪烁3次
{   for(i=0;i<3;i++)
     {        P1=0X00;
     delayms(500);
        P1=0xff;
      delayms(500);
      }
           
}
void disp4()                        //状态4 LED自上而下逐渐点亮
{
        
        for(i=0;i<8;i++)
        {
                P1=table3[ i];
                delayms(100);
        }
        P1=0xff;
}
void disp5()                        //状态5 从LED全部亮到全不亮
{
        for(i=0;i<9;i++)
        {
                P1=table5[ i];
                delayms(100);
        }
        delayms(300);
}
void disp6()                        //状态6 逐步逆时针点亮P1的LED,熄灭
{
   P1=0xff;
        for(j=0;j<2;j++)
        {
                for(i=0;i<8;i++)
                {
               
                        P1=table2[ i];
                        delayms(100);
                }
             P1=0xff;
               
        }
}




void disp7()   //状态7 全灭
{   P1=0XFF;
    delayms(500);
}


void main()
{
  while(1)
  {   keyscan();
      switch(keyflag)
      {case 1:disp0();break;
        case 2:     break;
        case 3:     break;
        case 4:disp7();break;
      }
  }  
}
void delayms(uint xms)
{ uint i,j;
   for(i=0;i<xms;i++)
     for(j=0;j<120;j++);
}
void keyscan()
{ P0=0xff;//输入先写“1”
  if((P0&0x0f)!=0x0f)//检测有按键按下
  {delayms(10);//延时去抖
   if(key0==0)//key0按键按下
   keyflag=1;//设标志位1
   if(key1==0)//key1按键按下
   keyflag=2;//设标志位2
   if(key2==0)//key2按键按下
   keyflag=3;//设标志位3
   if(key3==0)//key3按键按下
   keyflag=4;//设标志位4
   while(!key0);
   while(!key1);
   while(!key2);
   while(!key3);
  }
}

屏幕截图 2023-10-29 083824.png (63.94 KB, 下载次数: 51)

屏幕截图 2023-10-29 083824.png
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:275826 发表于 2023-10-29 17:28 | 只看该作者
你这个程序基本没用,都死在子函数里了
回复

使用道具 举报

板凳
ID:1096616 发表于 2023-10-29 17:57 | 只看该作者
tyrl800 发表于 2023-10-29 17:28
你这个程序基本没用,都死在子函数里了

那我应该怎么去写比较好呢?这个的K2和K3思路是什么?
回复

使用道具 举报

地板
ID:275826 发表于 2023-10-29 19:35 | 只看该作者
深层次 发表于 2023-10-29 17:57
那我应该怎么去写比较好呢?这个的K2和K3思路是什么?

用定时器延时
回复

使用道具 举报

5#
ID:180919 发表于 2023-10-29 20:11 | 只看该作者
程序修改可以了,不过效率太低了,要用定时器才行。
#include <reg52.h>
#define uchar unsigned  char
#define uint unsigned int
sbit key0=P0^0;
sbit key1=P0^1;
sbit key2=P0^2;
sbit key3=P0^3;
uchar code table0[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//LED从低位往高位移
uchar code table1[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//LED从高位往低位移
uchar code table2[]={0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00};//LED从1个亮到8个都点亮(从低位往高位)
uchar code table3[]={0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01,0x00};//LED从1个亮到8个都点亮(从高位往低位)
uchar code table4[]={0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff};//LED从8个全亮到一个都不亮(从低位往高位)
uchar code table5[]={0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff};//LED从8个全亮到一个都不亮(从高位往低位)
uchar code table6[]={0xfe,0xfc,0xfa,0xf6,0xee,0xde,0xbe,0x7e};//LED从低位往高位移(最低位始终为0)
uchar code table7[]={0x7f,0x3f,0x5f,0x6f,0x77,0x7b,0x7d,0x7e};//LED从高位往低位移(最高位始终为0)
uchar keyflag=0;//按键标志位
void keyscan();//按键检测函数
uchar i,j,a;
void delayms(uint xms);


void disp0()  //状态0 全亮
{   
        P1=0x00;
    delayms(500);   
}


void disp1()                        //状态1 低位到高位依次亮
{   
         P1=0xff;
     for(i=0;i<8;i++)
     {
         P1=table0[i];
         delayms(500);
     }
                     
}

void disp2() //状态2  LED从高位到低位依次亮
{  
        P1=0xff;
    for(i=0;i<8;i++)
   {        
           P1=table1[i];
       delayms(500);
   }           
}

void disp3()  // 状态3 LED闪烁3次
{   
        for(i=0;i<3;i++)
     {        
                 P1=0X00;
         delayms(500);
         P1=0xff;
         delayms(500);
      }           
}

void disp4()                        //状态4 LED自上而下逐渐点亮
{
     for(i=0;i<8;i++)
        {
            P1=table3[ i];
            delayms(100);
        }
        P1=0xff;
}

void disp5()                        //状态5 从LED全部亮到全不亮
{
        for(i=0;i<9;i++)
        {
                P1=table5[ i];
                delayms(100);
        }
        delayms(300);
}

void disp6()                        //状态6 逐步逆时针点亮P1的LED,熄灭
{
   P1=0xff;
        for(j=0;j<2;j++)
        {
          for(i=0;i<8;i++)
          {               
               P1=table2[ i];
              delayms(100);
          }
             P1=0xff;               
        }
}

void disp7()   //状态7 全灭
{   P1=0XFF;
    delayms(500);
}


void main()
{
   while(1)
  {  
       
    keyscan();
      switch(keyflag)
      {
                  case 1:disp0();break;
                  case 2:disp1();break;
                  case 3:disp2();break;
                  case 4:disp3();break;
                  case 5:disp4();break;
                  case 6:disp5();break;
                  case 7:disp6();break;
                  case 8:disp7();break;
      }
  }
   
}
void delayms(uint xms)
{ uint i,j;
   for(i=0;i<xms;i++)
     for(j=0;j<120;j++);
}


void keyscan()
{

  if((P0&0x0f)!=0x0f)//检测有按键按下
   {
            delayms(10);//延时去抖
          
                if(key0==0)//key0按键按下
                keyflag=1;
               
                if(key1==0 && keyflag<7)//key1按键按下
                keyflag++;//设标志位2
               
                if(key2==0 && keyflag>2)//key2按键按下
                keyflag--;//设标志位3
               
                if(key3==0)//key3按键按下
                keyflag=8;//设标志位4
                       
                while(!key0);
                while(!key1);
                while(!key2);
                while(!key3);
  }
}

回复

使用道具 举报

6#
ID:161164 发表于 2023-10-29 21:15 | 只看该作者
深层次 发表于 2023-10-29 17:57
那我应该怎么去写比较好呢?这个的K2和K3思路是什么?

给你一个例子
  1. void disp1()                        //状态1 低位到高位依次亮
  2. {
  3.         static uchar i = 0;
  4.         static uint delay = 500;
  5.         if(delay++>=500)
  6.         {
  7.                 delay = 0;
  8.                 P1=table0[i];
  9.                 i++;
  10.                 if(i>=8)i=0;
  11.         }
  12.         delayms(1);
  13. }
复制代码
回复

使用道具 举报

7#
ID:213173 发表于 2023-10-30 09:11 | 只看该作者
深层次 发表于 2023-10-29 17:57
那我应该怎么去写比较好呢?这个的K2和K3思路是什么?

这就是一个花样流水灯的程序,给你改好了。
  1. #include <reg52.h>
  2. #define uchar unsigned  char
  3. #define uint unsigned int
  4. sbit key0=P0^0;
  5. sbit key1=P0^1;
  6. sbit key2=P0^2;
  7. sbit key3=P0^3;
  8. uchar code table0[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//LED从低位往高位移
  9. uchar code table1[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//LED从高位往低位移
  10. uchar code table2[]={0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00};//LED从1个亮到8个都点亮(从低位往高位)
  11. uchar code table3[]={0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01,0x00};//LED从1个亮到8个都点亮(从高位往低位)
  12. uchar code table4[]={0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff};//LED从8个全亮到一个都不亮(从低位往高位)
  13. uchar code table5[]={0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff};//LED从8个全亮到一个都不亮(从高位往低位)
  14. uchar code table6[]={0xfe,0xfc,0xfa,0xf6,0xee,0xde,0xbe,0x7e};//LED从低位往高位移(最低位始终为0)
  15. uchar code table7[]={0x7f,0x3f,0x5f,0x6f,0x77,0x7b,0x7d,0x7e};//LED从高位往低位移(最高位始终为0)

  16. uchar keyflag=0;//按键标志位

  17. void keyscan();//按键检测函数
  18. void delayms(uint xms);


  19. void main()
  20. {
  21.         uchar i,j;

  22.         while(1)
  23.         {
  24.                 keyscan();
  25.                 if(++j>=250)
  26.                 {
  27.                         j=0;
  28.                         switch(keyflag)
  29.                         {
  30.                                 case 0:P1=0xff; break;
  31.                                 case 1:P1=0x00; break;
  32.                                 case 2:P1=table0[i]; break;
  33.                                 case 3:P1=table1[i]; break;
  34.                                 case 4:P1=table2[i]; break;
  35.                                 case 5:P1=table3[i]; break;
  36.                                 case 6:P1=table4[i]; break;
  37.                                 case 7:P1=table5[i]; break;
  38.                                 case 8:P1=table6[i]; break;
  39.                                 case 9:P1=table7[i]; break;
  40.                         }
  41.                         i=++i%8;
  42.                 }
  43.                 delayms(1);
  44.         }  
  45. }

  46. void delayms(uint xms)
  47. {
  48.         uint i,j;
  49.         for(i=0;i<xms;i++)
  50.                 for(j=0;j<120;j++);
  51. }
  52. void keyscan()
  53. {
  54.         static uchar count=0;
  55.         static bit sign=0;
  56.         uchar temp;
  57.         temp=P0&0x0f;
  58.         if(temp!=0x0f)//检测有按键按下
  59.         {
  60.                 if(++count==10 && temp!=0x0f && !sign)
  61.                 {
  62.                         sign=1;//自锁
  63.                         switch(temp)
  64.                         {
  65.                                 case 0x0e: keyflag=1; break;
  66.                                 case 0x0d: if(keyflag<9)keyflag++; break;
  67.                                 case 0x0b: if(keyflag>1)keyflag--; break;
  68.                                 case 0x07: keyflag=0; break;
  69.                         }
  70.                 }
  71.         }
  72.         else//松手
  73.         {
  74.                 count=0;
  75.                 sign=0;
  76.         }
  77. }
复制代码

回复

使用道具 举报

8#
ID:1095802 发表于 2023-10-31 12:20 来自手机 | 只看该作者
wulin 发表于 2023-10-30 09:11
这就是一个花样流水灯的程序,给你改好了。

1、主循环中的j是啥作用
2、按键中count为啥取10,是扫描10次消抖
3、没用中断,主循环时间长会丢键吗
能说明下吗,没看明白,有点像用状态机原理
回复

使用道具 举报

9#
ID:213173 发表于 2023-10-31 16:33 | 只看该作者
殿堂之上 发表于 2023-10-31 12:20
1、主循环中的j是啥作用
2、按键中count为啥取10,是扫描10次消抖
3、没用中断,主循环时间长会丢键吗
...

没有用定时器,在主循环中用delayms(1);使主循环周期大约1ms,按键扫描10次消抖,j计数250ms,控制流水灯移动速度。
回复

使用道具 举报

10#
ID:1096616 发表于 2023-11-4 09:10 | 只看该作者
wulin 发表于 2023-10-30 09:11
这就是一个花样流水灯的程序,给你改好了。

太厉害了,就是要这种效果,原来还可以这样子实现
回复

使用道具 举报

11#
ID:1096616 发表于 2023-11-4 09:10 | 只看该作者

嗯嗯,明白了
回复

使用道具 举报

12#
ID:1096616 发表于 2023-11-4 09:11 | 只看该作者
changhz 发表于 2023-10-29 20:11
程序修改可以了,不过效率太低了,要用定时器才行。
#include
#define uchar unsigned  char

很不错的想法,给我一种新思路了
回复

使用道具 举报

13#
ID:332444 发表于 2023-11-8 10:41 | 只看该作者
今天遇到一个有趣的32灯流水及按键复用,题主电路。

我的电路。


回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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