我刚刚开始了解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);
}
答案 0 :(得分:1)
如果您不知道C和/或之前没有使用过Arduino,那么该代码不是一个好的起点。
Arduino编程语言(称为Wiring)将C代码的大量原始细节抽象为更简化的格式(和/或语言),这样初学者就可以更容易地使用他们的想法取得进展而不会被卡在“成为程序员。“接线代码在编译之前被解释为C代码,这使用户能够在一个草图中将C(和C ++)与Wiring混合。
上面的代码混合了C和Wiring语法,因此您无法在Arduino文档中找到有关语法的所有信息,但值得搜索您不理解的关键字或术语。不同的重要事情涉及设置和使用串行端口。请参阅Serial
的Arduino文档,了解它是如何完成的(以及了解它的简单程度)。
我将粗略地描述功能(在我太无聊之前)......
该行将名为PROGMEM
的变量(在test
- 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'),使用名为{{1的AVR函数读取位置[i] [j]处的数组中的值并将该值发送给函数pgm_read_dword_near
,该函数将其发送出串口。发送每个数组后,它会调用send_strip
以等待delay()
中定义的毫秒数。
rate
答案 1 :(得分: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)向LED条带的10个段发送10种颜色。对于1M条带,这应该是所有的LED。
PROGMEM长测试[10] [10]中的每一行都是Strip的一组颜色。在这种情况下,您有10个条带变体。
我目前正在使用此条带,所以如果需要更多示例或解释,请告诉我。