Datasheet
0/1 フォーマット
値 | HIGH/LOW | 概要 | 時間 | 誤差 |
---|---|---|---|---|
T0H | 0 | high voltage time | 0.40us | ±150ns |
T1H | 1 | high voltage time | 0.8us | ±150ns |
T0L | 0 | low voltage time | 0.85us | ±150ns |
T1L | 1 | low voltage time | 0.45us | ±150ns |
RES | low voltage time Above | 50µs |
データフォーマット
24bitの色データ
Green(8bit) | Red(8bit) | Blue(8bit) |
---|
データ構造
50usのRETが続いた場合、新しいデータとみなす。1つめのデータは、LED1が抜き取り発色する。2つめのデータは、2番目のLED2が抜き取り発色する。50us以内でデータを結合し、流すだけでマイコンが自分のデータを抜き出し発色する。
Delay
delayMicroseconds()
は、2usのdelayが可能。これだと遅すぎる。
ArduinoのUNOのクロックは、16MHz
1/16MHz = 0.0625us
1周期 0.0625us。
割り込みMacro
sei()
cli()
をつかって、処理中割り込みを防ぐ。
ArduinoのPORT
Sample
12個のLEDを光らすサンプルですが、変色、うまく色が出せない。
```cpp:sample
define PORTA1_HIGH 0b1
define PORTA1_LOW 0b0
define BYTENUMBER 8
define NUBEROFLED 12
const uint8_t bitShift = BYTENUMBER - 1 ;
uint8_t colorData[36] = {5,5,5,
5,5,5,
5,5,5,
5,5,5,
5,5,5,
5,5,5,
5,5,5,
5,5,5,
5,5,5,
5,5,5,
5,5,5,
5,5,5};
void setup() {
DDRC = 1; // PORTCを出力に
PORTC = 0b0; // PORTCに 00000000を設定(全部LOW)
}
void loop() {
sei();
for(int i = 0; i<NUBEROFLED; i++){
send(colorData[i*3], colorData[i*3+1], colorData[i*3+2]);
}
cli();
reset();
delay(100);
}
void send(uint8_t g, uint8_t r, uint8_t b){
for(int i = 0; i < BYTENUMBER; i++){
if(g & (1 << (bitShift-i))){
led_one();
} else {
led_zero();
}
}
for(int i = 0; i < BYTENUMBER; i++){
if(r & 1 << ((bitShift-i))){
led_one();
} else {
led_zero();
}
}
for(int i = 0; i < BYTENUMBER; i++){
if(b & 1 << ((bitShift-i))){
led_one();
} else {
led_zero();
}
}
}
void led_zero(){
// HIGH: 0.35us
PORTC |= PORTA1_HIGH; //T 2
asm(" nop"); //T 3
asm(" nop"); //T 4
asm(" nop"); //T 5
asm(" nop"); //T 6 6 * 0.0625 = 0.375us
// LOW: 0.8us
PORTC &= PORTA1_LOW; //T 8
asm(" nop"); //T 9
asm(" nop"); //T 10
asm(" nop"); //T 11
asm(" nop"); //T 12
asm(" nop"); //T 13
asm(" nop"); //T 14
asm(" nop"); //T 15
asm(" nop"); //T 16
asm(" nop"); //T 17
asm(" nop"); //T 18
asm(" nop"); //T 19 13 * 0.0625 = 0.8125us
}
void led_one(){
// HIGH 0.7us
PORTC |= PORTA1_HIGH; // T 2
asm(" nop"); // T 3
asm(" nop"); // T 4
asm(" nop"); // T 5
asm(" nop"); // T 6
asm(" nop"); // T 7
asm(" nop"); // T 8
asm(" nop"); // T 9
asm(" nop"); // T 10
asm(" nop"); // T 11 11 * 0.0625 = 0.6875us
// LOW 0.6us
PORTC &= PORTA1_LOW; // T 13
asm(" nop"); // T 14
asm(" nop"); // T 15
asm(" nop"); // T 16
asm(" nop"); // T 17
asm(" nop"); // T 18
asm(" nop"); // T 19
asm(" nop"); // T 20
//asm(" nop"); // T 21 10 * 0.0625 = 0.625
}
void reset(){
PORTC &= PORTA1_LOW;
for(int i = 0; i < 60; i++){
asm(" nop");
asm(" nop");
asm(" nop");
asm(" nop");
asm(" nop");
asm(" nop");
asm(" nop");
asm(" nop");
asm(" nop");
asm(" nop");
}
}
```
実行結果
highは狙った通りの状態になっていますが、lowは長くなる。24bit間の時間が3000usとなり大きく遅延する。LEDはRest状態だと勘違いしLEDがチラツキ始める。
原因
クロックは正常に動いているが、ビットを出力する前後に遅延があり、if文などの条件分岐やビット演算に時間がかかる。