RPU-10講座/第二章 RS232C通信で、データのやりとり
すいません m(_ _)m、本記事はブログ引越時に書式が崩れました。順次修正中です。
■RPU-10の開発環境
RPU-10はATmega128が搭載されており、Best TechnologyのGCC Developer Lite(以下GDL)にも開発Targetが用意されていることは有名な話です。どうして用意されているのかは、まったくわかりませんが…RPU-10にはRPU-10用のアプリケーション以外にSTK500互換のブートローダが書き込まれています。本来、マイコンってのはちょっと特殊な回路を使ってプログラムの書込みを行うのですが、そうするとあまりお手軽じゃないので、ブートローダというプログラムをあらかじめ書き込んでおき、常時、これを起動して、RS232Cなどの手軽なI/Fにてプログラムを転送、ブートローダプログラムがフラッシュROMへ書き込むという構造になっています。
というわけで、今回はGDL V2.00を使用させていただくことにします。インストール時、どのターゲットを入れるか聞いてきますが、すくなくともRPU-10とATmega128、それからx86関係ぐらいは入れおいてください。もし、よくわからなければ、全部インストールしてしまっても問題はありません。
で、開発にあたり、一番参考にさせていただいたのが、urouroさんの気まま雑記です。こちらのブログを読んでいただければ、あえてここであれこれ説明する必要はないぐらいですが、自分でプログラムを書くということは、いろいろリスク面もありますし、また、本来、RPU-10はこのような使い方をするものではない製品ですので、自己責任で、ということだけは重ねてお願いさせていただきます。
実際のところ、ここまででブートローダプログラムをつぶしてしまったことは無いので、めったなことでは壊れないとは思います。また、GDLに同梱されているRPU-10のTARGETは、ブートローダを意識した構造になっていますので、そうそう、壊すことはないと思います。ここでの解説は、RPU-10(ブートローダによるRS232Cによるプログラム転送)と、Best TechnologyのGCC Developer Lite V2.00を使用することを前提に解説していきます。
というわけで準備するものは以下のとおりです。
- RPU-10
- メインハブとRPU-10接続ケーブル(4線のケーブル)
- 電源(バッテリでいいと思いますけど)
- シリアル通信ケーブル
- USB-シリアルコンバータ(必要に応じて)
- GCC Developer Lte V2.00
最小、AVRとRPU-10をTARGETとしてインストールすればよいのですが、後々のことを考えてx86も入れておくと便利です(ちょっとしたユーティリティを作るのに便利)。わからなければ全部入れておきましょう。
■シリアル通信
まずは定番中?といえば定番の、「シリアル端末から何か文字を入力すると、シリアル端末に文字が表示される」というところからやってみたいと思います。
まずはGDLを起動し、コンパイラオプションを「FUTABA RPU-10(ATmega128)」にします。操作は、GDLで、「ツール」-「コンパイラオプション」とメニューを操作して「Compiler Optionダイアログ」を表示し、設定リストで「FUTABA RPU-10(ATmega128)」を選択するだけです。
プログラムですが、こんな感じになります(フォントや画面幅の関係でちょっとよれよれしているのはご勘弁くださいな)。
1: //—————————————————————————————-
2: // RS232Cで入力された文字をそのまま表示(エコーバック)
3: // パソコンのシリアル端末から入力された文字を、そのままパソコンに返します。
4: //
5: // 環境 RPU-10、GDL V2.00
6: // 説明 ビルドされた本プログラムをRPU-10へ転送後、パソコン側で「SIMPLE TERM」(GDLに
7: // 同梱)などを使って通信速度115200bpsで通信ポートを開いてください。その後RPU-10
8: // を再起動するとプログラムがスタートし、「SIMPLE TERM」の方に起動文字列が表示
9: // され、キーボードで文字を入力すると、入力された文字が表示されます。
10: //
11: // AUTHORED BY SISO JUNK STDUIO
12: //—————————————————————————————-
13: #include <avr/pgmspace.h>
14: #include <avr/io.h>
15: #include <avr/interrupt.h>
16: #include <avr/eeprom.h>
17: #include <stdio.h>
18: #include <avr/boot.h>
19: #include <avr/wdt.h>
20:
21: #include <sv.h>
22: #include <rs.h>
23:
24: int main( void )
25: {
26: RPU_InitConsole( br115200 ); // RPU-10ライブラリの初期化
27: SV_Init( br115200 ); // サーボ制御ライブラリの初期化
28: sei(); // 割り込み処理開始
29:
30: // 1秒待つ(よく知らないけど必要らしい)
31: RPU_ResetTimerCounter();
32: while( RPU_GetTimerCounter10() < 100 );
33:
34: // 起動メッセージの表示
35: rs0_puts( “ECHO BACK PROGRAM” );
36: while( 1 ){
37: // RS232Cで受信したデータをそのまま送信する。
38: rs0_putc( rs0_getc());
39: }
40:
41: return 1;
42: }
■ヘッダその1
まずはヘッダについてです。C言語でプログラムする場合、このヘッダファイルとやらをインクルード(読み込み)させることが多いわけですが、 L12~L19については、ATmega128でプログラムするためのヘッダファイルです。
13: #include <avr/pgmspace.h>
14: #include <avr/io.h>
15: #include <avr/interrupt.h>
16: #include <avr/eeprom.h>
17: #include <stdio.h>
18: #include <avr/boot.h>
19: #include <avr/wdt.h>
■ヘッダその2
L20~L21は、RPU-10用のヘッダです。sv.hとrs.hがありますが、1つめはサーボ関係のライブラリ用ヘッダ、2つめはシリアル通信のためのライブラリ用ヘッダです。これらを読み込むことで、GDLに用意されているサーボ動作関数やシリアル通信関数を読み出すことができるようになります。
21: #include <sv.h>
22: #include <rs.h>
■メイン処理
メイン処理(main関数)の中では、まず、ライブラリの初期化を行います。L26の「RPU_InitConsole( br115200 )」は、RS232通信の初期化で(RPU-10の中ではConsoleって呼んでいるみたいですね)、パソコンとの通信速度を設定します。パラメータは通信速度のみですが、きっと中でいろいろやっているんでしょう。L27の「SV_Init( br115200 )」は、サーボ通信(RS485)の初期化です。これまた「br115200」という形で通信速度を設定していますが、恐らくいろいろやっていると思われます。その後、「sei()」を実行して割り込み処理を開始します。「sei()」は、ATmega128(というかAVR)のプログラミングでよく使われるものなので、必要な方は、AVR方面から調べてください。
24: int main( void )
25: {
26: RPU_InitConsole( br115200 ); // RPU-10ライブラリの初期化
27: SV_Init( br115200 ); // サーボ制御ライブラリの初期化
28: sei(); // 割り込み処理開始
29:
30: // 1秒待つ(よく知らないけど必要らしい)
31: RPU_ResetTimerCounter();
32: while( RPU_GetTimerCounter10() < 100 );
33:
34: // 起動メッセージの表示
35: rs0_puts( “ECHO BACK PROGRAM” );
36: while( 1 ){
37: // RS232Cで受信したデータをそのまま送信する。
38: rs0_putc( rs0_getc());
39: }
40:
41: return 1;
42: }
- L30~L32
1秒待ちをしています。細かな理由は知りませんが、ちょっと待つ必要があるらしいです。ここで新たに出てきたのが「RPU_ResetTimerCounter()」と「RPU_GetTimerCounter10()」ですが、これは、「sv.h」の方に定義されている関数で、unsigned longでひたすら10msec毎にカウントアップされているタイマー変数をリセットする関数と、その値を読み出す機能を持っています。実は、RPU_GetTimerCounter10()の方、使うのはお勧めじゃないのですが、理由はおいおい説明します。
この行では、まずタイマー値をリセットし、それから、そのタイマー値が100になるまでの間(=1秒)、while()文によってループすることで1秒待ちます。 - L35
「rs0_puts( “…” )」を実行して、起動メッセージを表示します。ほんとは、「fdevopen()」という便利な機能があって、「printf()」とかでRS232Cに出力することができるのですが、とりあえず使わない方針で行きます。興味がある方はご自分で調べてみてください。また、ATmega128特有?のメモリ管理があり、本チャンのプログラムを書くにはよろしくない書き方ですが、手軽なのでこのままにしておきます。これまたおいおい説明しますね。 - L38
RS232Cポートから読み出したデータをそのままRS232Cポートからに出力します。最後に「return 1」なんていう、実行されないコマンドが書いてありますが、うーん、これはなんと説明しましょう…。まあ、お作法と思っておいてください。
ここまで使った関数をまとめると、以下のようになります。
- void RPU_InitConsole( unsigned short BaudRate );
RPU-10のRS232C初期化となにやら初期化します。BaudRateは、シリアル通信速度を指定します。指定は、「br115200」、「br57600」等が使用できます(rs.h参照のこと) - void SV_Init( unsigned short BaudRate );
RPU-10のRS485初期化となにやら初期化します。BaudRateは、RS485の通信速度を指定します。指定はRPU_InitConsole()と同じです。 - void RPU_ResetTimerCounter( void );
タイマーをリセットします。タイマーというか、たぶん、割り込み処理でひたすら0.8333…msec毎にunsigned longの変数をカウントアップしている処理があって、それを0に初期化しているものだと思います。 - unsigned long RPU_GetTimerCounter10( void );
タイマー値を読み出します。10msec単位です。他に、0.8333…msec単位の関数もあります。 - void rs0_puts (char *);
RPU-10では、USART0がRS232Cに割り当てられており、GDLのライブラリを使う場合、rs0_…という名前の関数の方を使用します(他に、rs1_…というのもあります)。この関数は、RS232Cポートに文字列を出力します。 - void rs0_putc (char);
RS232Cポートから1バイトだけデータを取得します。この関数を実行したにも関わらず、もし受信データが無かった場合、受信するまで待ちます。 - char rs0_getc (void);
RS232Cポートへ1バイトだけデータを出力します。
■ビルドとプログラムの書込み
いよいよ書込みです。まずはGDLでプログラムをビルドします。既にRPU-10の設定になっていると思いますので、そのまま問題なくビルドできるはずです。ビルドには、メニューの「コンパイル」から「ビルド」を選択するか、「F9」を押します。
無事ビルドが通ったら、「フラッシュライタを起動しますか?」というダイアログが表示されると思います。フラッシュライタは、GDLに同梱されているプログラム転送ツールです。RPU-10に書き込む場合は、フラッシュライタの中からさらにavrdudeという書込みツールを起動しているみたいです…が、まあ、書き込めればいいので、つっこみはこれぐらいにしておきます。
で、よくこのツールを初めて使う人がはまる部分…それは通信ポートの設定です。どうやって通信ポートを切り替えるかというと、まずはタイトルバーのところを右クリックしてメニューを出します。そうすると「FW環境設定」というメニューを選ぶことができるはずです。これで設定画面を表示しておいて、ポートなどの変更をします。基本的には、通信ポートの変更だけでよいかと思います。
タイトルバーのところをクリックするとメニューが現れます。
で、「FW環境設定」を選ぶと、ウィンドウがビヨーンと伸びて設定ができるようになります。
書込みですが、RPU-10の上面ボタンを押しながら電源を入れると、LEDが「チカチカチカ!」っと3回点滅するはずです(結構、速いので、注意して見ていてください)。これでブートローダのモードになります。あとはフラッシュライタでおもむろにプログラムを転送します。おっと、転送の前に、パソコンとRPU-10をシリアルケーブルで接続するのをお忘れなく。転送が完了したら、とりあえずRPU-10の電源はOFFにしておきます。
■動作確認
動作確認は、今回、シリアル通信ですので、これまたGDLに同梱されている「SIMPLE TERM」を使って確認します。もしお好きなシリアル端末ソフトがあれば、そちらを使ってもらってかまいません。ちなみに我が家ではTera Termを愛用しています。起動は、「ツール」の「SIMPLE TERM」から行います。
SIMPLE TERMの通信速度などを設定する場合は、SIMPLE TERMのメニューから行います。「ファイル」-「プロパティ」とすると、設定画面を表示することができます。通信ポートをそれぞれのパソコンの環境に合わせ、通信速度を115200bpsに設定します。他は触らなくて大丈夫です。あとは「通信」メニューから「ポートオープン」選択します。
通信速度やポートを設定するには、「プロパティ」を使用します。
こんな感じで設定しします。「COM1」はお手持ちの環境に合わせてください。
で、テストする前にポートオープンするのを忘れずに。
最後におもむろにRPU-10の電源を入れると、SIMPLE TERMに起動メッセージ(”ECHO BACK PROGRAM”)が表示され、入力した文字が表示されます。この手のプログラムをやったことが無い方には、「入力した文字が表示されるなんてあたりまえじゃないの?」と思われる方もいらっしゃるかもしれませんが、「入力した文字を表示する」というのは、こうやってプログラムで「もらった文字を送りなおす」ということコンピュータががんばってやっているということを理解していただけると、コンピュータ製品に対してやさしい気持ちになれるかもしれません。
※注意:本BLOGにてRPU-10での再プログラミングについての情報を公開していますが、これらはSISOが個人的に再プログラミングを行った時の技術情報を整理して紹介しています。GDLへのRPU-10ライブラリ同梱については、Best Technologyさんのご好意で、趣味人への1つのチャンスとして同梱してくださっていると理解しています。そのため、RPU-10の再プログラミングについては、くれぐれもご自身の責任で、また、Best TechnologyさんやFUTABAさんに問い合わせたりすることの無いようにお願いいたします。
[…] RPU-10講座/第二章 RS232C通信で、データのやりとり […]