AVR入門(1)

AVRの本がいくつか出ていますが,個人的には初歩の段階では難しいと感じました.
それで自分なりにまとめてみたいと思います.
LEDを点灯させるだけのプログラムが第一歩です。
そのためには「回路を組むこと」と「プログラムを書くこと」の2つが必要です。
回路を組む上でピン配列を知る必要があり,そのためにデータシートが必要です。
ATtiny13Aを例にとってみます。
ATtiny13Aで検索すればATMELのサイトが出てくるので、データシートへのリンクを探します。
2種類候補があり、summary(数十ページ)とfull version(数百ページ)です。二つとも落としておきます。図だけはプリントアウトしておくと便利です。

単純なものからということでまずはATtiny13A(秋月で¥120)から始めます。ピン数が少ないので小さいだけが取り柄で使いこなしは難しいですが、原理を理解するという目的にはかないます。
8ピンのうち6ピンをICSPで使います.
よりピン数が多い(20),ATtiny2313が入門用の定番で,値段はもっと安い(秋月で¥100)ですが,ADコンバータがないのが唯一残念な点です.

純正のプログラマはAVRISPmkIIで秋月で¥4000.安心ではありますが,これはターゲット電源を別に与える必要もあるので面倒です.
個人的なおすすめはsparkfunのAVR pocket programmerで¥1500.(スイッチサイエンス,千石,若松など)
最近aitendoから¥900位のが出ましたが,これは付属のケーブルが10ピンなのでちょっと注意が必要です.

対応関係を確認したら接続します.ケーブルの向きを間違えないように注意します.

これで動作が確認できる.

avrdude -c usbtiny -p t13 -P usb
>avrdude: Device signature = 0x1e9007
>avrdude: safemode: Fuses OK

のようになれば,接続はOK.

これで準備はできたのでLチカを動かしてみる.
PB0=5pin にLEDを接続し,抵抗を経由してGNDに落します.
LEDを点灯させるにはPB0をHIGHにすればいいことになります.
そこで次のようなコードを書きます.

#include <avr/io.h> 
#include <util/delay.h>

int main(void)
{
    DDRB = 0x01;
    PORTB = 0x00;
    while(1) {
        PORTB ^= 0x01;
        _delay_ms(500);
    }
    return 0;
}

io.hはPORTB,DDRBなどのIOが物理的対応の共通ヘッダで,コンパイラでtiny13を指定すると,
実際にはiotn13.hを参照し,

#define DDRB                 _SFR_IO8(0x17)
#define PORTB                _SFR_IO8(0x18)

のようにより低水準なマクロになっている.
また,シフトを使って
PORTB = (1<<PB0);
のように書けば16進の計算をしなくて済みます.

8pinのAVRではほぼこのようになっていて,PB0~PB5の6ピンをdigital IOとして使うことができる.
DDRBはピンのIOをどう使うかで,
arduinoではpinMode(0, HIGH);とするのに対応します.
PORTBはピンの値をどうするかで,
digitalWrite(0, HIGH);とするのに対応するでしょう.
実際にはピン番号とポートを自動的に対応づけるために,もっと複雑なことが行われているが,その辺を理解するのに便利なツールを最後に紹介する.

^=はビット反転で指定したビットのみが反転されます.
PORTB = PORTB ^ 0x01; の略です。
ORの場合は
PORTB |= 0x01;
で1ビット目を1にする。

A B A OR B
0 0 0
0 1 1
1 0 1
1 1 1

のようにBが1の場合はAの値によらずA OR B = 1となる。
マスクされたビットB=0ではAの値を変えないので、これでいいことがわかる。
ex. B1010 | B0001 = B1011

ANDの場合は
PORTB &= ~0x01;
で1ビット目を0にする。
~0x01 = ~B00000001 =B11111110

A B A AND B
0 0 0
0 1 0
1 0 0
1 1 1

のようにBが0のときはAの値によらずA AND Bは0となる。
マスクされたビットB=1ではAの値を変えない。
ex. B1011 & ~B0001 = B1011 & B1110 = B1010

delay.hでは_delay_ms()が定義されている.ここでは500ms時間稼ぎをしているだけです.

■コンパイルとアップロード
コンパイルは

avr-gcc -Wall -Os -DF_CPU=9600000 -mmcu=attiny13 -c main.c -o main.o
avr-gcc -Wall -Os -DF_CPU=9600000 -mmcu=attiny13 -o main.elf main.o
rm -f main.hex
avr-objcopy -j .text -j .data -O ihex main.elf main.hex

適当なMakefileがあれば,makeとするだけです.
make flashで書き込み

avrdude -c usbtiny -P usb -p attiny13 -U flash:w:main.hex:i

■FUSEビットの変更
買ったままの新しい石だと遅いと感じると思います.
FUSEビットを書き換えないとCKDIV8が有効で,8分の1のスピードしか出ません.
FUSEビットを書き換える方法としては,WinAVR(Windows),AVRFuses.app(MacOSX)などを使うとGUIで設定できます.
値を調べる方法として
http://www.engbedded.com/fusecalc
を使うと,自分で計算しなくて済みます.
データシート(17.2 Fuse Bytes)でビットを調べて2進を16進に変換すればいいのですが.
avrdude -c usbtiny -P usb -p attiny13 -U hfuse:w:0xff -U lfuse:w:0x6a
でデフォルトに戻すことができます.

HFUSE=|-|-|-|SELFPRGEN|DWEN|BODLEVEL1|BODLEVEL0|RSTDSBL|
=B1111|1111=15|15=0xFF
LFUSE=|SPIEN|EESAVE|WDTON|CKDIV8|SUT1|SUT0|CKSEL1|CKSEL0|
=B0110|1010=6|10=0x6A



programmed:0(TRUE), unprogrammed:1(FALSE)なので、一見逆に見えます。
デフォルトではCKDIV8=0(programmed)なので、1に変更します。
CKDIV8を外すと lfuse 7A, hfuse FFとなりますから,
avrdude -c usbtiny -P usb -p attiny13 -U hfuse:w:0xff -U lfuse:w:0x7a
とすることで,内蔵RC9.6MHzで動きます.
ext clockにすると実際に外部クロックが実装されていないと動かないので,変更には注意が必要です.いい加減な変更をするとFUSEの書き換えもできなくなることがあります.
PB5を使おうとするとRSTDISBLを変更する必要がありますが、これを変更すると元に戻せなくなります。(高電圧、パラレルプログラミングが必要)
といいながら、またやってしまったので回復した。以下のサイトにある回路をブレッドボードとArduinoで接続して、そこにあるスケッチをArduinoにアップロードする。ただし、tiny13なのでHFUSE=0xFF, LFUSE=0x7Aに修正した。
http://www.rickety.us/2010/03/arduino-avr-high-voltage-serial-programmer/
シリアルコンソールを開いて、文字を入力するとリセットが無事終了した。再びavrdudeで認識できるようになった。

後はLEDを増やしたり,コードを変更して点滅の仕方を変えるだけでもいろいろ遊べます.

[GNU global]
Arduinoとか他人が作ったプロジェクトのソースを読むには,GNU globalのようなツールがあると便利.UNIX系のOSでは簡単にインストールできる.

gtags -vでカレントディレクトリ以下のソースファイルにタグを付けてデータベースを作るようだ.
global -xg 関数名 などでどのファイルにあるかを検索できる.
あとは,vimとかemacsのエディタを使うと楽だが,これはかなり説明がいるので,
ブラウザを使う方法だけを紹介する.
htags -F でhtmlファイルに出力する.HTMLというディレクトリにできるので,ブラウザでソースコードを読むと,関数は互いにリンクされていて,全てのシンボルの定義をたどることができる.

広告
カテゴリー: AVR

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

カテゴリー
2010年6月
« 5月   7月 »
 123456
78910111213
14151617181920
21222324252627
282930  
%d人のブロガーが「いいね」をつけました。