【问题标题】:Serial Data with ArduinoArduino 的串行数据
【发布时间】:2013-02-18 17:20:03
【问题描述】:

我刚刚开始了解 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);
}

【问题讨论】:

  • 您是否使用 C 编译器编译过代码?你用什么编译器,在什么平台上?当您运行生成的可执行文件时会发生什么?
  • “代码显示不正确” - 如果格式正确,它会显示。
  • 感谢您正确格式化代码 Carbonic Acid (H2CO3)。
  • Halfer,我使用 Audrnio 附带的软件来编译和上传代码到板上,所以没有我知道的生成的可执行文件。如果您对代码的工作原理有所了解,将不胜感激。
  • 我自己没有使用过 Arduino 用户,但您是否阅读过它随附的入门指南,或者 Arduino 网站上的入门指南?将代码上传到开发板时是否出现任何错误? (我不希望您将原始 C 程序代码上传到板上,因此在某处必须有编译步骤,即使您有软件可以隐藏此过程)。

标签: serial-port arduino hardware-interface


【解决方案1】:

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

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

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

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


这一行将名为test 的变量(在PROGMEM - EEPROM 内存中)定义为一个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'),使用名为 pgm_read_dword_near 的 AVR 函数读取数组中位置 [i][j] 的值并发送将该值传递给函数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);

  }
}

【讨论】:

    【解决方案2】:

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

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

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

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

    高点和低点的时间由 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 种变体。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多