これからはじめるAVR
「これから始める方へ」と「ATTiny26Lで始めるAVRの基礎」をまとめてデバイスをtiny2313に変えて書き直しました。2008.12.01

このページを読んでくださる方はマイクロコンピュータ(マイクロコントローラ)は面白そうだ、始めて見ようかな、と思っておられる方だと思います。掲示板には、何から始めたら良いだろうかとの質問がかなりあるようです。これに対して先輩諸氏の回答には、自ら技術者であって、これから職業的にマイクロコンピュータを学ぼうとしている人に対する回答が多いようですが、ここでは職業に関係なく、趣味の世界でマイクロコンピュータを楽しみたい人向けの方法を考えます。
遊びだから時間がかかってもよい、高級な道具・計測器があれば便利なことはわかるが経済性を考えて不便でも工夫しながら楽しみたい、 既製品より自作をしたい経費は少ない方がよい、という考えです。

AVRを使う理由は、自作ライタが安定して使えること、デバイスが変わっても共通点が多いこと、フリーのCコンパイラが使えること、基本機能を持ったデバイスTiny2313が秋月電子で\100で買えること、Web上に豊富な情報があること、などがあげられます。
工作の過程で標準部品を使えば簡単にできるところを代用品で済ませているところもありますが、趣味の世界だとしてご容赦ください。代用品を探してでもハンダ付けをして遊んでみる、という姿勢です。

2003年夏、はじめてマイクロコンピュータを知った頃はAVRを扱ったサイトは少なかったと思います。その中でChaNさんが簡単なライタから高度なライティングソフトまで研究されて、公開していただいていたのはありがたいことでした。このサイトがあったからこそAVRに親しむことができたと感謝しています。

ここで扱うAVRデバイスは ATTiny2313 です。 ADコンバーター機能はありませんが、内蔵のRCでクロックを発振することができ、2kBのフラッシュROMと128BのSRAMを持ちます。IOポートも十分あり、初級の実験には十分な機能を持ちます。

実験をするために必要なハードウエアとソフトウエアについて考えます。
 パソコン: プログラムを書き、コンパイルすること、ライティングソフトを使ってデバイスに書き込むこと、情報収集、データの保存、などに使います。Windows2000またはXPが使いやすい標準です。処理速度は問題になりませんから2000年頃のものでも大丈夫です。シリアルポート(RS232C)があるとラッキーです。簡単にライタを作ることが可能です。もし、USBしかなかったら−−−別の方法を考えましょう。

 実験用電源装置: 5Vで0.5〜1A取れる安定化電源があれば十分です。最近の電源アダプタはほとんどがスイッチング電源になっていますから数百円程度のもので十分です。できればアナログの電流計をつけておくと便利なことが多いです。携帯電話の充電器が余っていれば、やや電圧が高めですから整流用のシリコンダイオードを入れると使えそうです。もちろん手元に電源スイッチがあれば申し分ありません。

 プログラムライタ: プログラマともいいます。ATMELの純正品が数千円であったり、秋月や共立(デジット)のライタもありますが、いずれも持っていませんのでどのように扱うのかさえ知りません。もしPCにシリアルポートがあればChaNさんのCOMポート制御ISPアダプタを助けを借りることなく作ることができます。このサイトのCOMポート接続ISPライタの項をご覧ください。
PCにUSBポートしかなければ、TADさんの「DUAL書き込みWAV式ライタ」などを作ることになります。
最近(2008.12)ではsenshuさん他の尽力によるHIDaspxが安価に、簡単に作られてかつ性能がよいのでお薦めです。このサイトではここで紹介しています。そのライタはAVRにプログラムを書いたものが必要になりますのでライタがなければ作ることができません。もしお近くにAVRライタを持っている人がいないときはメールでこのサイトにご相談ください。
ライタはどのようなものでも書ければよいと思いますが、いくつものライタについて書くことは困難ですから、ここではHIDaspxを使う場合について説明します。

 ハンダ鏝など: 鏝とハンダを用意します。ルーペがあると配線点検に便利です。\100で十分です。

 テスタ: これは用意しましょう。高価なものは要りませんが導通を調べたり、ショートの有無を見たりよく使っています。

次はソフトウエアです。Atmelの統合環境AVRstudioは有名で、使っておられる方も多いのですが、私はほとんど使うことがないのでここでは取り上げないことにします。

 エディタ: プログラムを書くのに使います。メモ帳やノートパッドでも良いのですが、行番号が読みとれたり、検索機能が優れているなどでエディタがお薦めです。sakuraエディタを使っています。このエディタはインストールしなくても、sakura.exe を適当なフォルダに置くだけで実行できます。使い慣れたらカスタマイズするといいでしょう。なお、削除するときは一旦起動すると削除できなくなりますから、Windowsを再起動してsakuraを使う前に削除します。

 Cコンパイラ: プログラムを書き込める形にコンパイルするものですが、フリーソフトのWinAVRを使います。最新版のダウンロードについてはWinAVRメモを参照してください。
ダウンロードした WinAVR-20080610-install.exe を実行します。インストールの場所はデフォルトでいいでしょう。

 ライティングソフト: プログラムをAVRデバイスtiny2313に書き込むソフトです。ライタにHIDaspxを使いますからソフトウエアはhidspxを用意します。hidspx実行ファイル, HIDaspxファームウェア ... hidspx-xxxx.zip からダウンロードします。
解凍したら、わかりやすいところにフォルダを作って−−たとえばC:\a に−−hidspx.exeとhidspx.iniをコピーして、かつ、フォルダのショートカットを作っておきます。

LED1個を点滅するテストボードを作ります。
LED1個の点滅 @テストボードの組み立て
マイクロコンピュータATTiny2313に 5V電源 パスコン ライタ用コネクタ 電流制限抵抗つきLED を配線します。ブレッドボード使うと、(接触不良の心配はありますが)接続・変更が容易です。
回路図と組み立て例です。発光ダイオードが2個ありますが、今回使うのはD1の一つだけです。





LED1個の点滅 Aデバイス情報の読み取り
ライティングソフトを実行して、Tiny2313の情報を読みとります。これに成功すれば、Tiny2313の書き込み回路と書き込みソフトが正常であることがわかります。
テストボードに電源を繋ぐ前に電源端子間をテスタで調べてショートでないことを確認しておきます。電源を入れるときは、電流計に注意するか、ない場合にはICに指を当てて熱くならないかどうか気を付けます。熱くなるようならすぐに電源を切ります。

上で準備した フォルダC:\a を表示します。小さな窓にして隅に置いておくと便利です。この中にhidspx.exeとhidspx.iniが見えます。
デスクトップにコマンドプロンプトを出します。フォルダアイコンの右クリックでCMD窓(コマンドプロンプト)を起動する2を使うと便利です。
コマンドプロンプトにhidspx.exeをドラッグアンドドロップします。それに続けて、スペース、-rを入力してenterキーを押します。hidspxに-rオプションを付けるとデバイス情報を読み出せ、という命令になります。



このようにデバイス情報が読みとれれば成功です。このときに.iniファイルがなければ、コマンドラインに 「-ph -d4」のオプションが必要です。hidspxの扱いにつては付属の説明を読みましょう。

LED1個の点滅 Bプログラムの作成
ライタとテストボードが動くことがわかったので、点滅のプログラムを作ります。エディタを起動して次のように書いてみましょう。最も注意するところは全角の空白を書かないことです。このエディタは設定で全角空白が見えるようにできますから、そのように設定しておきます。
次のプログラムはPORTBのbit0に接続したLEDを点滅するものです。全部をコピーして、エディタにペーストし、led01.cのファイル名で、C:\a_prog\led01(フォルダを作って)に保存してください。(hidspx保存のために C:\a を作ったから C:\a_prog フォルダを作ってその中にプログラム毎のフォルダ(たとえば\led01を作っただけです。任意の場所にプログラム毎のフォルダを作るのがいいでしょう。)
/* ***************************************
led01.c LEDの点滅
mcu=Tiny2313  クロック=1MHz
**************************************** */
#include <avr/io.h>

int main( void )
{
   volatile long int i;
   DDRB=0xff;                           /* PortBをすべて出力に設定する */

   for (;;) {                           /* 無限ループ */
       PORTB=0x01;                      /* 00000001をPortBに出力 bit0=1 portBの0bitだけ点灯 */
       for (i=0; i<10000; i++){         /* 以下のfor文は時間稼ぎ 数値が大きくなれば点灯時間が長い */
         i=i;                           /* dummy */
       }
       PORTB=0x00;                      /* 00000000をPortBに出力 bit0=0 消灯 */
       for (i=0; i<10000; i++){         /* 以下のfor文は時間稼ぎ 数値が大きくなれば消灯時間が長い */
         i=i;                           /* dummy */
       }
   }
}

LED1個の点滅 Cコンパイル
テキスト形式で書かれたプログラムはmcu(マイクロコントローラ)に書き込めるように機械が理解する言語(機械語)に翻訳する必要があります。これにはWinAVRコンパイラを使います。
その準備として、プログラム(.cファイル)がある場所にコンパイル設計書の"makefile"が必要です。makefileを \WinAVRxxxx\sample からコピーします。
プログラムにより、makefileは mcuの種類(MCU = )、プログラムファイル名(TARGET = )、クロック(F_CPU = )が異なるのでこの部分は必ず書き換えます。また、ソースファイル(SRC = )と最適化レベル(OPT = )は場合によって変更が必要です。変更が必要な場所には ################ マークが続いた行を入れておくと便利です。

この2つがそろったら、そのフォルダでコマンドプロンプトを起動してください。(そこで起動しなかったらカレントをcdでそのフォルダに移してください。)
コマンドプロンプトの画面で >に続けて make と入力して enterキーを押します。しばらくしてコンパイルが終わり、同じフォルダに led01.hex という名の.hexファイルができます。これがライタの理解できる中間ファイルなのです。通常、hexファイルができれば書き込めることになります。

LED1個の点滅 Dターゲットへ書き込み
上の項で起動したコマンドプロンプト窓に、C:\a にある hidspx.exe をドラッグアンドドロップします。ここで、スペースを一つ空けて -r と入力しますと前述のmcu情報を読むことになります。(書く前に読みとるのは良いことだと思います。ライタの不調などが事前にわかります)
-rを消して、先ほど作ったled01.hexファイルをドラッグアンドドロップします。極短時間で書き込まれて12番ピンに接続されたLEDが点滅するでしょう。

LED1個の点滅 Eおまけ
成功したらプログラムの for (i=0; i<10000; i++){ の部分の 10000 を変更してみましょう。ただし、あまり大きくすると長時間になりますし、あまり小さくすると速すぎて点滅が見えなくなります。

プログラムの内容は変わりますが、通常、この方法でプログラムを開発します。この他にいろいろな技術があるようですが、まずはこの形をマスターされることが近道だと思います。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 コマンドプロンプト窓は、上に書いたそのフォルダで開く方法を実行し、かつ、コマンドプロンプトのプロパティ(タイトルバー右クリック)のオプションで簡易編集モードと重複する古い履歴を破棄にチェックを付けておくと格段に使いやすくなります。
上矢印キー↑で前のコマンドが呼び出せますからキー操作がほとんど要りません。またドラッグして右クリックするとコピーされ、単なる右クリックでペーストできます。コマンドプロンプト窓の情報を他にコピーするときや、テキストファイルからコマンドプロンプトにコピーするときに極めて便利です。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



LED2個を順に点灯する
上のプログラムの  for(;;){ .... }  の ....部分を次のように変えてみます。
       PORTB=0b00000001;                /* 00000001をPortBに出力 bit0=1 portBの0bitだけ点灯 */
       for (i=0; i<10000; i++){         /* 以下のfor文は時間稼ぎ 数値が大きくなれば点灯時間が長い */
         i=i;                           /* dummy */
       }
       PORTB=0b00000010;                /* 00000010をPortBに出力 bit1=1 点灯 */
       for (i=0; i<10000; i++){         /* 以下のfor文は時間稼ぎ 数値が大きくなれば消灯時間が長い */
         i=i;                           /* dummy */
       }
       PORTB=0b00000100;                /* 00000100をPortBに出力 bit2=1 点灯 */
       for (i=0; i<10000; i++){         /* 以下のfor文は時間稼ぎ 数値が大きくなれば消灯時間が長い */
         i=i;                           /* dummy */
       }
LSBからMSBに向かって順に点灯が移動することになります。ただ、上の回路図ではbit0とbit1だけしか点灯しません。この文を長くしてLEDの数を増やすとLEDの光が移動するように見えます。


2進3桁カウンタ
回路図に赤で書いた部分を追加して、2進3桁のカウンタをタクトスイッチでカウントアップします。
注意するところは入力回路をプルアップしておくことです。通常スイッチは入力端子−GND間につなぎますが、スイッチを押さない状態で入力ポートを解放しますと入力入力インピーダンスが高いために雑音でHLが頻繁に変わってしまします。10k程度の抵抗でVccにつなぐのですが、tiny2313ではPORTxに1を書けば内部プルアップ(50〜100k)が有効になります。

また、機械的スイッチは水銀スイッチを除いてチャタリング(跳ね返りによってon,offが繰り返される)が生じますから、これをソフト的に処理します。すなわち、on,offを繰り返している間は読みに行かないことにします(waitルーチン利用)。
もう一つは、人の動きに対してMCUの判断は速いですから、2回目が押されたのか、1回目がまだ続いているのかわからなくなります。そこで、前回の読み取り値を記録して、前回に押されていなければ新しく押されたと判断してカウントし、前回に押されていればまだ続いていると判断してカウントしないことにしています。

プログラムは次のとおりです。
/* ***************************************
led03.c タクトSW入力の2進3桁カウンタ  2008.12 im
mcu=Tiny2313  クロック=8MHz埋蔵RC
fuse設定  -fL11100100 -fH11011111 -fx00000001
SW入力=PD6
LED=PB2,PB1,PB0
SWのチャタリング防止
**************************************** */
#include <avr/io.h>

int main( void )
{
  volatile uint16_t i;
  uint8_t cnt,s0,s1;
  
  cnt=0x0;                    /* カウント値の初期値=0 */
  s1=0b01000000;              /* 最初は押されていない状態をセット */
  DDRB=0xff;                  /* PortBをすべて出力に設定する PortDはデフォルトで入力設定 */
  PORTD=0b01000000;           /* 入力設定になっているポートにHを書くとプルアップされる */

  for (;;) {                  /* 無限ループ */
    PORTB=cnt;                /* カウント値ををPortBに出力 */
    s0=s1;                    /* 前回のデータを保存して  */
    s1=(PIND & 0b01000000);   /* ポートBと01000000のandをとるとB6の0/1だけがs1に代入される  */
    if(s0>s1){                /* 前回=64(off) 今回=0(on)のときswが押されたと判断 */
      cnt++;                  /* カウントをインクリメント   */
    }
    for(i=1;i<11600;i++){     /*チャタリング防止のディレイ 7steps/loopで10ms    */
      i=i;                    /* このfor文3行を削除するとチャタリングが経験できる   */
    }
  }
}
コピーアンドペーストでエディタに移し、前回と同様に コンパイル 書き込み をしてください。
なお、今回はクロックを 内蔵RC発振の8MHzに変更しています。一般に8MHzで使われることが多いから変更しました。
mcuへのクロック書き込みはfuseビットを書き換えますので、コマンドラインで、
>HIDaspx.exe -fL11100100 -fH11011111 -fx00000001
とします。-fL以下はここからコピーアンドペーストすると間違いがありません。


 ここまでにしてきた、プログラムのテキストを作ること、コンパイルすること、hexファイルを書き込むこと(fuseを書き込むこと)ができれば、後はプログラムの勉強だけで実験が進められると思います。作られたプログラムをコピーしながら新しい技術を取り入れてください。
(fuseビットの内 -fL11100100 -fH11011111 -fx00000001 赤字のところは必ず1にしてください。ここに0を書くと特別なライタでないと以後使えません) 間違いでは無いのですが、hidspx-200-0817版以降のものでは特別な方法でないと0を書くことはできなくなりました。この他にも0を書くと困るビットがあるのですが、どちらも新しいhidspxでは不注意書き込みの対策がなされていますので心配が無くなりました。



なお、このページで疑問が生じましたら掲示板かメールでご連絡ください。「はじめの一歩」にお役に立てば幸甚です。


TOPページへもどる


inserted by FC2 system