标题: 单片机流水灯程序,想把用两个按键改成用一个按键控制,请大佬们给看看,谢谢 [打印本页]

作者: cxy822    时间: 2024-6-16 14:22
标题: 单片机流水灯程序,想把用两个按键改成用一个按键控制,请大佬们给看看,谢谢
流水灯选择程序,现在是两个按键,一个开始,一个停止,想把用两个按键改成用一个按键控制,同一个按键,按一下开始,再按一下停止,改了几次没改明白,请大佬们给看看怎么改,谢谢!

单片机源程序如下:
  1. #include <REGX52.H>

  2. #include <stdlib.h>                        //库文件,使用随机数发生函数

  3. typedef unsigned char uchar; //无符号字符型数据
  4. typedef unsigned int  uint;         //无符号整型数据

  5. sbit Key1=P1^6;        //按键开始
  6. sbit Key2=P1^7;        //按键停止

  7. bit flag=0;                //定时时间标志位
  8. uchar num[2];        //产生的随机数
  9. uchar cnt;                //计数变量
  10. uchar str[2]= {0xff,0xff};         //定义数组存放35个LED数据

  11. void Delay_Us(int i);                //延时函数
  12. void Timer_Init(void);                //定时器初始化
  13. void UART_Init(void);                //串口初始化
  14. //主函数
  15. void main(void)
  16. {
  17.     uchar i,j,k;                        //定义变量
  18.     UART_Init();                           //串口初始化
  19.     Timer_Init();                           //定时器初始化

  20.                                   //12个LED初始状态,全部熄灭
  21.         P2=0xff;
  22.         P1=0xff;
  23.     while(1)
  24.     {
  25.         if(flag)         //定时时间到
  26.         {
  27.             flag=0;         //标志位清零
  28.             /*----12抽取2个LED-----*/
  29.                         for(i=0; i<2; i++)         //12个LED全部熄灭
  30.             {
  31.                 str[i]=0xff;
  32.             }
  33.             for(i=0; i<2; i++)
  34.             {
  35.                 k=rand()%12; //产生随机数0-11
  36.                 for(j=0; j<i ; j++)
  37.                 {
  38.                     while(num[j]==k)         //如果产生的随机数与之前的相同,则重新生成
  39.                     {
  40.                         k=rand()%12;
  41.                     }
  42.                 }
  43.                 num[i]=k;
  44.                 str[num[i]/8]&=~(0x01<<(num[i]%8));         //将随机数转换为对应的LED数据
  45.             }
  46.                         
  47.                         P2=str[0];                          //控制12个LED点亮
  48.                                P1=str[1];
  49.         }
  50.         if(Key1==0)        //按键开始
  51.         {
  52.             Delay_Us(1000);        //延时消抖
  53.             if(Key1==0)
  54.             {
  55.                 TR0=1;
  56.             }
  57.             while(Key2==0);        //按键松手检测
  58.         }
  59.         if(Key2==0)        //按键停止
  60.         {
  61.             Delay_Us(1000);        //延时消抖
  62.             if(Key2==0)
  63.             {
  64.                 TR0=0;
  65.                 /*----12抽取2个LED-----*/
  66.                 for(i=0; i<2; i++)         //35个LED全部熄灭
  67.                     {
  68.                         str[i]=0xff;
  69.                     }
  70.                     for(i=0; i<2; i++)
  71.                     {
  72.                         k=rand()%12; //产生随机数0-34
  73.                         for(j=0; j<i ; j++)
  74.                         {
  75.                             while(num[j]==k)         //如果产生的随机数与之前的相同,则重新生成
  76.                             {
  77.                                 k=rand()%12;
  78.                             }
  79.                         }
  80.                         num[i]=k;
  81.                         str[num[i]/8]&=~(0x01<<(num[i]%8));         //将随机数转换为对应的LED数据
  82.                     }
  83.                                 
  84.                                 P2=str[0];                          //控制12个LED点亮
  85.                                 P1=str[1];
  86.             }
  87.             while(Key2==0);        //按键松手检测
  88.         }
  89.     }
  90. }
  91. //延时函数
  92. void Delay_Us(int i)
  93. {
  94.     while(i--);
  95. }
  96. //定时器初始化
  97. void Timer_Init(void)
  98. {
  99.     TMOD|=0x01; //打开定时器0,1,工作方式1。
  100.     TH0=0x3c;        //给定时器0赋初值,定时50ms
  101.     TL0=0xb0;
  102.     ET0=1;      //打开定时器0中断允许
  103.     TR0=0;                //打开定时器
  104.     PS=1;
  105.     EA=1;       //打开总中断
  106. }
  107. //串口初始化
  108. void UART_Init(void)
  109. {
  110.     SM0=0;                //串口模式0:同步移位寄存器方式
  111.     SM1=0;
  112.     TI=0;                //发送中断清零
  113. }

  114. //void UART_Send(uchar dat)
  115. //{
  116. //    ST=0;
  117. //    SBUF=dat;          //LED数据
  118. //    while(~TI);                 //等待发送完成
  119. //    TI=0;                        //标志位清零
  120. //    ST=1;
  121. //    ST=0;
  122. //}
  123. //定时器0中断函数
  124. void Timer0() interrupt 1
  125. {
  126.     TH0=0x3c;   //定时50ms
  127.     TL0=0xb0;
  128.     cnt++;                //中断计数
  129.     if(cnt==2)
  130.     {
  131.         cnt=0;
  132.         flag=1;        //标志位置1
  133.     }
  134. }
复制代码



作者: zhuls    时间: 2024-6-16 16:45
if (!key) key_count++;
key_count %=2;
switch (key_count)
{
case 0:
  run....
case 1:
  stop...
}

}


作者: 123yhk    时间: 2024-6-16 22:41
............
char Start_end_flag = 0x01;//开始结束标志位
............

void main(void)
{
............
    while(1)
    {
............
        if(Key1==0)        //按键开始
        {
            Delay_Us(1000);        //延时消抖
        Start_end_flag ^= 0x01;//异或运算,1^1=0,0^1=1,由此可实现0和1的切换
            if(Start_end_flag == 0)
            {
                TR0=1;
            }
                                               
            if(Start_end_flag == 1)
            {
                TR0=0;
                /*----12抽取2个LED-----*/
                for(i=0; i<2; i++)         //35个LED全部熄灭
                    {
                        str[i]=0xff;
                    }
                    for(i=0; i<2; i++)
                    {
                        k=rand()%12; //产生随机数0-34
                        for(j=0; j<i ; j++)
                        {
                            while(num[j]==k)         //如果产生的随机数与之前的相同,则重新生成
                            {
                                k=rand()%12;
                            }
                        }
                        num[i]=k;
                        str[num[i]/8]&=~(0x01<<(num[i]%8));         //将随机数转换为对应的LED数据
                    }
                              
                                P2=str[0];                          //控制12个LED点亮
                                P1=str[1];
            }               
                                               
            while(Key1==0);        //按键松手检测
        }
    }
}
作者: cyi8    时间: 2024-6-17 09:43
单独建立一个循环,让键值在1与0之间循环,然后程序判断键值是1还是0就行了,两个键值的单键很好搞的
作者: cy009    时间: 2024-6-17 10:40
使用key1完成开和关的功能:
作者: cy009    时间: 2024-6-17 10:42
使用key1完成开始和停止的功能:
if(Key1==0)        //按键开始
        {
            Delay_Us(1000);        //延时消抖
            if(Key1==0)
            {
                TR0 = !TR0;
            }
            while(Key2==0);        //按键松手检测
作者: dhjmw    时间: 2024-6-17 17:36
你这个去抖程序受书毒害严重啊!我都是隔一段时间读一次,与上次相同则采用,否则继续使用上次的值,保存本次值。
if(k_in == k_temp)k=k_in;
else k_temp=kin;
if(!k && k_old)led=!led;
k_old=k;
作者: cxy822    时间: 2024-6-17 19:47
zhuls 发表于 2024-6-16 16:45
if (!key) key_count++;
key_count %=2;
switch (key_count)

谢谢,刚开始搞,研究一下
作者: cxy822    时间: 2024-6-17 19:49
123yhk 发表于 2024-6-16 22:41
............
char Start_end_flag = 0x01;//开始结束标志位
............

谢谢,刚开始搞,我还得慢慢研究
作者: cxy822    时间: 2024-6-17 21:15
cy009 发表于 2024-6-17 10:42
使用key1完成开始和停止的功能:
if(Key1==0)        //按键开始
        {

感谢!学习中
作者: cxy822    时间: 2024-6-17 21:19
dhjmw 发表于 2024-6-17 17:36
你这个去抖程序受书毒害严重啊!我都是隔一段时间读一次,与上次相同则采用,否则继续使用上次的值,保存本 ...

哈哈,刚开始学
作者: cxy822    时间: 2024-6-18 22:11
非常谢谢大家!改成功啦




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1