1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

LED点灯

Last updated at Posted at 2019-07-19

概要

ここまで,Arduinoでのブートシーケンスに従いアセンブリ言語でプログラムを記述し,C言語で定義したmain関数を呼び出すところまで作成した.そして,gdbを使って実際にmain関数が呼び出されるところまで確認した.ここでは,実際にArduino Unoを使用して,組み込み開発のHello Worldである,LEDの点灯をやってみる.

LEDを点灯させる

LEDを点灯させるには,以下のプログラムを追加します.

led.s
lightOn:
        ldi     R16,    0b00100000 ; PB5 is Output, Others are Input
        out     0x04,   R16        ; 0x04 = DDRB
        ldi     R16,    0b00100000 ; PB5 is High (1 = High, 0 = Low)
        out     0x05,   R16        ; 0x05 = PORTB
        ret

そして,mainからこの関数を呼び出します.

main.c
void lightOn(void);

int main(void) {
    lightOn();
    return 0;
}

そして,PCにArduino Unoをつないで,avrdudeで書き込みます(以下のDEVは環境に合わせる)

PREFIX = avr-elf
BASEDIR = /usr/local/core/$(PREFIX)
BINDIR = $(BASEDIR)/bin

AS = $(BINDIR)/avr-as
NM = $(BINDIR)/avr-nm
CC = $(BINDIR)/avr-gcc
LD = $(BINDIR)/avr-ld
AVRDUDE = $(BINDIR)/avrdude
CONF = $(BASEDIR)/etc/avrdude.conf
READELF = $(BINDIR)/avr-readelf
OBJDUMP = $(BINDIR)/avr-objdump
OBJCOPY = $(BINDIR)/avr-objcopy
GDB = $(BINDIR)/avr-gdb
DEV=/dev/cu.usbmodem142101 # PORT

(略)
write:
	$(AVRDUDE) -C $(CONF) -c arduino -P $(DEV) -p m328p -b 115200 -D -U flash:w:$(TARGET).hex:i

これで

>make write

とすると,Arduinoにプログラムが書き込まれ,LEDが光ります.

Arduino Unoの仕組み

前述のプログラムでLEDを点灯させることはできるが,なぜこのプログラムで点灯するかを概説していく.私も,この辺のことには疎く,今回勉強したので備忘録を兼ねている.

Atmeta328p

Arduino Unoにはatmega328pというMCUが搭載されている.以下がatmega328pのピンの入出力
atmega328pの仕様書

atmega328p.png

Arduino Unoには28個のピンがあり,そのうち23本は入出力用となっている.そして,この23本はB~Dにグループ化されている(PBx, PCx, PDx).これを見ると,PB0-7, PC0-6, PD0-7まであることがわかる.

そして,Arduinoでの入出力は,以下の手順で行うことなっている.

  1. ピンごとに入力用か出力用かを設定
  2. 入力,または出力用レジスタに/から,値を書き込む/値を読み込む.

そして,Arduinoでは,入出力を決めるためのレジスタとしてDDRx(x=A,B,C,D), 出力用のレジスタとしてPORTx(x=A,B,C,D),入力用のレジスタとしてPINx(x=A,B,C,D)が用意されている.以下,PBxの例

Screen Shot 2019-06-02 at 10.38.41.png

例えば,PB5を出力用に設定し,電圧をかけるには,DDRBレジスタのDDB5を1に設定し,PORTB5に1を書き込めば良い,ということになる.

Arduino Uno

Arduino Unoは,atmega328pをMCUとして備え,周辺機器が内蔵されたボードである.以下がピンのレイアウト
arduino_uno_layout.png

レイアウト図の見方がよくわからなかったが,これは中央左にatmaga328pが配置され,周辺にピンを指すポートが配置されている.そして,MCUの入出力のピン番号が,周辺のポートの灰色の部分に記載されている.そして,周辺のピンはDIGITAL用とか,ANALOG INという用途ごとにまとめられていて,それぞれ番号がついている(e.g., ANALOGはA0,A1,DIGITALは0から13まで).
よって,例えばDIGITALピンのの0番を操作したければ,対応するMCUが2番だから,atmega328pのPD0ポートを操作すれば良い,ということになる.

改めて,LED点滅を考える

Arduino Uno内臓のLEDは,13番ポートに接続されている.この意味は,Digitalピンの13番に接続されているという意味である(回路図を見てもよくわからないが,経験的にこう判断した).
これまでの説明から,13番ポートに対応するのは,atmega328pのPB5であることがわわかる.

よって,DDRBレジスタのDDB5を出力用(1)に設定し,PORTB5を1に設定してあげる(電圧をかける),13番ポートに電流が流れ,LEDが点灯する,という仕組みになっている.

最後は,このDDRBやPORTBを設定するにはどうすればよいか?ということ.組み込み用CPUはメモリーマップドI/Oを採用していることが多く,例外なくatmega328pもこれを採用している.すなわち,特定のレジスタにアクセスするためには,予め決められたメモリアドレスに値を書き込み,読込することによってレジスタにアクセスできる.以下は,atmega328pのデータ用メモリマップである.

Screen Shot 2019-06-02 at 10.23.47.png

これを見ると,I/Oのためのアドレスは64個用意されており,0x0020-0x005Fでアクセスできる事がわかる.ただし,atmega328pの仕様とIN/OUTとにつけられた0x0000-0x001Fに注意する.

Screen Shot 2019-06-02 at 10.29.29.png

実は,I/Oレジスタには2つのアドレスがつけられており,INとかOUTという命令を使うときには,0x0000 - 0x001Fのアドレスを使えと書いてある.そして,DDRB, PORTBの仕様を見ると,2種類のアドレスが書いてあることがわかる.

Screen Shot 2019-06-02 at 10.38.49.png

例えばPORTBでは,Load/Store系の命令を使うときには0x25,IN/OUT命令を使うときには0x05がアサインされていることがわかる.

LEDを点灯させる(再掲)

これまでの内容を踏まえて,再度LED点灯プログラムを見てみる.

led.s
lightOn:
        ldi     R16,    0b00100000 ; PB5 is Output, Others are Input
        out     0x04,   R16        ; 0x04 = DDRB
        ldi     R16,    0b00100000 ; PB5 is High (1 = High, 0 = Low)
        out     0x05,   R16        ; 0x05 = PORTB
        ret

まず,LEDが13番ポートに接続されている情報をもとに,PORTB, DDRBを操作しなければならないことを知る.そして,PORTBのPB5を出力ように設定するためにDDB5を1に設定し,その後PORTB5に1を書き込むことでLEDを点灯させている.

LED点灯プログラムは以下のコマンドで実行することができる

>git clone https://github.com/hiro4669/iosv.git
>cd iosv
>git branch led_ver1 origin/led_ver1
>git checkout led_ver1
>cd led
>make
>make write
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?