找回密码
 立即注册

QQ登录

只需一步,快速开始

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

关于51单片机按键控制程序调试

[复制链接]
跳转到指定楼层
楼主
ID:372579 发表于 2021-11-8 09:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
30黑币
就是想做一个按键控制几个LED灯的程序,一个按键控制8个LED,按键按一次,第一个灯亮,并延时熄灭,按键按两次第二个灯亮,并延时熄灭,以此类推,当累计到第八次时,全灭,第九次又回到第一个灯亮,重新累计。下面是自己写的,就只有第一次会亮,大家帮忙看下,谢谢!

#include <reg51.h>
#define uint unsigned int
#define uchar unsigned char
sbit led0 = P1^0;
sbit led1 = P1^1;
sbit led2 = P1^2;
sbit key1 = P3^4;
sbit key2 = P3^5;
sbit key3 = P3^6;
sbit key4 = P3^7;
void delay(uint);
void main()
{
        P1=0xff;           
        if(key1==0)
                {
                        delay(20);
                         if(key1==0)
                                 led1=0;
                                delay(5000);
                }

        if(key2==0)
                {
                        delay(20);
                         if(key2==0)
                                 led2=0;
                                delay(5000);
                }           
        void delay(uint z)
{
        uint x,y;
                for(x=z;x>0;x--)
                        for(y=109;y>0;y--);
}

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

使用道具 举报

沙发
ID:277550 发表于 2021-11-8 11:08 | 只看该作者
逻辑有些许不清晰

是连续按2次(较短时间内)、

还是
开始
按第1次、亮LED1、延时熄灭
按第2次、亮LED2、延时熄灭
..........
按第8次、亮LED8、延时熄灭
按第9次、没动作
循环至“开始”
回复

使用道具 举报

板凳
ID:372579 发表于 2021-11-8 11:41 | 只看该作者
devcang 发表于 2021-11-8 11:08
逻辑有些许不清晰

是连续按2次(较短时间内)、

就是按一次延时熄灭,如果再按一次,那就是两次,那么就第二个灯亮,然后延时熄灭,且每个灯延时时间不一样
回复

使用道具 举报

地板
ID:514901 发表于 2021-11-8 14:27 | 只看该作者
#include <reg51.h>
#define uint unsigned int
#define uchar unsigned char
sbit key1 = P3^4;
void delay(uint);
void main()
{
    char cnt = 0;
    P1=0xff;   
    while(1)
    {
       if(key1 == 0)
       {
          delay(10);
          if(key1 == 0)
          {
              if(++cnt==9)
                  cnt = 0;
              P1 = ~(0X0001 << cnt)              
          }
       }
    }      
}   
void delay(uint z)
{
        uint x,y;
                for(x=z;x>0;x--)
                        for(y=109;y>0;y--);
}
回复

使用道具 举报

5#
ID:313048 发表于 2021-11-8 15:32 | 只看该作者
  1. unsigned long int g_timeMs = 0;                //做全局变量        
  2. unsigned int Time[8][2] = {};                //这里为你每个灯要延时的时间  8个灯  2前面为要延时的时间   后面那个为按下的时间
  3. int main()
  4. {
  5.         unsigned char key_value = 0;
  6.         timer_init();                //定时器初始化 1ms
  7.         key_init();
  8.         led_init();
  9.         while(1)
  10.         {
  11.                 if(key_scan() == true)  //按键检测是否按下  按下返回true
  12.                 {
  13.                         key_value++;
  14.                         Time[key_value][1] = g_timeMs;  //保存按下的时间
  15.                         //开相应的灯
  16.                 }
  17.                 //下面进行轮询查询时间
  18.                 for(char i = 0;i<8;i++)
  19.                 {
  20.                         if(Time[i][0]< (g_timeMs - Time[i][1])) //亮的时间到了
  21.                         {
  22.                                 //关闭相对应的灯
  23.                         }
  24.                 }
  25.         }
  26.         
  27. }

  28. void timer0 interrupt 1
  29. {
  30.         g_timeMs++;
  31. }
复制代码

仅做参考,这样不需要硬延时,亮的时间可以随意定,只要不是太大就可以了,只提供此思路,直接长时间使用可能会出现g_timeMs越界的问题,不过一般自己玩还是不会出现这个问题的。
回复

使用道具 举报

6#
ID:976661 发表于 2021-11-8 15:57 | 只看该作者
程序缺少while(1),没有while(1)的程序只能运行一次
回复

使用道具 举报

7#
ID:313048 发表于 2021-11-8 16:11 | 只看该作者


unsigned long int g_timeMs = 0;                //做全局变量       
unsigned int Time[8][2] = {};                //这里为你每个灯要延时的时间  8个灯  2前面为要延时的时间   后面那个为按下的时间
int main()
{
        unsigned char key_value = 0;
        timer_init();                //定时器初始化 1ms
        key_init();
        led_init();
        while(1)
        {
                if(key_scan() == true)  //按键检测是否按下  按下返回true
                {
                        key_value++;
                        Time[key_value][1] = g_timeMs;  //保存按下的时间
                        //开相应的灯
                }
                //下面进行轮询查询时间
                for(char i = 0;i<8;i++)
                {
                        if(Time[i][0]< (g_timeMs - Time[i][1])) //亮的时间到了
                        {
                                //关闭相对应的灯
                        }
                }
        }
       
}

void timer0 interrupt 1
{
        g_timeMs++;
}


大致就这样吧  可以随便设置要亮的时间,不过要考虑g_timeMs越界的问题,但是自己玩玩的话应该是没问题的,毕竟要越界还是要很长很长的时间的。
回复

使用道具 举报

8#
ID:624769 发表于 2021-11-8 16:16 | 只看该作者
你说: 一个按键控制8个LED,按键按一次,第一个灯亮,并延时熄灭,以此类推,当累计到第八次时,全灭,

疑惑:8个灯 第一 第一个灯亮灭, 第8次不是应该 第八个灯  亮  灭?  怎么变全灭了? 到底应该以什么,怎么  “推” ? 是当中某一次亮两个灯?还是第八个灯另有用途? 还是把全灭 推后到 第9次??

你又说: 第九次又回到第一个灯亮,重新累计。
疑问: 到底还要不要有全灭这个挡位? 全灭这个档位到底如何设计? 前面8个灯都亮 然后灭了, 在这个时候按第九次 究竟应该如何体现(本来就全灭着……)?
回复

使用道具 举报

9#
ID:372579 发表于 2021-11-8 21:05 | 只看该作者
188610329 发表于 2021-11-8 16:16
你说: 一个按键控制8个LED,按键按一次,第一个灯亮,并延时熄灭,以此类推,当累计到第八次时,全灭,

...

不好意思,这里应该是第九次全灭,我弄错了
回复

使用道具 举报

10#
ID:624769 发表于 2021-11-8 21:34 | 只看该作者
aide51 发表于 2021-11-8 21:05
不好意思,这里应该是第九次全灭,我弄错了

全灭这个档位到底如何设计? 前面8个灯都亮 然后灭了, 在这个时候按第九次 究竟应该如何体现(本来就全灭着……)?
回复

使用道具 举报

11#
ID:213173 发表于 2021-11-9 10:26 | 只看该作者
没有主循环while(1),给你改好了。
  1. #include <reg51.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char

  4. sbit key1 = P3^4;
  5. uint i,j;
  6. void delay(uint);

  7. void main()
  8. {
  9.         while(1)
  10.         {   
  11.                 if(key1==0)
  12.                 {
  13.                         delay(20);
  14.                         if(key1==0)
  15.                         {
  16.                                 P1=~(0x01<<i);
  17.                                 delay(1000);
  18.                                 i=++i%8;
  19.                         }
  20.                 }
  21.                 P1=0xff;
  22.         }
  23. }
  24.    
  25. void delay(uint z)
  26. {
  27.         uint x,y;
  28.         for(x=z;x>0;x--)
  29.                 for(y=120;y>0;y--);
  30. }
复制代码
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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