シリアルでの送信はできたので, 次はシリアル受信をしてみよう.
まず,ケーブルの接続は送信のときと同じ. 送信には RS232_DCE_TXD を使ったので,受信には RS232_DCE_RXD を使えばよい.
シリアル受信に関しても,送信と同様に Interface誌 2006/01月号 が参考になる. 送信はただ決まったタイミングで出力するだけなのだけど, 受信はちょっと工夫が必要だ. シリアル通信にはクロックが無いので,相手がスタートビットを送ってきた タイミングに合わせて,だいたい受信信号のビットの真ん中あたりで値を 読むようにする必要がある.
とりあえずこんなかんじで書いてみた.
(※注) 上のソースにはバグがある.詳しくは シリアル経由でスプライト操作その3 を参照.(2007/05/09)
スタートビットを受信すると,半クロックぶん遅れたタイミング (つまり受信ビットのど真ん中)で受信信号を読み込む. 受信信号に変化があった場合にクロックのタイミングを再調整することで, クロックの誤差の累積を防いでいる.
ソース中のコメントにあるが,ストップビットが1.5だと,受信信号の到着と 受信線読み込みが同じタイミングで発生する可能性がある.この場合には 受信信号の到着を優先させ,さらに serclk_old を変化させることで, 受信線読み込みを無視するようになっている (受信信号到着の際にも,serclk_old には serclk が代入される.これをやらないと, 直後のクロックタイミングで受信線読み込みが行われてしまうので). 受信信号が到着しているので,半ビットぶん待ってから受信線読み込みを行うべき なので,これでいいわけだ.
送信のときと同様,パラメータは 9600bps,8ビット,パリティ無し,ストップビット長1ビットにしてある. 8ビットのデータを受信すると,LEDに表示する.
んで,FreeBSDのPCから
# cu -s 9600 -l /dev/cuad0で,スタータキットに接続する.
cuを起動している kterm 上で「a」を押すと, スタータキット側に 0x61 が送信される.
「Z」を押すと,スタータキット側に 0x5a が送信される.
ふむふむ,受信もバッチリだ.