#168/#172 ATmega48/88/168 用サンプル・プログラム(アセンブラ)

#168ATmega168USB DIPモジュール#172ATmega48学習用ボード/AVRライタ(ATmega48/88/168)用のアセンブラ・プログラムのサンプルです。AVR Studio4 でアセンブルしてあります。プロジェクト・フォルダ毎に圧縮してあります。AVRSPX用のバッチ・ファイル、HEXファイルも含んでいます。

tiny2313用のものとほぼ同じ内容です。tiny2313用はこちら

 (1) LED点灯
 (2) 無し
 (3) LED点滅(TIMER0/CTC)
 (4) 高速PWM制御(TIMER0/PWM)
 (5) I2Cマスタ送信 #176 MCP23017制御
 (6) I2Cマスタ送受信 I2C-EEPROMのデータの読み出し
 (7) I2Cスレーブ送受信

割り込みは使っていませんが、割り込みベクタやスタックは使用の有無にかかわらず、設定しています。電源電圧は5V、クロックは20MHzのレゾネータを使用しています。

プログラムは無保証、無サポートです。改良などのため予告なく変更することがあります。

なお、ファイル名変更やロケーション変更などの可能性があるため、個別ファイルに直リンクされないようにお願いします。

(1) LED点灯 (07/08/24) 出力ポートの使用法
単純にLED1を点灯させるプログラムです。PORTDを出力ポートに設定して、そのLEDを点灯させるだけです。マイコンを使う上で最も基本となる処理です。

mega168のPB1にLED1のアノード(+)、PD5にLED2のアノード(+)がつながっているものとします。また、両LEDのカソードは1kΩの抵抗器を通してGNDに接続します。

test1.zip
PW="168"
(3) LED点滅(TIMER0/CTC) (07/08/24) CTCモードの使用法
タイマ0を使用してLEDを点滅させます。タイマ0のコンペア機能を利用して一定の周期タイミングを生成します。コンペア・マッチすると、タイマ0は自動的にクリアされます(CTCモード)。時計などを作るときの基本となる仕組みです。

mega168のPB1にLED1のアノード(+)、PD5にLED2のアノード(+)がつながっているものとします。また、両LEDのカソードは1kΩの抵抗器を通してGNDに接続します。

test3.zip
PW="168"
(4) 高速PWM制御(TIMER0/PWM) (07/08/24) PWMの使用法
LED2を消灯状態からだんだん明るくしてまた消灯してと、それを繰り返します。PWMでLEDの明るさを制御するプログラムです。LEDが接続されている0Bチャネル(OC0B/RD5)を使用しています。LEDの代りにトランジスタなどを使ってDCモータをドライブすれば、回転速度制御などに応用できます。

mega168のPB1にLED1のアノード(+)、PD5にLED2のアノード(+)がつながっているものとします。また、両LEDのカソードは1kΩの抵抗器を通してGNDに接続します。

test4.zip
PW="168"
(5) I2Cマスタ送信 #176 MCP23017制御 (07/08/25) TWI使用
I2Cマスタ
mega168のTWIモジュールを使用したI2Cマスタ(マスタ送信のみ)のプログラム・サンプルです。#176 I2C 16ビットI/Oエクスパンダ のGPIOAを出力ポートに設定して、そこに接続されたLEDの表示を約1秒毎に更新します。0〜255のバイナリ値を順番に表示し、それを繰り返します。

ビット・レートは100kbpsです。

電源ONから送信した最初の3つのパケットのそれぞれの波形を示します。ビット・レートは計算どおり100kbpsになっています。
ロジアナ実測波形1 (1回目)
ロジアナ実測波形2 (2回目)

ロジアナ実測波形3 (3回目)

USIモジュール使用のプログラムこちらのページにあります。

test5.zip
PW="168"
(6) I2Cマスタ送受信 I2C-EEPROMのデータの読み出し (07/08/25) TWI使用
I2Cマスタ
mega168のTWIモジュールを使用したI2Cマスタ(マスタ送信、マスタ受信)のプログラム・サンプルです。 I2C-EEPROMの24LC64のデータ読み出しの簡単な使用例です。データ書き込みは読み出しにくらべて簡単なので省略します(リピート・スタート・コンディションを発行しないで、続けてROMデータを送信し、最後にストップ・コンディションを発行するだけ)。

動作中はスタート・コンディションを発行するたびにLED1の状態が反転します。ROMがつながっていない場合でも点滅します。このLED1はハングアップしていないか確認するためのものです。

ROMアドレス0x1234にROMデータ0x56が書き込まれている場合、それが正常に読み出されるとLED2が点灯します。それ以外は消灯した状態です。

ROMがつながっていない(またはアドレスが一致していない)状態で、CB(W)でNOACKが返っているにもかかわらず、継続してスタート・コンディション、CB(R)を送信すると、ハングします。tiny2313のUSIのプログラムでは、CB送信時のNOACKは無視していますが、このプログラムでは、CB(W)でNOACKが返った場合は、ストップ・コンディションを発行してアイドルに戻すようにしています。

CB: コントロールバイトの略。CB(W)はR/Wフラグ(LSB)が"0"、CB(R)はR/Wフラグ(LSB)が"1"のコントロールバイトを示します。

ロジアナ実測波形

USIモジュール使用のプログラムこちらのページにあります。

test6.zip
PW="168"
(7) I2Cスレーブ送受信 (07/08/25) TWI使用
I2Cスレーブ
mega168のTWIモジュールを使用したI2Cスレーブのプログラム・サンプルです。1バイトのデータをスレーブ受信し、そのデータを保持して次回マスタから読み出されたときに、そのデータをスレーブ送信します。
また、受信した内容の下位2ビットの値をLED1とLED2に表示します("1"でON、"0"でOFF)。

応用部分の処理はtiny2313と同様、イベント・ドリブン方式になっています。tiny2313の(7)I2Cスレーブ送受信 を参照してください。サブルーチン名も全て同じです。

このプログラムは#179 ATtiny2313ミニ・ユニバーサル基板相当の基板にtiny2313用(8)I2Cマスタ送受信プログラムを入れたものを接続して相互に通信させて動作確認しました。

リピート・スタート・コンディションが発生するケースは未確認です。

USIモジュール使用のプログラムこちらのページにあります。

test7.zip
PW="168"

検索エンジン対策のため、パスワードがかかっていますが、パスワードはzipファイルの下にかかれていますので、お手数ですが、それを使って解凍してください。

I2Cに関してはこちらで簡単に説明していますので、参照ください。


TWI モジュール(07/08/25)

mega168で簡単なプログラムの動作確認ができたところで、TWIモジュールを使ったI2Cマスタを作ってみました。さすがにTWIを使うと簡単にできました。半日ぐらいで完成しましたが、珍しく、最初に焼いたプログラムが一発で動きました。こんなことは滅多にありませんが、USIで苦労した分の埋め合わせでしょうか。組み合わせによって何か問題が出るかもしれませんが、とりあえず問題なさそうなのでアップしました。

残るはI2Cスレーブですが、どんな通信でも、大抵はスレーブ側、受信側が難しいものです。

I2Cスレーブができました。夕食後に2時間ぐらいで作ったのですが、これまた、一発で作動しました。自慢じゃないですが、(いや自慢ですが)こんなにあっさり動くとは思いませんでした。細かいチェックはしていないので、問題個所が潜伏している可能性もありますが、とりあえずアップします。

TWIのスレーブはPICのMSSPより簡単でした。全部TWISRの状態値で判断できるので(PICの場合はフラグが分散)、C言語で言うところのswitch-case文できれいに処理が振り分けられます。状態値はビットごとに意味付けされているわけではないので、8ビット(下位3ビットは無効)の数値としてで判断する必要があります。この状態値の判定に漏れがあると、不具合が起きると思いますが、シングル・マスタの通常ケースでは問題ないでしょう。

TWIのマニュアルは割と丁寧にかかれているので、ざっと読んだだけでプログラムを作ることができました。USIの説明は不親切、というよりは書きようがないハードウェアですので(詳細に書くとソフトウェアの説明になってしまうので)、設計の概念を理解するまでは難解だと思います。


www.wsnak.com