zhaohang 发表于 2022-5-3 16:15

想用单片机控制8个LED,使其产生流星灯的效果,但是没有思路

如题。大家有什么好的思路吗?谢谢啦!

uikyhuang 发表于 2022-5-3 16:31

啥叫流星灯?如果流水灯的话,最简单就是循环输出2进制码。

toyboy 发表于 2022-5-3 17:00

8个LED?为什么要用到单片机?NE555+CD4017不就可以了?

zhaohang 发表于 2022-5-3 17:43

uikyhuang 发表于 2022-5-3 16:31
啥叫流星灯?如果流水灯的话,最简单就是循环输出2进制码。

不是流水灯,是街上那种像彗星一样拖着尾巴的流星灯,挺漂亮的,也想弄一个,但是没有思路。

zhaohang 发表于 2022-5-3 17:44

toyboy 发表于 2022-5-3 17:00
8个LED?为什么要用到单片机?NE555+CD4017不就可以了?

我正在玩单片机。

dqp05 发表于 2022-5-3 17:48

定时器,每间隔一段时间,改变LED状态,就行了

whseen 发表于 2022-5-3 18:47

网上应该能找到类似的单片机程序,流水灯控制不难,可以兼顾步进电机。技术慢慢起来后,尝试无感开关磁阻电机,从步进加速后闭环调速,到电感测量定位。无感无刷永磁电机,要防止逆变桥短路。

阿甲 发表于 2022-5-3 18:50

控制流星灯是学单片机的第一个程序啊,定义好引脚,亮灯时间,关闭时间,,a++然后循环就行啊

uikyhuang 发表于 2022-5-3 20:28

zhaohang 发表于 2022-5-3 17:43
不是流水灯,是街上那种像彗星一样拖着尾巴的流星灯,挺漂亮的,也想弄一个,但是没有思路。 ...

你跑2~4个灯就像了?

uikyhuang 发表于 2022-5-3 20:31

阿甲 发表于 2022-5-3 18:50
控制流星灯是学单片机的第一个程序啊,定义好引脚,亮灯时间,关闭时间,,a++然后循环就行啊 ...

刚开始也是学循环,但是后来看到最简单是用p0~p7输出2进制
00000000
10000000
01000000
00100000

00000001
00000000

cyradg 发表于 2022-5-4 21:04

流星灯是前面的LED显示更亮?后面显示更暗?如果是要多个脚输出PWM波形了,这就复杂了,这个和流水灯(跑马灯)可不是一回事,跑马灯是IO口的基本操作,学习单片机的第一个实战课就是这个。要使多个引脚输出PWM波形,AVR的时钟数量不够,好像只有三个,STM的时钟倒是挺多的。

cyradg 发表于 2022-5-4 21:19

本帖最后由 cyradg 于 2022-5-4 21:32 编辑

或者在main里面定义几个变量,通过不同变量来设置不同IO输出高电平和低电平的时间来模拟PWM,虽然频率精确度,模拟流星灯估计还行。比如变量1:uint16_t IO1,或者u16 IO1,变量2:uint16_t IO2,或者u16 IO2,具体看你使用什么单片机开发环境,然后在循环体里对IO1,IO2循环计数,比如IO1是 0~400输出高电平,401~65535输出低电平,用来模拟IO1口输出PWM波形,依此类推。。。。AVR芯片主频不高,输出PWM波形频率不会太高,也不准确,但是亮个灯足够了,弄个Attiny之类的单片机足够了,价格便宜。

cyradg 发表于 2022-5-4 22:01

以AVR为例,输出口为PB口的PB0..PB3共四个口
typedef struct
{
      uint8_t IO0:1;       //PB0口
      uint8_t IO1:1;       //PB1口
      uint8_t IO2:1;       //PB2口
      uint8_t IO3:1;       //PB3口
      uint8_t Reserver:4;   //PB4..PB7口
}IO_TypeDef;

#define IOPORT((volatile IO_TypeDef *)&PORTB)

int main(void)
{
      DDRB |=0xF;      //设置PB0..PB4为输出
      PORTB=0;          //设置PB口全部输出0
      uint8_t IO0=0;
      uint8_t IO1=0;
      uint8_t IO2=0;
      uint8_t IO3=0;
      while(1)
      {
            if (IO0==255) IO0=0;
            IO0++;
            if (IO0<=100)IOPORT ->IO0=1;    //如果IO0变量小于等于100,PB0引脚输出1
            else IOPORT->IO0=0;                     //如果IO0大于100小于255,PB0引脚输出0
            //PB1,PB2,PB3引脚类似操作
       }
}

如果是STM32,那就要用GPIOx去操作了,开启IO时钟,设置IO输出方向,然后用BSRR寄存器设置输出高低电平,虽然比AVR复杂些,基本也差不多。

hfshen 发表于 2022-5-5 09:23

楼主叫这种为流星灯,我叫余辉灯,就是第一个灯全亮,后边几个逐个变暗。
下边是多年前玩STC单片机写的练习,供参考。
思路:通过控制LED灯的点亮时间长短控制其亮度。
当然也可以用PWM,用占空比控制。

/*******************************************************************************
*描述:   余辉跑马灯程序                                                          *
*连接方法: JP11(P2)和JP1(LED灯) 用8PIN排线连接起来                                                   *
*                                                                                                                                                           *
*******************************************************************************/

#include<reg51.h>
#include <intrins.h>

/*****************************************************************************
*延时子程序                                                                                                                             *
*                                                                                                                                                       *
******************************************************************************/
void delayms(unsigned char ms)
{
        unsigned char i;
        while(ms--)
        {
        for(i = 0; i < 120; i++);
        }
}

/*****************************************************************************
*主程序                                                                                                                                 *
*                                                                                                                                                       *
******************************************************************************/
main()
{
        unsigned char LED1,LED2,LED3,TM;
        unsigned char i;
        LED1 = 0xfe;
        LED2 = 0xfc;
        LED3 = 0xf8;
        P2 = LED1;
        while(1)
        {
                for(i = 0; i < 10; i++) {
                        delayms(5);
                        P2 = LED1;
                        delayms(5);
                        P2 = LED2;
                        delayms(2);
                        P2 = LED1;
                        delayms(5);
                        P2 = LED3;
                        delayms(2);
                        P2 = LED1;
                        delayms(5);
                }
                LED1 = _cror_(LED1,1);
                LED2 = _cror_(LED2,1);
                LED3 = _cror_(LED3,1);
        }
}

uikyhuang 发表于 2022-5-5 12:06

cyradg 发表于 2022-5-4 21:04
流星灯是前面的LED显示更亮?后面显示更暗?如果是要多个脚输出PWM波形了,这就复杂了,这个和流水灯(跑马 ...

在led脚上并几十微法电容可以起廷时和渐暗效果。流星灯感觉8个不太够。

dqp05 发表于 2022-5-5 13:15

好像每个灯的亮度也不一样;

捱多年 发表于 2022-5-9 18:52

每个灯不再一个bit而是给它一个byte,每扫描一次减1

kpj001 发表于 2022-5-9 19:57

4颗一组模拟流星,第一颗高亮,后面依次减弱。然后整组定时位移。普通led单色不说,亮度还需要PWM控制,比较麻烦。WS2812实现就很容易了,也有专门的库,直接调用即可,比如 arafruit_neopixel 考虑到这个是单片机入门例程,而你一点思路都没有,还是劝退。直接买蓝牙 WS2812 控制器,手机app控制,花样足够多。

zhaohang 发表于 2022-5-25 22:36

流星灯终于成功了!原来想复杂了,其实可以简单实现。用面包板、8个直径3mm的LED、STC11F02E做的。用Keil、C语言编程,程序如下:
#include<reg52.h>
sbit led1=P1^0;
sbit led2=P1^1;
sbit led3=P1^2;
sbit led4=P1^3;
sbit led5=P1^4;
sbit led6=P1^5;
sbit led7=P1^6;
sbit led8=P1^7;
unsigned int i;
void delay(i)
{
while(20*i--);
}
void main()
{
led1=0;               //1灯亮
delay(6400);

led2=0;                //2灯亮
delay(5600);
led1=1;
delay(800);

led3=0;   //3灯亮
led1=0;
delay(4800);
led1=1;
delay(800);
led2=1;
delay(800);

led4=0;   //4灯亮
led1=0;
led2=0;
delay(4000);
led1=1;
delay(800);
led2=1;
delay(800);
led3=1;
delay(800);

led5=0;   //5灯亮
led1=0;
led2=0;
led3=0;
delay(3200);
led1=1;
delay(800);
led2=1;
delay(800);
led3=1;
delay(800);
led4=1;
delay(800);

led6=0;   //6灯亮
led1=0;
led2=0;
led3=0;
led4=0;
delay(2400);
led1=1;
delay(800);
led2=1;
delay(800);
led3=1;
delay(800);
led4=1;
delay(800);
led5=1;
delay(800);

led7=0;   //7灯亮
led1=0;
led2=0;
led3=0;
led4=0;
led5=0;
delay(1600);
led1=1;
delay(800);
led2=1;
delay(800);
led3=1;
delay(800);
led4=1;
delay(800);
led5=1;
delay(800);
led6=1;
delay(800);

led8=0;   //8灯亮
led1=0;
led2=0;
led3=0;
led4=0;
led5=0;
led6=0;
delay(800);
led1=1;
delay(800);
led2=1;
delay(800);
led3=1;
delay(800);
led4=1;
delay(800);
led5=1;
delay(800);
led6=1;
delay(800);
led7=1;
delay(800);
   
led2=0;   //7灯亮
led3=0;
led4=0;
led5=0;
led6=0;
led7=0;
delay(800);
led2=1;
delay(800);
led3=1;
delay(800);
led4=1;
delay(800);
led5=1;
delay(800);
led6=1;
delay(800);
led7=1;
delay(800);
led8=1;
delay(800);
   
led3=0; //6灯亮
led4=0;
led5=0;
led6=0;
led7=0;
led8=0;
delay(800);
led3=1;
delay(800);
led4=1;
delay(800);
led5=1;
delay(800);
led6=1;
delay(800);
led7=1;
delay(800);
led8=1;
delay(1600);
   
led4=0;//5灯亮
led5=0;
led6=0;
led7=0;
led8=0;
delay(800);
led4=1;
delay(800);
led5=1;
delay(800);
led6=1;
delay(800);
led7=1;
delay(800);
led8=1;
delay(2400);

led5=0;   //4灯亮
led6=0;
led7=0;
led8=0;
delay(800);
led5=1;
delay(800);
led6=1;
delay(800);
led7=1;
delay(800);
led8=1;
delay(3200);

led6=0;   //3灯亮
led7=0;
led8=0;
delay(800);
led6=1;
delay(800);
led7=1;
delay(800);
led8=1;
delay(4000);

led7=0;   //2灯亮
led8=0;
delay(800);
led7=1;
delay(800);
led8=1;
delay(4800);

led8=0;   //1灯亮
delay(800);
led8=1;
delay(5600);
}

zhaohang 发表于 2022-5-25 22:37

流星灯终于成功了!原来想复杂了,其实可以简单实现。用面包板、8个直径3mm的LED、STC11F02E做的。用Keil、C语言编程,程序如下:
#include<reg52.h>
sbit led1=P1^0;
sbit led2=P1^1;
sbit led3=P1^2;
sbit led4=P1^3;
sbit led5=P1^4;
sbit led6=P1^5;
sbit led7=P1^6;
sbit led8=P1^7;
unsigned int i;
void delay(i)
{
while(20*i--);
}
void main()
{
led1=0;               //1灯亮
delay(6400);

led2=0;                //2灯亮
delay(5600);
led1=1;
delay(800);

led3=0;   //3灯亮
led1=0;
delay(4800);
led1=1;
delay(800);
led2=1;
delay(800);

led4=0;   //4灯亮
led1=0;
led2=0;
delay(4000);
led1=1;
delay(800);
led2=1;
delay(800);
led3=1;
delay(800);

led5=0;   //5灯亮
led1=0;
led2=0;
led3=0;
delay(3200);
led1=1;
delay(800);
led2=1;
delay(800);
led3=1;
delay(800);
led4=1;
delay(800);

led6=0;   //6灯亮
led1=0;
led2=0;
led3=0;
led4=0;
delay(2400);
led1=1;
delay(800);
led2=1;
delay(800);
led3=1;
delay(800);
led4=1;
delay(800);
led5=1;
delay(800);

led7=0;   //7灯亮
led1=0;
led2=0;
led3=0;
led4=0;
led5=0;
delay(1600);
led1=1;
delay(800);
led2=1;
delay(800);
led3=1;
delay(800);
led4=1;
delay(800);
led5=1;
delay(800);
led6=1;
delay(800);

led8=0;   //8灯亮
led1=0;
led2=0;
led3=0;
led4=0;
led5=0;
led6=0;
delay(800);
led1=1;
delay(800);
led2=1;
delay(800);
led3=1;
delay(800);
led4=1;
delay(800);
led5=1;
delay(800);
led6=1;
delay(800);
led7=1;
delay(800);
   
led2=0;   //7灯亮
led3=0;
led4=0;
led5=0;
led6=0;
led7=0;
delay(800);
led2=1;
delay(800);
led3=1;
delay(800);
led4=1;
delay(800);
led5=1;
delay(800);
led6=1;
delay(800);
led7=1;
delay(800);
led8=1;
delay(800);
   
led3=0; //6灯亮
led4=0;
led5=0;
led6=0;
led7=0;
led8=0;
delay(800);
led3=1;
delay(800);
led4=1;
delay(800);
led5=1;
delay(800);
led6=1;
delay(800);
led7=1;
delay(800);
led8=1;
delay(1600);
   
led4=0;//5灯亮
led5=0;
led6=0;
led7=0;
led8=0;
delay(800);
led4=1;
delay(800);
led5=1;
delay(800);
led6=1;
delay(800);
led7=1;
delay(800);
led8=1;
delay(2400);

led5=0;   //4灯亮
led6=0;
led7=0;
led8=0;
delay(800);
led5=1;
delay(800);
led6=1;
delay(800);
led7=1;
delay(800);
led8=1;
delay(3200);

led6=0;   //3灯亮
led7=0;
led8=0;
delay(800);
led6=1;
delay(800);
led7=1;
delay(800);
led8=1;
delay(4000);

led7=0;   //2灯亮
led8=0;
delay(800);
led7=1;
delay(800);
led8=1;
delay(4800);

led8=0;   //1灯亮
delay(800);
led8=1;
delay(5600);
}
页: [1] 2
查看完整版本: 想用单片机控制8个LED,使其产生流星灯的效果,但是没有思路