0

我刚刚开始了解 Arduino。我有一个来自 Radio Shack 的 1 米长的 LED 灯带可以玩。

该条带有一个示例程序,因此我查看了它并将其缩减为基础知识,但我不明白发生了什么。我正在找人解释发生了什么以及功能代码是如何工作的。

这是代码:

#include <avr/pgmspace.h>

#define DATA_1 (PORTC |=  0X01)
#define DATA_0 (PORTC &=  0XFE)
#define STRIP_PINOUT (DDRC=0xFF)

/*
green 0xff0000
cyan 0xff7f00
truquoise 0xffff00
dark blue 0x00ff00
red 0x0000ff
dark yellow 0x6f00ff
yellow 0x8f00ff
white 0xffffff
off white 0x444444
dim white 0x111111
off 0x000000
*/

PROGMEM long test[10][10]={
  {0x000000,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00},
  {0x00ff00,0x000000,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00},
  {0x00ff00,0x00ff00,0x000000,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00},
  {0x00ff00,0x00ff00,0x00ff00,0x000000,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00},
  {0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x000000,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00},
  {0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x000000,0x00ff00,0x00ff00,0x00ff00,0x00ff00},
  {0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x000000,0x00ff00,0x00ff00,0x00ff00},
  {0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x000000,0x00ff00,0x00ff00},
  {0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x000000,0x00ff00},
  {0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x00ff00,0x000000},
};

void setup() {

  STRIP_PINOUT;

  reset_strip();

}


void loop() 
{
  while (1)
  {
    send_pattern(test, 10, 50);
    reset_strip();
  }
}


void send_pattern(long data[][10], int length, int rate)
{
  int i=0;
  int j=0;

  for (i=0; i<length; i++)
  {
    noInterrupts();
    for (j=0; j<10; j++)
    {
      send_strip(pgm_read_dword_near(&data[i][j]));
    }
    interrupts();

    delay(rate);

  }




}


void send_strip(uint32_t data)
{
  int i;
  unsigned long j=0x800000;

  for (i=0;i<24;i++)
  {
    if (data & j)
    {
      DATA_1;
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");    
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      DATA_0;
    }
    else
    {
      DATA_1;
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");
      __asm__("nop\n\t");    
      DATA_0;
    }

    j>>=1;
  }
}


void reset_strip()
{
  DATA_0;
  delayMicroseconds(20);
}
4

2 回答 2

1

如果您不了解 C 和/或以前没有使用过 Arduino,那么该代码不是一个好的起点。

Arduino 编程语言(称为 Wiring)将 C 代码的许多原始细节抽象为更简化的格式(和/或语言),以便初学者更容易在他们的想法上取得进展,而不会陷入“成为程序员”的困境。 " Wiring 代码在编译之前被解释为 C 代码,这使用户能够在一个草图中将 C(和 C++)与 Wiring 混合。

您上面的代码混合了 C 和 Wiring 语法,因此您不会在 Arduino 文档中找到有关语法的所有信息,但值得搜索您不理解的关键字或术语。不同之处在于设置和使用串行端口。请参阅 Arduino 文档Serial以了解它是如何在其中完成的(以及理解起来有多简单)。

我将粗略地描述一下功能(在我太无聊之前)......


这一行定义了一个变量(在PROGMEMEEPROM 内存中),命名test为 10 x 10 的数字数组(longs):例如,有 10 个数组,每个数组包含 10 个数字(以十六进制表示)

PROGMEM long test[10][10]={

这个块调用一个函数(代码顶部的#defined)来设置一个端口)和一个函数(在代码的底部)来重置条带。

void setup() 
  STRIP_PINOUT;
  reset_strip();
}

void loop() 
{
  while (1) // i.e. do this forever
  {
    // send the test var, its length and the delay amount between each pattern
    send_pattern(test, 10, 50); 
    reset_strip();
  }
}

此函数遍历传递的 var data(在本例中为 var 'test'),使用调用的 AVR 函数读取数组中位置 [i][j] 处的pgm_read_dword_near值,并将该值发送到将send_strip其发送出去的函数串口。发送每个数组后,它会调用delay()等待rate.

void send_pattern(long data[][10], int length, int rate)
{
  int i=0;
  int j=0;

  for (i=0; i<length; i++)
  {
    noInterrupts();
    for (j=0; j<10; j++)
    {
      send_strip(pgm_read_dword_near(&data[i][j]));
    }
    interrupts();

    delay(rate);

  }
}
于 2013-02-19T10:50:51.640 回答
0

一米长的 LED 灯条有 10 段,每段有 3 个 LED,所以即使总共有 30 个 LED,您也只能控制 10 段。

LED 灯条有红(电源)、黑(地)和绿(信号)三根线。

每个段采用 24 位十六进制数来确定 LED 的颜色。当一个段获得它的 24 位时,它会设置它的颜色,然后将其余的信号传输到下一个段。

信号为高电平或低电平,但对于接收信号的芯片,它通过高电平然后低电平的时间长度来确定它是 1 还是零。条带随附的手册用图片更好地解释了这一点。

Highs 和 Lows 的时间由 void send_strip(uint32_t data) 方法控制。告诉微__asm__("nop\n\t")控制器基本上浪费了一个周期,所以它基本上是一个非常短的延迟(在 16MHz Arduino 上为 62.5ns)。我不得不使用 send_strip() 方法来获得正确的时间,否则所有的 LED 都会变成全白。

void send_pattern(long data[][10], int length, int rate) 将 10 种颜色发送到 LED 灯条的 10 段。对于 1M 灯条,这应该是所有的 LED。

PROGMEM long test[10][10] 中的每一行都是 Strip 的一组颜色。在这种情况下,您有 10 种条带变体。

我目前正在玩这条带,所以如果需要更多示例或解释,请告诉我。

于 2014-01-29T22:38:17.927 回答