Arduinoは遅すぎて処理が追いつかない、クソじゃねーか!ってことで標準入出力を高速化しましょう。レジスタからピンを操作すれば複数のピンを同時に制御することも出来ます。
デジタル出力(digitalWrite)を高速化
まずは普通のLチカ
void setup() { pinMode(8, OUTPUT); } void loop() { digitalWrite(8,HIGH); delay(500); digitalWrite(8,LOW); delay(500); }
同じ処理をavrっぽく書くと処理を高速化することが出来ます。
void setup() { DDRB |= 0b00000001;//ポートBの0番ピン(Arduinoの8番ピン)をOUTPUT } void loop() { PORTB |= 0b00000001;//ポートBの0番ピン(Arduinoの8番ピン)をHIGH delay(500); PORTB &= ~0b00000001;//ポートBの0番ピン(Arduinoの8番ピン)をLOW delay(500) }
DDRB,DDRDでポートB,ポートCの入力,出力を決めます。二進数で表すと0b00000000の右から0番ピン、1番ピンの順で対応しています。0は入力、1は出力
Arduino UnoではdigitalWrite(pin,HIGH)は以下のように対応しています。
Arduino | レジスタ表記 |
digitalWrite(0, HIGH ) | PORTD |= 0b00000001 |
digitalWrite(1, HIGH ) | PORTD |= 0b00000010 |
digitalWrite(2, HIGH ) | PORTD |= 0b00000100 |
digitalWrite(3, HIGH ) | PORTD |= 0b00001000 |
digitalWrite(4, HIGH ) | PORTD |= 0b00010000 |
digitalWrite(5, HIGH ) | PORTD |= 0b00100000 |
digitalWrite(6, HIGH ) | PORTD |= 0b01000000 |
digitalWrite(7, HIGH ) | PORTD |= 0b10000000 |
digitalWrite(8, HIGH ) | PORTB |= 0b00000001 |
digitalWrite(9, HIGH ) | PORTB |= 0b00000010 |
digitalWrite(10, HIGH ) | PORTB |= 0b00000100 |
digitalWrite(11, HIGH ) | PORTB |= 0b00001000 |
digitalWrite(12, HIGH ) | PORTB |= 0b00010000 |
digitalWrite(13, HIGH ) | PORTB |= 0b00100000 |
digitalWrite(pin,LOW)については以下の表のようになります。
Arduino | レジスタ表記 |
digitalWrite(0,LOW) | PORTD &= ~ 0b00000001 |
digitalWrite(1, LOW ) | PORTD &= ~ 0b00000010 |
digitalWrite(2, LOW ) | PORTD &= ~ 0b00000100 |
digitalWrite(3, LOW ) | PORTD &= ~ 0b00001000 |
digitalWrite(4, LOW ) | PORTD &= ~ 0b00010000 |
digitalWrite(5, LOW ) | PORTD &= ~ 0b00100000 |
digitalWrite(6, LOW ) | PORTD &= ~ 0b01000000 |
digitalWrite(7, LOW ) | PORTD &= ~ 0b10000000 |
digitalWrite(8, LOW ) | PORTB &= ~ 0b00000001 |
digitalWrite(9, LOW ) | PORTB &= ~ 0b00000010 |
digitalWrite(10, LOW ) | PORTB &= ~ 0b00000100 |
digitalWrite(11, LOW ) | PORTB &= ~ 0b00001000 |
digitalWrite(12, LOW ) | PORTB &= ~ 0b00010000 |
digitalWrite(13, LOW ) | PORTB &= ~ 0b00100000 |
Arduino Uno以外は異なるので、arduinoとavr のピン対応を調べてから書きましょう。
複数のピンを同時に操作
レジスタから操作すると複数のピンを同時に変更できます。以下は2番ピンから13番ピンを全て使ったLチカのスケッチです。ただし、全てのピンにLEDをつけると電流が流れすぎるので大きな抵抗を使いましょう。
void setup() { DDRD |= 0b11111100;//ポートDの2~7番ピンをOUTPUT DDRB |= 0b00011111;//ポートBの0~4番ピンをOUTPUT } void loop() { PORTD |= 0b11111100;//ポートDの2~7番ピンをHIGH PORTB |= 0b00011111;//ポートBの0~4番ピンをHIGH delay(500); PORTD &= ~0b11111100;//ポートDの2~7番ピンをLOW PORTB &= ~0b00011111;//ポートBの0~4番ピンをLOW delay(500) }
デジタル入力(digitalRead)を高速化
bool state = 0; void setup() { DDRB = 0b00000000;//ポートBを全てINPUT } void loop() { state = (PINB>>1) & 0b00000001;//state = digitalRead(9)と同じ }
digitalRead | レジスタ表記 |
digitalRead(0) | PIND & 0b00000001 |
digitalRead(1) | (PIND>>1) & 0b00000001 |
digitalRead(2) | (PIND>>2) & 0b00000001 |
digitalRead(3) | (PIND>>3) & 0b00000001 |
digitalRead(4) | (PIND>>4) & 0b00000001 |
digitalRead(5) | (PIND>>5) & 0b00000001 |
digitalRead(6) | (PIND>>6) & 0b00000001 |
digitalRead(7) | (PIND>>7) & 0b00000001 |
digitalRead(8) | PINB & 0b00000001 |
digitalRead(9) | (PINB>>1) & 0b00000001 |
digitalRead(10) | (PINB>>2) & 0b00000001 |
digitalRead(11) | (PINB>>3) & 0b00000001 |
digitalRead(12) | (PINB>>4) & 0b00000001 |
digitalRead(13) | (PINB>>5) & 0b00000001 |
リンク
↓ArduinoでAVRのように表記すれば、処理を高速化したりといろいろ便利なことがあると思います。
リンク
コメント