回路図
ATmega164PでLEDとスイッチ入力の実験

◆ATmega164 はAVRのアトメガシリーズのマイクロコントローラ。
 8ビット×4ポート、フラッシュメモリ:16k 、RAM:1k 、EEPROM:512バイト
 (これだけの機能があれば各種実験システムに発展可能)

◆入門編として、スイッチ操作でLEDをON/OFFさせる簡単なシステムです。
 簡単ながら、マイクロプロセッサの基本回路と、基本的なCプログラム。

◆TMEGA164P:\350 秋月電子 (2011/8/10現在)


  製作のポイント

●AVRIsp接続コネクタは、2列のピンヘッダ(オス)を3ブロックで切断して使用します。
 pin番号はAVRIspのコネクタの三角マークが1番です。
  ▼
  1 2
  3 4
  5 6

●LED(発光ダイオード)は、直径3または5mmのどんな種類でもOK。
 回路記号は矢印に似た形状で電流は矢印方向へ流れる。 
 長いリード線(アノード)は電源(Vcc)側、短いリー ド線(カソード)はグランド(GND)側に接続。
 電流制限抵抗はLEDに流れる電流が5〜10mAとなるような値にする。
 LEDの順電圧が2.5V、電流制限抵抗に8mAを流す場合は
 計算上は (5V-2.5V) ÷ 0.008A = 313Ω 実際の抵抗は入手しやすい330Ωを使用
 (LEDの種類、ほしい明るさ等により、値は調整) 

●ユニバーサル基板に40PのICコネクタを乗せてマイクロコントローラを差込む。

●Vcc(5V) と GND に電源を接続します。 5V電源は不要になった携帯電話の電源を利用する
 ことができます。ケーブルを根元で切断し、被覆を1cm程剥き、+-極性を確認してから赤と黒の
 ミノムシクリップを接続します。電圧は5Vちょうどではなく、4.8V〜5.2Vの範囲内なら問題なく使う
 ことができる筈。

    プログラム解説

C言語でプログラムを記述する場合の基本的なテクニック

(1) コメント
  プログラムを読みやすくするためのコメントは /* と */ で囲みます。何行に渡っても構いません。
  1行だけのコメントは //  に続けて書いてもOKです。 改行までの文がコメントと見なされます。

(2) #include
 標準的なポートの定義などは ×××.h というヘッダファイル
に用意されています(もちろん自分で
 作ることもできますが) これらのヘッダファイルを併合(include)します-という宣言が #include文です。
 例えば、EEPROMを使う場合は
   #include <avr/eeprom.h>
 と書けば、eeprom.hで定義されている関数を使うことができます。

(3) #define
 #define LED1       0x01
 と記述すると、プログラム中で LED1 と書かれた部分は 0x01 に置き換えて
 プログラムが作られます。プログラムが読み易くなるだけでなく、違うCPUに変更する場合や、定数を
 変更する場合なども、define文で定義しておけば変更が容易になります。
 注)0x01 は16進表記です。0x0f は10進の15, 0x10は16を意味します。
   LED1がポートのb0に接続されているので0x01としています。もしb2なら0x02、b6なら0x40とします。

(4) プロトタイプ宣言
 
void init(void);
 void lptm(unsigned int);
 のようにプログラムの前半に書かれているのは関数のプロトタイプ宣言です。
 実際のプログラム中では init(); のように記述されますが、正式な関数の型を宣言するのがプロトタイプ
 宣言です。宣言と違った使い方をするとコンパイルの際エラーが出されます。
 なお、セミコロン;はひとつの関数のおしまいを意味する記号です。
  上の行はデバイスをイニシャライズする init 関数で、左側のvoidは関数が終わったとき返ってくる値が
 無いことを意味します。( )の中のvoidは関数を呼ぶ時に渡す引数が何も無いことを意味するvoidです。
  lptm()関数は引数が1個あります。符号無しのint(16ビット)の値を引き渡す関数です。lptm(1);とすれば
 1msで帰ってくるループタイマー、lptm(1000);なら1000msつまり1秒で帰ってくるタイマー関数です。
 このように、C言語は関数のカタマリで表現する言語です。最初から命令語が用意されている一般的な
 プログラム言語と最も違い、C言語の最大の特徴は関数を自由に作れることです。

(5)外部変数
 関数の外側で宣言した変数はレジスタではなく、RAMに生成されます。
  volatile unsigned char inb_B;
 のvolatileは、揮発性なので要注意の宣言です。プログラムを生成するコンパイラはなるべく手を抜いた
 短いプログラムにするため、記述付近で使用されない変数などが消えてしまうプログラムを生成する
 場合がよくあります。プログラム通りに動かない不思議な現象に悩まされることがありますが、その
 原因のひとつが「変数の揮発」です。 特に、割込みなどで使う変数はかならずvolatileにしておく必要
 があります。ここでは、不揮発性の8ビット型符号なしのinb_Bという入力バッファを宣言しています。
  ちなみに、関数の中で宣言した内部変数は関数の中から出たときには消滅するため、メモリが消費され
 ることはありません。一時的で構わない変数は、関数の中で宣言します。

(6) int main(void)関数
 総てのCプログラムは、このmain()と書かれた関数から実行されます。
 { }の中にプログラムを記述します。
 
(7) init(); 関数を呼び出しています。

(8)
 LEDを点灯する  on_LED1(); 関数を呼び出します。

(9) 1000msのループタイマーです。

(10) whileは( )の中が真である間継続する制御語です。
 while( i < 10) {,,,,,,,}  は変数iが10未満の間、抜け出さないプログラムですが、
 while(1); または while(1){ } は、ずっと抜け出さないプログラムです。

(11)大カッコ{ }は、プログラムのブロックを意味します。
  多重カッコ構造が可能ですが、混乱しないように、タブで見やすく段合わせするのが基本です。

(12) if(inb_B & IN_DAT) 
    {
       カッコ内の条件が成立する場合実効されるプログラム
    }
    else
    {
       カッコ内の条件が成立しない場合実行されるプログラム
    }
  なお、&はビットAND演算式で、変数inb_BとIN_DATのビットのANDを取る式で、
  if 文は( )の中の式が真(0以外)なら次の大カッコ内のプログラムを実行し、else(そうでなかったら)
  2番目の大カッコの中のプログラムが実行します。 else以降の文は省くことができます。

(15)SIGNAL(SIG_OVERFLOW0) は予め用意されているタイマー割り込み機能です。
 21でタイマーの実行速度を規定し、22でタイマー割り込みを有効化し、23でCPUに割り込み許可を
 しています。こうすることで、タイマーは8マイクロセカンド毎に内部カウンタTCNTをダウンカウントし、
 TCNTがオーバーフローする際に、SIGNAL(SIG_OVERFLOW0)関数が実行されます。 
 例では、16でタイマーを再スタートし、17でBポートから
入力バッファinb_Bに入力しています。
 オーバーフローが発生するのはタイマークロック8μs×(255-130)=1ms毎です。
 例題プログラムでは毎1msに入力して、それをmain()で判断していますが、例えば、「割込みで複数回
 入力回信号が一致したら初めて入力バッファの値を確定する」というような構造にすれば、ノイズや
 チャタリングに左右されない実用的なプログラムにすることができます。
  なお、SIGNAL(SIG_OVERFLOW0)割り込みは新しい規格では ISR(TIMER0_OVF_vect) という名称を
 使うことが推奨されています。タイマー0割込みが最も重要な割り込みですが、他には、RS-232C(COM)
 通信の受信割込み ISR(USART_RXC_vect) があれば、ほとんどの用途に間に合うでしょう。

(24〜26) 出力をON/OFFする関数です。出力素子をONにする場合、1(H)にするか0(L)にするかは回路に
 よって異なりますが、一旦出力関数で決めておけば、実際のプログラム中で迷うことはなくなります。





 
プログラム
Top page
inserted by FC2 system