レガシーなRS232Cインタフェースにはまる
STM32のRTC(リアルタイマークロック)が動き始めた。次のプロジェクトの目標はSDカードアクセスで、行く行くはこのSTM32で、液晶フォトフレームのようなものを作ってみようと考えている。その前に環境を整備しておこうとして思わぬところで時間を費ってしまった。一週間たっぷりはまりこんで一喜一憂していた。まあこれが趣味の醍醐味だと負け惜しみを言っている(単に耄碌(もうろく)しただけかも)。
printfがやっと動いた(6/08/09)
当面の懸案は片付いたのだが、具体的な次の作業が見つけられない。そんなこともあって細々とした手直しや、周辺の環境整備をして気分が乗るのを待っている。1年以上前にAVRの実装処女作として作った温度ロガーを久しぶりに動かしてみた。電池はまだ十分あって温度が表示されたが、コマンドを殆ど忘れていることがわかる。あわててコマンドの案内メッセージを出すためにAVRStudioを立ち上げてAVRプログラムの修正。良かった。やり方を忘れていなかった。かと思えばBeagleBoardのために買ったワイヤレスのキーボードを試してみたりする。どうも落ち着きがない。
当研究所のキーボードは15年以上前に買ったDECのPCについていたものである。中古でも当時30万近くしたPCだったのでキーボードのつくりが良い。こいつの使い勝手、キータッチを上回るキーボードにそれ以来お目にかかったことがない(安物ばかり使っていたこともあるが)。ブラウン管モニター同様愛用していて今も何の不具合もないが、さすがに古くなってきた。今度のワイヤレスはその代替としても考えており、少し高めの製品を選んだためか打ちやすい。
ところでBeagleBoardのブートローダーや、STM32のファームライターはシリアルを要求する。PC一台では開発の効率が悪いので、戸棚の奥に眠っていた大昔のLet'sNoteを引っ張り出した。Pentium133MhzのWindows95時代のものである。ターミナルだけなら十分だ。立ち上げてみて、色々思い出した。こいつはLinuxと、DOS(V7)まで3つのOSが動くようにしてあった。海外のサイトの情報をもとに、liloを細工してPartitionTableを書き換えるという荒技をやって、DOSとWindowsを両立させている。懐かしい。
情けないことにLinuxのコマンドを殆ど忘れているのでWindowsのハイパーターミナルでシリアルをテストする。問題なく動いた。これでPCの画面を切り替えなくてもBeagleBoardを動かすことが出来る。
STM32の方は、ファームライブラリをV1(V2は殆ど同じ)からV3に上げないといけない。STマイクロのmigration guideを少しまともに読んでお勉強する。CMSISなどという大層なコンセプトがついているので何かと思ったら、Cortex Microcomputer Software Interface Standardの略で、ARMのCortex-Mファミリーの中だけの話だ。
構造的に大きく変わったわけではなさそうだ。直接レジスターを叩くときのライブラリ(core_cm3.h関連)と、構造体を介して動かすソフトのためのライブラリを別に用意したのと、表記上の変更・統一(Atmelと同じようなuint32_tとか、volatileでなく__IO__とか)などが主な変更だ。要するにCortex-Mシリーズの統一したライブラリを目指したもので(ベンダー側のメンテナンスコスト削減)、ユーザーにはたいしたメリットはない。まあ、GNU用のスタートアップルーチンが用意されたのが安心と言えば安心である。
一気にV3の新しいプロジェクトを立ち上げる気力がなかったので、前からやろうと思っていたprintfの実装をすることにした。Eclipseで#include <stdio.h>が未定義エラーになっているのも以前から気になっている。それでいて標準ライブラリは、sprintfが問題なく使えている。良くわからない。
オリジナルのデモソースは、printfだったが、動かなかったので、sprintfに替えた経緯がある。理屈から言えばこのあいだのsyscalls.cのスタブルーチンの_write( )にUARTの出力関数を実装すれば動くはずだ。「ねむい」さんのsyscallsのソースもそうなっていた。早速このソースを参考にコーディングしてみる。
こいつがまた思い通り動かない。出力はされるのだがタイミングがおかしい。色々調べているうち、昔のことを思い出した。かなり昔、UNIXを少しいじっていた頃、標準ストリーム出力が言うことをきかなかったことを思い出す。確か、ストリームは、バッファーリングしているのでデータを残さないで全部を吐き出させるためには何かテクニックがあったはずだ。
ウェブに慌てて教えを請う。やっぱりそうだった。えー、¥n(ニューライン)がバッファーの区切りなの?それじゃあ、デモソースにある時刻を表示するステートメントの最後が¥r(リターン)では、いつまでたっても表示されない。デモソースのオリジナルは、printfの文法を無視した実装になっている。ちょうど逆だ。
どうも、オリジナルのデモソースのprintfは標準のpirntfで動いていない。その証拠に\n\rが行頭にあり、これでは全部のステートメントが一回づつ遅れる。それに時刻表示が\rで終わっている。これでは1秒毎に表示されず、バッファーが満杯になって始めて全部の秒表示が行われ、最終的に最後の秒表示が出るだけだ。今のソフトがまさしくこうして動いており、何分かに一回、時刻が更新されている。
UARTに出すメッセージの行換え文字\rをすべて\nにして行末に移しコンパイルし直す。これで正しくメッセージが表示された。おや、時刻表示が\nによって行を換えて斜めに表示されてしまう。これはまずい。
「ねむい」さんから貰ったsyscallsのソースを確かめて見ると、_write( )で、\nがあると\rを追加している。そうか、これがそれを防ぐ仕掛けか。しかし、時間表示が延々と行を換えて出てくるのは時刻表示らしくない。
そこで考え付いたのが、\nを\rに、\rを\nにひっくり返す方法だ。これで、\n\rとやれば、従来どおり行を換えて行頭から出力され、\nだけだと、行頭に来るが、行換えをせず重ね書きをして時刻表示らしくなる。恐らく標準ライブラリには、これらを定義する関数か、環境変数があるのだろうが、とりあえずの対策である。
簡易RS232Cの制作ではまる(6/13/09)
今さらレガシーなRS232Cでもないのだが、COMポートの使用頻度が高くなったきたので、chaNさんの簡易RS232Cインターフェースを作ることにした。USB-UARTがあるから必要ないように思えるが、USBの仮想COMポートは、頻繁にファームを書き直し、リセットしては動かすマイコン相手には、極めて使い勝手が悪い。
USBの仮想UARTは、セッションのときだけ存在するまさしく仮想的なもので、どちらかのアプリケーションが終われば無効になる。マイコンのように常にリセットするような相手では、PC側の端末ソフトはその都度、立ち上げなおさなければいけないし、フラッシュローダーも仮想COMポートが生きているように見えても実際にはマイコンだけでなく仮想COMポートもリセットしてから(コネクタの抜き差し)でないとつながらない。
ARMのフラッシュローダーを使うようになってUARTを使う機会が増えた。BeagleBoardもブートローダーはシリアル経由だ。ChaNさんのAVRspもシリアルであり、シリアル、UARTの使用頻度は高い。幸い我が家の自作PCはレガシーなCOMポートがついている。いざとなったら16550を使った拡張COMポートインターフェースだってある(古いものなら何でもある。あ、あれはISAバスだったか)。
ハードのCOMポートなら端末プログラムを立ち上げておきさえすれば、マイコン側がどういう状態であろうと常に動き出す。フラッシュローダーも端末プログラムを止めればそのまま動く。手始めにSTM32のTTL-UARTをRS232CインターフェースにするChaNさんの簡易RS232CをDSUBソケットに作ることにした。
これはインバータICを使った至極簡単な回路である。これで+9V,-9VのRS232CラインがTTLになってしまう魔法のような回路だ。規格に合っていない邪悪な方法だそうだが、他のいくつかのサイトでも動作が確認されておりアマチュアが使う分には折り紙つきだ。ブレッドボードに組み、動きを確認する。作るのに1分もかからない。最初はPCからの送信がうまくいかなかったが、端末のフロー制御をしていないという例のオチに気が付いてジャンパーを飛ばして解決し、ブレッドボードでは何の問題なく稼動した。3.3VのVccなのに5Vの入力パルスが来るのが少し気になるが、これは実装のときに100KΩの抵抗を増やせば良いだろう。
今度は基板を小さく切り取ってDSUBの変換基板に実装する。ところがブレッドボードでは苦もなく動いたのに、こいつが言うことを聞かないのである。TTLからの送信はできるのだが、PCからの送信が出来ない。フロー制御はコネクタで処置済みである。オシロまで持ち出した。結果、PCからの送信、マイコンにとって受信側が、送信データを拾って発振を起こしている。配線が近くなったから?まさか。
それともインバータの手持ちがなかったので74HCU04というアンバッファータイプを使ったのが原因なのだろうか。Vccを3.3Vにしたので、RS232Cの電圧が高すぎ、ICをこわしてしまったのだろうか(100KΩを200KΩにして3Vまで下げた)。ICを取り替えてみたいが、こういうときに限ってICを半田付けしてしまっている。やれやれ。
休みに家族と都心に出たついでに秋葉に寄り千石で74HC04を仕入れ、ついでに秋月で、本式のRS232Cのラインドライバー(ADM3202ARN 2ヶ ¥300)を用心のため買う。例の表面実装部品とりはずしの低温半田でインバーターICを取替え(これは確かに楽だ)、組み込みなおす。しかし当然、HC04でも動かない。頭を抱える。ブレッドボードでは問題ないのに。
思い込みとは恐ろしい。結局、RS232Cを動かすのに3日もかかってしまった。オチは、ここに書くのも恥ずかしい、インバーターの入力ピンと出力ピンの取り違いである。ブレッドボードでは横並びにインバータを使い、実装では配線を短くするため、反対側の回路を使った。ピンナンバー順に入出力が並んでいると頭から思い込んで、片側の回路に入出力を逆につけて動かない、動かない、発振していると悩んでいたのである。
データシートは見たが、思い込んでいるときは、こういうものである。ふんふん、下から入力、出力、入力、出力ね、とはなから自分で納得し図をろくに見ていない。昔、鉄道の単線で、全速力の列車の正面衝突という大事故の原因が、区間にひとつしかないタブレットという交換器の機械が空かない(実際にもう汽車が走っている)のは故障と頭から決め付けて、鍵をはずしてもう一方の列車に渡してしまった駅長さんの話を思い出した。
動いたときは、本当に安心した。情けないという自責の気持ちより、これが動かずに終わったらこの先の気持ちの整理をどうしようかと恐れていたのだが、それをしないですんだという安堵感の方が強かった。くだらないことにくよくよする自分が情けなくてまたさらに落ち込むという鬱のスパイラルに陥るときがある。まあ、こんなことで一喜一憂しているのだから本当に安い娯楽だ。
やっぱり本式のラインドライバーは違う。フラッシュローダーが動く(6/14/09)
手を動かしていると、こういう気持ちの納まらない時の気分転換になる。安全のために買ってあったRS232Cのラインドライバーを実験してみた。DIPではなくあえてSOICのADM3202ARNにしたのは、変換基板に必要部品も乗せてしまおうと言う魂胆である。
ICのおまけに、チップコンデンサーが付いている(0.1μF、5×2)。これが、今まで実装したことのある20x12ではなく、もう一段小さい16x08(横1.6ミリ、縦0.8ミリ)だ。これをつけろというらしい。うーむ、変換基板の端子に普通のリード線のコンデンサーをつけるつもりをしていたが、挑戦状を突きつけられた感じだ。これは受けるしかないだろう。
写真を見ていただければ良いが、これは面白かった。良い勉強になった、半田ごてをもう少し細いこて先にすればもっと楽だったかもしれない。被害はチップコン1個(ピンセットで強く挟んだ弾みに机から飛びはね行方不明になった)。まあ、このへんが手配線の限界だろう。
ブレッドボードにDSUBコネクタと一緒に配線してテストする。うむ、配線違いもなく問題なく動く。オシロで波形を見る。きれいに+6V,-6VにわかれたRS232Cの信号が出ている。STマイクロのフラッシュローダーはどうだ。こいつは気難しくて簡易RS232Cでは動かなかったのだ。おおお、何の問題もなく認識した。やっぱり本式は違う。買っておいて良かった。
| 固定リンク
「電子工作」カテゴリの記事
- 生存証明2(2022.10.19)
- 生存証明(2022.01.23)
- パソコン連動テーブルタップの修理を諦めて自作(2021.02.16)
- 半年ぶりのブログ更新に漕ぎつけた(2019.09.19)
- 研究所活動は停滞したままでCCDカメラ顕微鏡導入など(2019.02.08)
コメント