ATmega644シリーズの違い

ATmega644には無印644、644P、644A、644PAがありますが、それぞれ微妙に機能が違います。

その違いをブロック図で見ていきたいと思います。(それぞれデータシートから抜粋しました)

まず無印644です。

次に、Sanguinoに使われていて、秋月でも扱っている644Pです。ちなみに秋月のサイトに掲載されているデータシートは644Aのものだったりします。

大きな変化では、

  • UART1が追加されている
  • Timer/CounterのPortへの接続先が微妙に変わっている
  • OscillatorブロックからTOSC1/TOSC2の信号が出ている

というところが変わっています。

さらに644Aです。

さらに、644Aでは16bitのT/C3が追加されているのと、なぜかもう一つ16bit T/C1 の箱が増えています。また、ポートとの接続も複雑になっています。

次に644PAです。

644PAでは大きな変更はなさそうです。

644、644P、644A、644PAでは微妙に差があるので、データシートを見るときは気をつけてみる必要がありそうです。

Mega644版Arduino(Sanguino)・・・アナログ編

次にアナログ入力を試してみたのですが、サンプル「AnalogInput」をコンパイル&実行しようとしてみると、エラーが発生します。

エラーの原因は

int sensorPin = A0

の行で、「A0」が未定義ということのようです。で、元からある arduino-0022/hardware/arduino の下のファイルと、追加した arduino-0022/hardware/sanguino の下のファイルを見比べてみると、WProgram.h のファイルにA0~A15の設定が抜けていることがわかりました。

そこで、arduino-0022/hardware/arduino/cores/arduino/WProgram.h から以下の部分のうちの黒字部分と、ATmega644Pの記述(赤字の部分)を追加しました。

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
const static uint8_t A0 = 54;
const static uint8_t A1 = 55;
const static uint8_t A2 = 56;
const static uint8_t A3 = 57;
const static uint8_t A4 = 58;
const static uint8_t A5 = 59;
const static uint8_t A6 = 60;
const static uint8_t A7 = 61;
const static uint8_t A8 = 62;
const static uint8_t A9 = 63;
const static uint8_t A10 = 64;
const static uint8_t A11 = 65;
const static uint8_t A12 = 66;
const static uint8_t A13 = 67;
const static uint8_t A14 = 68;
const static uint8_t A15 = 69;
#elif defined(__AVR_ATmega644P__)
const static uint8_t A0 = 24;
const static uint8_t A1 = 25;
const static uint8_t A2 = 26;
const static uint8_t A3 = 27;
const static uint8_t A4 = 28;
const static uint8_t A5 = 29;
const static uint8_t A6 = 30;
const static uint8_t A7 = 31;
#else
const static uint8_t A0 = 14;
const static uint8_t A1 = 15;
const static uint8_t A2 = 16;
const static uint8_t A3 = 17;
const static uint8_t A4 = 18;
const static uint8_t A5 = 19;
const static uint8_t A6 = 20;
const static uint8_t A7 = 21;
#endif

さらに、これを処理する部分があるはずなので、探したところ、同様に wiring_analog.c の中の、analogRead()という関数で処理していそうだったので、同様に以下のように黒字部分を arduino-0022/hardware/arduino/cores/arduino/wiring_analog.c から追加し、さらに赤字部分をオリジナルで追加しました。

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
if (pin >= 54) pin -= 54; // allow for channel or pin numbers
#elif defined(__AVR_ATmega644P__)
if (pin >= 24) pin -= 24; // allow for channel or pin numbers
#else
if (pin >= 14) pin -= 14; // allow for channel or pin numbers
#endif

これでサンプル「AnalogInput」も無事に動作するようになりました。
ただ、これだけの記述だけではデジタルピンが sanguino.ccに掲載されている端子配置にならないような気がしたのですが、上記の変更でデジタルピンもこの順番で動作するようです。

・・・もう少し調べてみたら、arduino-0022/hardware/sanguino/cores/arduino/pins_arduino.c の中の配列 digital_pin_to_bit_mask_PGM[] の中で、PortAだけ逆順に並んでいました。ここでデジタルピンの並び順を変換しているようですね。

ライセンスを見ると、LGPLのようなので、差分を取り込んだファイルを添付(sanguino_analog.tar.gz)しておきます。同名のファイルを差し替えれば同じレベルになるはずです

Mega644版Arduino(Sanguino)・・・ハードウェア編

無事にコンパイルできることが確認できた(といっても、Blinkだけですが)ので、ハードウェアを準備します。確認のターゲットはまずはサンプルプログラムBlinkです。なので、(Arduinoでの)デジタル13ピンにLEDを接続したものを点滅させるのが目標になります。

最終的に作ったハードウェアはこんな感じです。(途中の写真がないのですみません)

16MHzのクリスタルと22pFのコンデンサ2つ、Vcc/GND間のパスコン(チップセラミックコンデンサ1uF)を実装した小さな基板を作って、ブレッドボード上のATmega644Pのそばに取り付けました。さらに、リセット端子のプルアップ抵抗と電源供給の配線を行っています。画面左上の青いコンデンサは自動リセット用のDTR信号にかませる0.1uFのコンデンサです。右上の緑色の基板はホストとの通信用のAE-UM232Rで、上の写真ではすでに接続済みです。写真下にはちょっとだけLEDの頭が見えています。

  1. AVRISP mkII(他のものでもいいですが)の接続
    まず、購入状態のATmega644PではArduino(Sanguino)として動作しませんので、ブートローダを書き込んでやります。自分はAVRISP mkIIを使用しているので、ピン配置を確認しながらVcc/GND/MISO/MOSI/RESET/SCKの6pinを接続します。RESETにはプルアップが必須なので忘れないようにします。
  2. ブートローダの書き込み
    ターゲットのATmega644pに電源を供給し、 Arduinoから「Tools」→「Burn Bootloader」→「w/ AVRISP mkII」を選択して、ブートローダを書き込みます。
    書き込みには多少時間がかかりました。赤い文字のエラーメッセージが出ていないことを確認します、
  3. AE-UM232Rの接続
    TXD/RXDを接続し、さらに自動リセット用のDTRを0.1uFのコンデンサを経由して接続します。さらに動作確認用のLEDと抵抗を19pin(D13)に接続します。
  4. 書き込み&実行
    サンプル「Blink」をコンパイル&アップロードして実行します。

これで問題なく無事にLEDが点滅しました。

Mega644版Arduino(Sanguino)・・・準備編

手元にグラフィック液晶があるのですが、これをArduino(28pin ATmega)で制御しようとすると、グラフィック液晶は4bit制御モードがないために最低でも10pinは必要になってしまいます。

なので、ピン数の多い手持ちのATmega644Pを使いたいのですが、ArduinoのIDE(統合環境)に慣れてしまうと「できればArduino(の統合環境)」で使いたい、と思ってしまいます。さらにArduinoの場合、bootloaderを書き込んでおけば、AVRISP mkIIなども必要なくなるというのも魅力です(むしろこっちの魅力の方が大きい。コマンドラインでブートローダを使う方法はないだろうか?)。

で、大抵の場合はこういうのは先人がいるので、Googleさんで調べてみると、Sanguino.ccが該当することがわかりました。しかし、こちらのサイトはArduinoの0018を対象にしているようなのでちょっと古そうだと思ってがっかりしたのですが、ダウンロードページをよく見ると、「For arduino-0018 and newer:」となっています。記載されているインストール方法をみると、既存のArduinoのディレクトリにまるごと追加のディレクトリをコピーするようなので、試してみることにしました。実際に試したインストール手順は以下の通りです。

  1. ダウンロードのページからリンクを辿っていって、Sanguino-0018r2_1_4.zipをダウンロードします。
  2. ダウンロードしたzipファイルを展開します。
  3. ダウンロードしたSanguinoというフォルダを 「~/arduino-0022/hardware/」 の下に「sanguino」という名前でコピーします。
  4. arduino IDE を起動して、「Tools」→「Borads」の下に、sanguinoが追加されるのを確認します。
  5. 何かサンプルをコンパイルしてみます。

これでとりあえずコンパイルできる所までは確認できました。