ポートレジスタを操作すれば digitalRead() / digitalWrite() を高速化できます。
例えば LED を本当に同時に点灯させる必要がある場合や、ボタンの入力を高速に読み取る必要がある時に使えますが、MCU の違いによって操作するポートレジスタが異なります。
ピンとポートの対応表です。AVR 系 Arduino で使われている・・・を比較してみます。
PIN | 328P | 32U4 | 2560 | 4809 |
D0 | PD0 | PD2 | PE0 | PC5 |
D1 | PD1 | PD3 | PE1 | PC4 |
D2 | PD2 | PD1 | PE4 | PA0 |
D3 | PD3 | PD0 | PE5 | PF5 |
D4 | PD4 | PD4 | PG5 | PC6 |
D5 | PD5 | PC6 | PE3 | PB2 |
D6 | PD6 | PD7 | PH3 | PF4 |
D7 | PD7 | PE6 | PH4 | PA1 |
PIN | 328P | 32U4 | 2560 | 4809 |
D8 | PB0 | PB4 | PH5 | PE3 |
D9 | PB1 | PB5 | PH6 | PB0 |
D10 | PB2 | PB6 | PB4 | PB1 |
D11 | PB3 | PB7 | PB5 | PE0 |
D12 | PB4 | PD6 | PB6 | PE1 |
D13 | PB5 | PC7 | PB7 | PE2 |
PIN | 328P | 32U4 | 2560 | 4809 |
D14 | PJ1 | |||
D15 | PJ0 | |||
D16 | PH1 | |||
D17 | PH0 | |||
D18 | PD3 | |||
D19 | PD2 | |||
D20 | PD1 | |||
D21 | PD0 |
PIN | 328P | 32U4 | 2560 | 4809 |
D22 | PA0 | |||
D23 | PA1 | |||
D24 | PA2 | |||
D25 | PA3 | |||
D26 | PA4 | |||
D27 | PA5 | |||
D28 | PA6 | |||
D29 | PA7 | |||
D30 | PC7 | |||
D31 | PC6 | |||
D32 | PC5 | |||
D33 | PC4 | |||
D34 | PC3 | |||
D35 | PC2 | |||
D36 | PC1 | |||
D37 | PC0 | |||
D38 | PD7 | |||
D39 | PG2 | |||
D40 | PG1 | |||
D41 | PG0 | |||
D42 | PL7 | |||
D43 | PL6 | |||
D44 | PL5 | |||
D45 | PL4 | |||
D46 | PL3 | |||
D47 | PL2 | |||
D48 | PL1 | |||
D49 | PL0 | |||
D50 | PB3 | |||
D51 | PB2 | |||
D52 | PB1 | |||
D53 | PB0 |
PIN | 328P | 32U4 | 2560 | 4809 |
A0 | PC0 | PF7 | PF0 | PD3 |
A1 | PC1 | PF6 | PF1 | PD2 |
A2 | PC2 | PF5 | PF2 | PD1 |
A3 | PC3 | PF4 | PF3 | PD0 |
A4 | PC4 | PF1 | PF4 | PA2 PF2 |
A5 | PC5 | PF0 | PF5 | PA3 PF3 |
A6 | PF6 | PD4 | ||
A7 | PF7 | PD5 |
PIN | 328P | 32U4 | 2560 | 4809 |
A8 | PK0 | |||
A9 | PK1 | |||
A10 | PK2 | |||
A11 | PK3 | |||
A12 | PK4 | |||
A13 | PK5 | |||
A14 | PK6 | |||
A15 | PK7 |
PIN | 328P | 32U4 | 2560 | 4809 |
SDA | PC4 | PD1 | PD1 | |
SCL | PC5 | PD0 | PD0 |
PIN | 328P | 32U4 | 2560 | 4809 |
RESET | PC6 | PF6 |
PIN | 328P | 32U4 | 2560 | 4809 |
(ICSP) MISO | PB3 | PB3 | PB3 | |
(ICSP) SCLK | PB1 | PB1 | PB1 | |
(ICSP) MOSI | PB2 | PB2 | PB2 |
328P 以外はキレイに並んでいるとは言い難いです。
ポートとピンの対応表です。
PORT A | ||||||||
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 | |
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | |
328P | ||||||||
32U4 | ||||||||
2560 | D29 | D28 | D27 | D26 | D25 | D24 | D23 | D22 |
4809 | [A5] | [A4] | D7 | D2 |
PORT B | ||||||||
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 | |
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | |
328P | (ICSP) SCLK D13 |
(ICSP) MISO D12 |
(ICSP) MOSI D11 |
D10 | D9 | D8 | ||
32U4 | D11 | D10 | D9 | D8 | (ICSP) MISO | (ICSP) MOSI | (ICSP) SCLK | (TX LED) |
2560 | D13 | D12 | D11 | D10 | (ICSP) MISO D50 |
(ICSP) MOSI D51 |
(ICSP) SCLK D52 |
D53 |
4809 | D5 | D10 | D9 |
PORT C | ||||||||
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 | |
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | |
328P | (RESET) | SCL A5 |
SDA A4 |
A3 | A2 | A1 | A0 | |
32U4 | D13 | D5 | ||||||
2560 | D30 | D31 | D32 | D33 | D34 | D35 | D36 | D37 |
4809 | D4 | D0 | D1 |
PORT D | ||||||||
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 | |
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | |
328P | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
32U4 | D6 | D12 | (RX LED) | D4 | D1 | D0 | SCL D2 |
SDA D3 |
2560 | D18 | D19 | SCL D20 |
SDA D21 |
||||
4809 | A8 | A7 | A6 | A0 | A1 | A2 | A3 |
PORT E | ||||||||
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 | |
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | |
328P | ||||||||
32U4 | D7 | |||||||
2560 | D3 | D2 | D5 | D1 | D0 | |||
4809 | D8 | D13 | D12 | D11 |
PORT F | ||||||||
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 | |
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | |
328P | ||||||||
32U4 | A0 | A1 | A2 | A3 | A4 | A5 | ||
2560 | A7 | A6 | A5 | A4 | A3 | A2 | A1 | A0 |
4809 | (RESET) | D3 | D6 | [A5] | [A4] |
PORT G | ||||||||
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 | |
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | |
328P | ||||||||
32U4 | ||||||||
2560 | D4 | D40 | D41 | |||||
4809 |
PORT H | ||||||||
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 | |
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | |
328P | ||||||||
32U4 | ||||||||
2560 | D9 | D8 | D7 | D6 | D16 | D17 | ||
4809 |
PORT J | ||||||||
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 | |
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | |
328P | ||||||||
32U4 | ||||||||
2560 | D14 | D15 | ||||||
4809 |
PORT K | ||||||||
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 | |
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | |
328P | ||||||||
32U4 | ||||||||
2560 | A15 | A14 | A13 | A12 | A11 | A10 | A9 | A8 |
4809 |
PORT L | ||||||||
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 | |
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | |
328P | ||||||||
32U4 | ||||||||
2560 | D42 | D43 | D44 | D45 | D46 | D47 | D48 | D49 |
4809 |
入出力の方向です。1 が出力 (OUTPUT)、0 が入力 (INPUT) です。DDRB は ポート B の入出力の方向を調べたり変更したりできます。機能的には pinMode() と同等です。
ピンの状態です。1 が HIGH 、0 が LOW です。PORTB は入出力の方向が出力 (OUTPUT) になっているポート B のピンの状態を調べたり変更したりできます。機能的には digitalRead() / digitalWrite() と同等です。
入力状態です。1 が HIGH 、0 が LOW です。PINB はポート B のピンの状態を調べられます。機能的には digitalRead() と同等です。
ATMega4809 では ATMega328P エミュレーションでないと上記ポート操作ができません。ATMega4809 でネイティブなポート操作を行うには VPORTx を使います。これはポートレジスタを I/O 空間にマップした仮想ポートです。
入出力の方向です。1 が出力 (OUTPUT)、0 が入力 (INPUT) です。VPORTB.DIR は ポート B の入出力の方向を調べたり変更したりできます。機能的には pinMode() と同等です。
ピンの状態です。1 が HIGH 、0 が LOW です。VPORTB.OUT は入出力の方向が出力 (OUTPUT) になっているポート B のピンの状態を調べたり変更したりできます。機能的には digitalRead() / digitalWrite() と同等です。
入力状態です。1 が HIGH 、0 が LOW です。VPORTB.IN はポート B のピンの状態を調べられます。機能的には digitalRead() と同等です。
例えば以下のようなコードがあったとします。UNO の MCU は ATMega328P です。
|
digitalWrite() で置き換えると以下のようになります。
|
UNO のボード画像の一部です。
SS ピンは D10 を使っています。UNO なので PB2、つまり PORT B の 2bit 目を操作しています。最下位ビットは bit0 なので 4 を OR したりビット反転した 4 を AND していたりします。
PORT B | |||||||
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
RST ピンは D9 を使っています。UNO なので PB1、つまり PORT B の 1bit 目を操作しています。最下位ビットは bit0 なので 2 を OR したりビット反転した 2 を AND していたりします。
PORT B | |||||||
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
それを踏まえると LEONARDO (ATMega32U4) では以下のようなコードになります。
|
LEONARDO のボード画像の一部です。
SS ピンは D10 を使っています。LEONARDO なので PB6、つまり PORT B の 6bit 目を操作しています。最下位ビットは bit0 なので 64 を OR したりビット反転した 64 を AND します。
PORT B | |||||||
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
RST ピンは D9 を使っています。LEONARDO なので PB5、つまり PORT B の 5bit 目を操作しています。最下位ビットは bit0 なので 32 を OR したりビット反転した 32 を AND します。
PORT B | |||||||
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
さらに MEGA2560 (ATMega2560) では以下のようなコードになります。
|
MEGA2560 のボード画像の一部です。
SS ピンは D10 を使っています。MEGA2560 なので PB4、つまり PORT B の 4bit 目を操作しています。最下位ビットは bit0 なので 16 を OR したりビット反転した 16 を AND します。
PORT B | |||||||
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
RST ピンは D9 を使っています。MEGA2560 なので PH6、つまり PORT H の 6bit 目を操作しています。最下位ビットは bit0 なので 64 を OR したりビット反転した 64 を AND します。
PORT H | |||||||
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
Nano Every (ATMega4809) では ATMega328 エミュレーションを使えばコードの修正は不要です。
|
ATMega328 エミュレーションを使わない場合には、VPORT を使った次のようなコードになります。
|
Nano Every のボード画像の一部です。
SS ピンは D10 を使っています。Nano Every なので PB1、つまり PORT B の 1bit 目を操作しています。最下位ビットは bit0 なので 2 を OR したりビット反転した 2 を AND していたりします。
PORT B | |||||||
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
RST ピンは D9 を使っています。Nano Every なので PB0、つまり PORT B の 0bit 目を操作しています。最下位ビットは bit0 なので 1 を OR したりビット反転した 1 を AND していたりします。
PORT B | |||||||
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
ここにある情報が役に立って、「調べる手間が省けたからオマイに飯でもおごってやるよ」 というハートウォーミングな方がいらっしゃいましたら、下のボタンからどうぞ。