この記事について
ArduinoをArduino IDEなしで開発していきます。
なぜ、そんな面倒なことをするのかだって?暇だったから以外には理由はない。
必要なもの
この記事と同じことをするには以下のものが必要です。
-
Arduino UNO Rev.3(Atmega328P搭載)
アマゾンで買えます
搭載されているMCUがAtmega328Pでない場合はこの記事で紹介するコードの編集が必要です。 -
PC(Ubuntu20.04 LTS搭載)
同じ方法が通用すると思われますが、WindowsやMacでは環境構築に苦労します。ubuntuならパッケージマネージャから一発で手に入ります。 -
USBケーブル
書き込みに使います。
開発環境セットアップ
Ubuntu20.04 LTS環境を前提にして話を進めます。
まず、以下の開発に必要なツールを揃えます。
- gcc-avr
avrのクロスコンパイラです。 - avr-libc
AVRのCライブラリです。 - avrdude
AVRのIntel Hexファイルのライタアプリケーションです。
以下のコマンドにより一発で手に入ります。
sudo apt install gcc-avr avr-libc avrdude
ビルドディレクトリを作る
以下のようにビルドディレクトリを作ります。
Makefileを書く
ビルドステップは以下のようなステップを踏みます。
このビルドステップをmakeファイルに直すと以下のようになります。
#!/usr/bin/make -f
# setting output file
OUT = build/Program.ihex
# compiler setting
CC = avr-gcc
CFILES = $(wildcard src/*.c)
CPU_FREQ = 16000000
CFLAGS = -c -std=gnu99 -Os -Wall -ffunction-sections -fdata-sections -mmcu=atmega328p
# linker setting
LD = avr-gcc
OBJFILES = $(addprefix build/, $(notdir $(CFILES:.c=.o)))
LDFLAGS = -Os -mmcu=atmega328p -ffunction-sections -fdata-sections -Wl,--gc-sections
# objcopy setting
OBJCOPY = avr-objcopy
OBJFLAGS = -O ihex -R .eeprom
# avrdude setting
AVRDUDE = avrdude
PORT = /dev/ttyACM0
AVRDUDECONF = ./conf/avrdude.conf
AVRDUDEFLAGS = -C $(AVRDUDECONF) -v -V -p atmega328p -carduino -b 115200 -P $(PORT) -D
# Build Step Setting
all : $(OUT)
$(OUT) : $(OUT:.ihex=.elf)
$(OBJCOPY) $(OBJFLAGS) $^ $@
$(OUT:.ihex=.elf) : $(OBJFILES)
$(LD) $(LDFLAGS) $^ -o $@
build/%.o : src/%.c
$(CC) $(CFLAGS) -DF_CPU=$(CPU_FREQ) $^ -o $@
upload : $(OUT)
$(AVRDUDE) $(AVRDUDEFLAGS) -U flash:w:$^:i
clean :
rm -rf build/*.o
rm -rf build/*.ihex
rm -rf build/*.elf
.PHONY : all upload clean
このmakefileはsrc/ディレクトリ以下の*.cファイルを抽出してビルドします。
ビルド生成物はbuild/ディレクトリに配置されます。
ビルドするには以下のコマンドを実行します。
make all
ビルド時の設定はmakefile内の以下の変数の値を書き換えることで設定できます。
変数名 | 設定内容 |
---|---|
CPU_FREQ | CPU動作周波数(デフォルトは16MHz) |
PORT | Arduinoが接続されたポート |
ビルドしたファイルをArduinoに書き込みたいときは
make upload
を実行します。
ビルド生成物を削除したいときは
make clean
でbuild/ディレクトリ内のビルド生成物が削除されます。
avrdudeの設定
avrdudeの設定はconf/avrdude.confファイルに書きます。
avrdude.confの勉強がめんどくさかったのでArduino IDEの設定をパクリ参考にします。
Arduino IDEのavrdudeの設定はhardware/tools/avr/etcにあります。
同じものはGithubにもあります。
書き込みにはシリアルポートのアクセス制限変更が必要です。
書き込み前に以下のコマンドを実行してください。
sudo chmod a+rw /dev/ttyACM0
環境によってはttyACM0がttyACM1だったりttyACM2だったりします。
コードを書く
src/Main.cにコードを書きましょう。
組み込みエンジニアおなじみのLチカをやりましょう。
まず、Arduinoの回路図を見てどのピンがオンボードのLEDに接続されているかを調べます。
Arduinoの回路図は以下のリンクから見れます。
PIN13がオンボードLEDに接続されていることがわかります。13PINをHighに設定できればLEDが光ることがわかります。13PINがどこに接続されているかたどっていくと…
PB5ピンということがわかりました。
次にAtmega238pのマニュアルを調べます。
The DDxn bit in the DDRx Register selects the direction of this pin. If DDxn is written logic one, Pxn is configured as an output pin. If DDxn is written logic zero, Pxn is configured as an input pin.
さらに、
If PORTxn is written logic one when the pin is configured as an output pin, the port pin is driven high (one). If PORTxn is written logic zero when the pin is configured as an output pin, the port pin is driven low (zero).
とあります。
というわけでsrc/Main.cに以下のようなコードを書きます。
#include <avr/io.h>
#include <util/delay.h>
#define MS_DELAY 500
void setup(void);
void loop(void);
int main(void)
{
setup();
while (1)
{
loop();
}
}
void setup(void)
{
/* configure PB5 pin as an output pin */
DDRB |= _BV(DDB5);
}
void loop(void)
{
/* set PB5 pin high */
PORTB |= _BV(PORTB5);
/*Wait 500 ms */
_delay_ms(MS_DELAY);
/* set PB5 pin low */
PORTB &= ~_BV(PORTB5);
/*Wait 500 ms */
_delay_ms(MS_DELAY);
/* set PB5 pin high */
PORTB |= _BV(PORTB5);
/*Wait 500 ms */
_delay_ms(MS_DELAY);
/* set PB5 pin low */
PORTB &= ~_BV(PORTB5);
/*Wait 500 ms */
_delay_ms(MS_DELAY);
/* set PB5 pin high */
PORTB |= _BV(PORTB5);
/*Wait 2000 ms */
_delay_ms(MS_DELAY);
_delay_ms(MS_DELAY);
_delay_ms(MS_DELAY);
_delay_ms(MS_DELAY);
/* set PB5 pin low */
PORTB &= ~_BV(PORTB5);
/*Wait 500 ms */
_delay_ms(MS_DELAY);
}
かけたら
make all
Arduinoをパソコンに接続して
make upload
します。
そうすると、以下のようにLEDがチカチカします。
Githubレポジトリ
この記事で使用したコードは以下のレポジトリから手に入れることができます。