鱼C论坛

 找回密码
 立即注册
查看: 1602|回复: 16

[已解决]单片机用两个按键控制8个LED小灯

[复制链接]
发表于 2022-2-13 21:06:22 | 显示全部楼层 |阅读模式
5鱼币
本帖最后由 救赎自我- 于 2022-2-13 21:07 编辑

各位前辈们 鄙人单片机小白 想着用单片机K1 K2两个按键分别实现LED四个小灯的流水点亮 即K1控制高四位 K2控制低四位 共八个小灯 程序如下 找不出哪里出了问题 未能实现 求大佬指点
#include "reg52.h"
#include "intrins.h"
typedef unsigned char u8;
typedef unsigned int u16;  //最大值65535


sbit led1=P2^0;         //D1指示灯
sbit led2=P2^1;
sbit led3=P2^2;
sbit led4=P2^3;

sbit led5=P2^4;         //D5指示灯
sbit led6=P2^5;
sbit led7=P2^6;
sbit led8=P2^7;

sbit K1=P3^1;
sbit K2=P3^0;
#define led P2

void delay(u16 i)
{
   while(i--);
}

void keypros()
{
   if(K1==0)
   {
          delay(1000);  //10ms 消抖
          if(K1==0)
          {
                   u8 i=0;
         led=0XFE;  //1111 1110
         delay(50000);

         while(1)
         {
             for(i=0;i<3;i++)
                 {
                          led=_crol_(led,1);         //        1111 1110  1111 1101
                        delay(50000);
                         }
                               
         }
          }
          while(!K1);  //判断按键是否松开
       
   }
   if(K2==0)
   {
          delay(1000);  //10ms 消抖
          if(K2==0)
          {
                   u8 i=0;
         led=0xef;  //1110 1111
         delay(50000);
         while(1)
         {
             for(i=0;i<3;i++)
                 {
                          led=_crol_(led,1);         //        1110 1111  1101 1111
                        delay(50000);led=0xef;
                         }
                               
         }
          }
          while(!K2);  //判断按键是否松开
       
   }


}

void main()
{
  while(1)
  {
      keypros();  
  }
}
最佳答案
2022-2-13 21:06:23
楼主代码里面的while(1)这个循环好像没有办法结束,进去这个循环以后,按K2还有反应吗?

最佳答案

查看完整内容

楼主代码里面的while(1)这个循环好像没有办法结束,进去这个循环以后,按K2还有反应吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-2-13 21:06:23 | 显示全部楼层    本楼为最佳答案   
楼主代码里面的while(1)这个循环好像没有办法结束,进去这个循环以后,按K2还有反应吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-2-13 21:21:02 | 显示全部楼层
本人小白一位,好奇问楼主,为什么要用判断按键是否松开,为什么不用上拉电阻或下拉电阻?效果不是更好吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-2-13 22:56:57 | 显示全部楼层
傻眼貓咪 发表于 2022-2-13 21:21
本人小白一位,好奇问楼主,为什么要用判断按键是否松开,为什么不用上拉电阻或下拉电阻?效果不是更好吗?

这位仁兄 可否进一步说说 是说直接确定他的高低电平吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-2-13 23:42:07 | 显示全部楼层
救赎自我- 发表于 2022-2-13 22:56
这位仁兄 可否进一步说说 是说直接确定他的高低电平吗

是的,因为用按键好象会有时差。
如果有误,抱歉让你看笑话了,哈哈。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-2-14 08:59:33 | 显示全部楼层
傻眼貓咪 发表于 2022-2-13 23:42
是的,因为用按键好象会有时差。
如果有误,抱歉让你看笑话了,哈哈。

没有没有  我理解你的意思了  但是问题不在这里好像 现在是我只要按下K1他就8个灯流水点亮 而我是想让他控制4个灯流水点亮 for循环那里我明明设置了i<3 但是他却能点亮8个灯 我就是在这里非常的困惑 兄弟你对此有何见解 救救俺 哭了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-2-14 10:45:13 | 显示全部楼层
本帖最后由 jhq999 于 2022-2-14 10:47 编辑

学习了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-2-14 10:59:40 From FishC Mobile | 显示全部楼层
我上网爬文了关于流水LED代码如下,只是没有按键,可以自行修改代码,希望对你有帮助:
#include <reg52.h>

sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;

void main(){
        unsigned int i = 0;  //定义循环变量 i,用于软件延时
        unsigned char cnt = 0; //定义计数变量 cnt,用于移位控制
        ENLED = 0;
        ADDR3 = 1;
        ADDR2 = 1;
        ADDR1 = 1;
        ADDR0 = 0;
        while (1){  //主循环,程序无限循环执行该循环体语
                P0 = ~(0x01 << cnt);  //P0 等于 1 左移 cnt 位,控制 8 个 LED
                for (i = 0; i < 20000; i++); //软件延时
                cnt++;  //移位计数变量自加 1
                if (cnt >= 8){  //移位计数超过 7 后,再重新从 0 开始
                        cnt = 0;
                }
        }
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-2-14 11:07:36 | 显示全部楼层

代表

本帖最后由 jhq999 于 2022-2-14 14:32 编辑
救赎自我- 发表于 2022-2-14 08:59
没有没有  我理解你的意思了  但是问题不在这里好像 现在是我只要按下K1他就8个灯流水点亮 而我是想让他 ...

if(K1==0)
   {
          delay(1000);  //10ms 消抖
          if(K1==0)
          {
                   u8 i=0;
         //led=0XFE;  //1111 1110
         delay(50000);

         while(1)
         {
             led=0XFE;//////////////////////////////////////////////////////////////如果不这里设定led值和while(1)led=_crol_(led,1);没有区别
             for(i=0;i<3;i++)
                 {
                          led=_crol_(led,1);         //        1111 1110  1111 1101
                        delay(50000);

                    }
                                    
         }
    }
          while(!K1);  //判断按键是否松开
       
   }

不懂单片机,为什么不这样写
if(K1==0)
   {
          delay(1000);  //10ms 消抖
          if(K1==0)
          {
                   u8 i=0;
         //led=0XFE;  //1111 1110
         delay(50000);

         while(!K1) /////////////////////判断按键是否松开,为什么不放在这里判断
         {
             led=0XFE;//////////////////////////////////////////////////////////////如果不这里设定led值和while(1)led=_crol_(led,1);没有区别
             for(i=0;i<3;i++)
                 {
                          led=_crol_(led,1);         //        1111 1110  1111 1101
                        delay(50000);

                    }
                                    
           }
       }
         
   }
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-2-14 15:58:32 | 显示全部楼层
你的老师没有告诉过你吗?
读取外部输入之前自己要先输出高电平

1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-2-15 01:24:16 | 显示全部楼层
#include <mcs51/8052.h>
#include <stdint.h>
#include <stdbool.h>

#define K1 0
#define K2 1

void delay(uint16_t count) {
    for(uint16_t i = 0; i < count; ++i);
}

void led_set(uint8_t data) {
    P0 = 0xff;

    // ENLED = 0;
    // ADDR3 = 1;
    // ADDR2 = 1;
    // ADDR1 = 1;
    // ADDR0 = 0;
    P1 = (P1 & 0xe0) | 0x0e;    // LEDS6 on
    P0 = data;
}

bool key_get(uint8_t index) {
    P2 = 0xf7;
    uint8_t mask;
    switch(index) {
        case 0: mask = 0x10; break;
        case 1: mask = 0x20; break;
        default: mask = 0;
    }
    if(P2 & mask) return false;
    delay(5000);
    if(P2 & mask) return false;
    return true;
}

void main() {
    while(1) {
        if(key_get(K1)) {
            uint8_t led_data = 0x10;
            for(uint8_t i = 0; i < 4; ++i) {
                led_set(~led_data);
                led_data <<= 1;
                delay(15000);
            }
        }
        if(key_get(K2)) {
            uint8_t led_data = 0x01;
            for(uint8_t i = 0; i < 4; ++i) {
                led_set(~led_data);
                led_data <<= 1;
                delay(15000);
            }
        }
    }
}
1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-2-15 08:34:20 | 显示全部楼层
学习了
精彩

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-2-15 09:33:42 | 显示全部楼层
傻眼貓咪 发表于 2022-2-14 10:59
我上网爬文了关于流水LED代码如下,只是没有按键,可以自行修改代码,希望对你有帮助:

谢谢大佬  我找到问题所在了 我的程序没有给小灯归位
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-2-15 09:35:33 | 显示全部楼层
zzyet 发表于 2022-2-14 14:23
楼主代码里面的while(1)这个循环好像没有办法结束,进去这个循环以后,按K2还有反应吗?

并没有 不过我找到了问题所在 现在已经可以运行了 谢谢兄弟
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-2-15 09:38:40 | 显示全部楼层
人造人 发表于 2022-2-14 15:58
你的老师没有告诉过你吗?
读取外部输入之前自己要先输出高电平

定义的管脚默认高电平 我是想让他低电平流水点亮 现在已经可以运行了 谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-2-15 09:40:17 | 显示全部楼层
傻眼貓咪 发表于 2022-2-14 10:59
我上网爬文了关于流水LED代码如下,只是没有按键,可以自行修改代码,希望对你有帮助:

谢谢兄弟 问题已经解决了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-2-15 09:54:57 | 显示全部楼层
jhq999 发表于 2022-2-14 11:07
不懂单片机,为什么不这样写

问题已经解决了 谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-5 11:28

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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