調歩同期通信についてこれまで, シリアル通信としては質問が多かった I2C バスについて, サンプルプログラムを提供してきました ここらで, 目先を変えて同じシリアル通信で, もっと古くから使われている調歩同期通信に取り組んでいこうかと思います そこで, 最初に調歩同期通信について, さっとおさらいをしてみます ( かなり, 無駄な記述が多いですが, 我慢してください ) [ 概要 ] 調歩同期通信は古くから使われているシリアル通信方式で,PC では RS-232-C が有名でしたが, フロッピー ディスクと並び レガシー インタフェース と呼ばれ, 今日ではほとんど見なくなってしまいました なお,PC ではほとんどの場合 RS-232-C は調歩同期通信の意味で使われていましたが, 本来は調歩同期通信 ( 非同期通信 ) だけでなく, 同期通信でもしようされる規格です 元々は, 通信でモデムと端末を結ぶための 25 ピンのコネクタを用いた通信のハードウェアを定めたものですが,PC ではいつの間にか 9 ピンになってしまいました これは, 厳密には RS-232-C という規格ではないですが, 慣例で RS-232-C と呼ばれています ( 伝送関係者からは, マイコンや PC での使い方は本来の RS-232-C の使い方ではないと, 怒られたこともありました ) PC ではほとんど見かけなくなりましたが, マイコンでは今日でも広く用いられています ただし, 調歩同期通信という呼び方ではなく, 非同期通信や UART 通信などと呼ばれることがほとんどです 本来は機器同士を結ぶためのインタフェースですが, 取り扱いが簡単なために, いろんな場面で使われているようです CSI のようなクロック同期通信と比べると, 回路が大きくなるので, 昔は中位以上のマイコンにしか内蔵されていませんでしたが, 今日ではロウエンドの MCU でもインタフェースが内蔵されているのと, 手順なし ( 無手順 ) でも使えるので, 初めての人が比較的簡単に使えるようになっています ロウエンド MCU の RL78 でも, 一番小さい 10 ピンの RL78/G10 にもインタフェース (UART) が内蔵されています 調歩同期通信の一番の特徴は, クロックがなくてもデータを再生できることでしょう そのため, 送信データと受信データだけで ( 当然, グランドも必要ですが ) 双方向の通信が可能です 送信と受信を切り替えながら通信する ( 半二重通信 ) なら, 信号線は 1 本で済みます これは, 信号線を長く引っ張る場合にはありがたい特徴です それでは, 調歩同期通信の信号について, 簡単に触れたいと思います 調歩同期通信では, 送信側と受信側で通信条件が一致している必要があります 通信条件とは次の内容です 1 信号レベルと論理 2 通信速度 3データの長さ ( 通常は 8 ビット長ですが,7 や 9 ビットの場合もあり ) 4 転送順序 ( 通常は LSB から順に転送する ) 5パリティの選択 6ストップビットの長さ ( 最近はほとんど 1 ビット ) page. 1
このページは読み飛ばして構いません 1は通常はあまり意識しない ( マイコンの端子ではほぼ決まっている ) のですが,PC やその他の機器と接続する場合に問題になります 前述の RS-232-C は ±12V で駆動するインタフェースで, 通常は論理が反転してマイコンに接続されます 最も古くからある TTY( テレタイプ端末 ) では,20mA のカレントループ ( 電流駆動 ) も用いられていました マイコン間をインタフェースする場合には,CMOS レベルや TTL レベルが用いられるのがほとんどです 2は最も表に出てくる項目です 昔は TTY の 110 ボーや 300 ボーの倍数 (600,1200, 2400,4800,9600,19200 等 ) の伝送周波数が主に用いられてきましたが, 倍数から外れた周波数も一部で使われています 波形が全く崩れないとした場合でも, 送信側と受信側の通信速度が 5%( 実際は 4.5% 程度 ) 以上あると正常な通信は実現できません 古いマイコンでは動作クロックはほとんどが外付けの水晶発振子やセラミック振動子で, 4.9152MHz( マイコンは 2.5MHz 動作 ) や 18.432MHz( インテルが 9 分周して,2MHz 動作の 8080 用の CPU クロックを生成し,2.048MHz で動作させるようなスペックにしていた ), 19.6608MHz( ボードを接続する標準バスのクロックが 10MHz でその倍 ) など調歩同期通信を意識した発振周波数がよく使われていました, ところが, 最近のマイコンでは,32MHz や 20MHz と言った内蔵クロックをもつ MCU が増え, ぴったりした周波数にならないだけでなく, 精度も水晶発振子やセラミック振動子に比べると悪くなっているので, 周波数の誤差についても注意が必要です それでも, ここらは, 数字で出てくるのでかなり知れ渡っていますが, 実際にやり取りする信号は, 波形が鈍るとか, 反射の影響でノイズが出たりするとか, かなり崩れた波形になることがあります 3UART によって, 使用できるビット長が異なりますが, ほとんどの場合に, データは 8 ビット長が使われます 4については, ほとんどの場合に LSB から順に転送されます ここらは,I2C とは逆の順番です 5パリティについては, パリティの有無や (1 のビットが ) 奇数か偶数かは UART では選択できるので, 合わせるだけです 6UART では, ストップビットは 1 ビットあれば機能として十分です UART で 2 ビットに設定した場合でも, 送信では 2 ビット分送信されますが, 受信では最初の 1 ビットだけがチェックされ,2 ビット目は無視されるのがほとんどです 前述の TTY では, 全てメカで処理していたので,2 ビット必要だったようです TTY は ASCII コードを使用して,CR(0x0D: キャリッジリターン ) や LF(0x0A: ラインフィード ) を用いていました ヘッドが右側の方にあると,CR で行の先頭に戻るまでに時間が必要で,CR の直後に印字データを送ると, 戻り切れずに途中で印字してしまいます これを避けるには, 必ず CR の後は LF とすることで対応していました ところが, アセンブラで, 最初に右側にソースを印字し CR 後に左側にアドレスや機械語を印字するものがあり, 面食らったことがありました page. 2
[ 信号のサンプリング ] これらの条件が満足されていることとして説明を続けます なお, 実際の通信では, これ以外に使用するコード体系も一致させることが必要ですが, 通常はソフトでの処理部分になるので, ここでは省略します 調歩同期通信の信号の例を図 1 に示します ロウレベルのスタートビット (ST) から始まり,LSB(b0) から順に 8 ビットのデータが続き, 最後はストップビット (SP) で終わっています ストップビットの後は, 次の通信が始まるまではストップビットと同じ極性 ( ハイレベル ) が続きます ST b0 b1 b2 b3 b4 b5 b6 b7 SP 図 1. 調歩同期通信信号の例 では, 図 2 のサンプリング タイミングに示す波形を受信したときに, どのタイミングでデータを取り込む ( ビット同期 ) かと取り込んだデータのどこからどこまでが一つのデータか ( キャラクタ同期 ) をデータと通信条件から決める必要があります シリアルデータ どのタイミング? 間隔は決まっているが 正しいタイミングは分からない 図 2. サンプリング タイミング 調歩同期通信では, このためにスタートビットとストップビットが定められています このため,8 ビットのデータをやり取りするのに,10 ビット分の時間が必要になり, その分通信速度が低くなります データが通信されていない状態では, マイコンの端子の信号レベルはハイレベルになっています 通信が始まったことを示すために, 信号レベルは 1 ビット分の期間ロウになります これが, スタートビットで, データの始まりを示します ( キャラクタ同期 ) 受信側では, スタートビットの始まり ( 立下り ) を検出し, そのタイミングから 1/2 ビット分遅れたところ ( ビットの中央 ) でデータを読みます ビットの中央でデータを読めば, マージンが一番大きくなるので, ここから, 通信速度で決まる 1 ビットの時間ごとにデータを読めばビットを正しく読めるはずです ビットの中央で読むことをビット同期と言います page. 3
指定された数のビットを読むと受信完了ですが, その後にハイのストップビットがきます このストップビットが正しく読めて通信完了となります ハイの状態は通信を始める前の状態と同じです 通信後のハイの状態の最初の 1 ビット ( または 2 ビット ) がストップビットで, それに続くハイの状態は通信していない状態です 実際の受信動作で, 正しいデータを再生するには, 通信条件が一致していること以外に, 信号の波形が崩れていないことが必要になります 通信する距離が長くなると, 波形の崩れの影響が大きくなってきます 波形の崩れ ( 主に波形の鈍り ) を如何に抑えるかが受信マージンに影響してきます 図 3 に受信マージンの考え方を示します サンプリング点に対して, 前後にどれだけ安定した期間があるかが受信マージンです 下側の拡大部では, 波形の鈍りがある場合を示しています 波形の鈍りがあると, スタートビットの立下りを検出 ( 判断 ) する閾値になるまでに遅延が発生します 検出したタイミングから 1/2 ビット経過したタイミングで, データのサンプリングを行うので, 後ろ側のマージンが小さくなってしまいます 受信マージン 受信マージン 図 3. 受信マージン また, スタートビットを如何に早く検出できるかもマージンに影響してきます ( デバイスのマニュアルにはスタートビットの検出を行うクロックを通信速度の 6 倍以上などと記載されているのを見かけますが, 最低 2 ケタ以上にすべきです 図 4 にスタートビット検出サンプリングによる遅れを示します 最悪,1 サンプリング周期遅れてしまいます 最悪 1 サンプリング周期遅延 図 4. スタートビット検出サンプリング遅延 page. 4
なお, これらのスタートビット検出遅れは,1 データで 1 回だけです 通信速度の誤差 ( ボーレート誤差 ) のようにビットごとに蓄積されるような性質の誤差ではありません UART によっては, ノイズ対策として複数回サンプリングして一致したら有効なデータと判断する機能を搭載したののがあります この場合, 当然スタートビットの検出タイミングも遅延しますが, 受信データそのものが同じように遅延するので, 無視して構いません [ 蓄積する誤差 ] 受信に大きな影響を及ぼすのが, ビットごとに誤差が蓄積していくボーレート誤差です 送信側と受信側でボーレートに誤差がある場合がこれに該当します スタートビットからストップビットまで 10 ビットの場合, ビットの誤差は最終的に 9.5 倍になります 逆に考えると, スタートビットの検出誤差が 0 で, 受信マージンが 50% と理想的な場合でも, 最後のビットでのマージンは 50/9.5% となります 実際には, スタートビットの検出遅れや入力信号に対するセットアップ時間とホールド時間が存在するので, マージンは 4% 程度になると考えられます UART で許容ボーレート誤差が 2~3% と言われているのはここらの結果からです ここらまでは, ハードウェアマニュアルのボーレート許容範囲として式が掲載されていることがありますので, 興味のある方はマニュアルも眺めてみてください これに, 波形の鈍り分が加わると, ボーレート誤差のマージンはもっと少なくなります 波形の鈍り分は定量的には決まらないので, ハードウェアマニュアルにも記載されていないはずですので, 注意が必要です 信号線が長くなって, 波形が鈍ったときには, 通信速度を低くする必要があります ビットの幅が広くなれば, その分だけ影響が小さくなります ここまで, 注意事項 ( というか, 脅し文句 ) から離れたいと思います [ ダブルバッファ ] 現在では, ほとんどの UART の送受信部はシフトレジスタとバッファの 2 段構成になっています 中には, 数バイトの FIFO をもった UART もあります このような構成になっているのは, 受信したデータのプログラムでの処理と次のデータの受信処理を並行してできるようにするためです ダブルバッファ構成になった受信回路のブロック例を図 5に示します 受信データ サンプリング ノイズ除去 シフトレジスタ 図 5. ダブルバッファ構成 バッファレジスタ page. 5
このブロック例では, 受信データはサンプリングされ, ノイズ除去された結果がシフトレジスタに取り込まれていきます 8 ビット分のデータ受信が完了したら, シフトレジスタからバッファレジスタにデータが転送され, 受信完了割り込みが発生します 引き続いて次のデータがくると, シフトレジスタは新しいデータを取り込んでいきます これをソフトウェアから見ると, データ受信完了割り込みが発生したので, バッファレジスタから受信データを読み出します このときの読み出しタイミングとしては, 次のデータの受信が完了する前であればよいことになります 新しいデータの受信が完了し, バッファレジスタが空なら新しく受信したデータをバッファレジスタに転送します バッファレジスタが空でなければ, オーバーラン エラーとなります このとき, 新しく受信したデータがどうなるかは個々の UART で異なります [ 全二重通信と半二重通信 ] シリアル通信を行うときに, 送信用の通信線と受信用の通信線が独立していれば, 送信と受信を独立に行わせることができます 送信と受信を同時に行うことが可能な通信を全二重通信と言います 現在, ほとんどの UART では, 全二重通信に対応しています これに対して, 送信と受信を切り替えながら, 交互に行うのが半二重通信です UART でも, 通信線が 1 本しかない場合には, 半二重通信となります [ フロー制御 ] 調歩同期通信では, 手順 ( プロトコル ) なしで, データを送受信する使い方がほとんどではないかと思います しかし, それでは, 前に述べたオーバーラン エラーが発生する可能性があります このようなことを防止するためにプロトコル ( フロー制御 ) を使用することがあります フロー制御には,RS-232-C で定義されている制御線 (RTS と CTS) を用いたハードウェアによる方法 ( ハードウェア ハンドシェイク ) と,ASCII コードで定義されている制御コード (XON と XOFF) を用いたソフトウェアによるものが一般的です PC やマイコンなどのデータ端末装置 (DTE) 間でハードウェア ハンドシェイクを行う場合には, 互いの RTS と CTS を接続します 図 6 に RL78 マイコンでの接続例を示します マイコン マイコン P00/TxD0 P00/TxD0 P01/RxD0 P01/RxD0 P02 RTS RTS P02 P137/INTP0 CTS CTS P137/INTP0 図 6. マイコンでのハードウェア ハンドシェイク例 page. 6
マイコンに内蔵された UART で CTS や RTS がサポートされていることはほとんどなく, 汎用ポート等を使って実現します UART のハードウェアで CTS 信号をサポートしても,CTS 信号がオフになっても直ぐに送信が停止する訳ではなく, 個々の場合で, その後に送信されてくるデータ数が変わってきます ( 図 7 参照 ) CTS 信号 RxD 信号何キャラクタかは不定図 7. CTS 信号からのタイミング 通常,UART はダブルバッファ構成になっているので, 連続送信機能を使っていると, それだけで 1 キャラクタ分は送信されてしまいます これにソフトウェア処理の遅延が加わってくるので,CTS 信号をオフしても直ちに送信は停止しないと考える必要があります そのため,CTS 信号を使った制御を行う場合には, 送信側が CTS 信号のオフを検知して送信を停止するまでに送られてしまうデータ数を十分に格納できるバッファ メモリを持っておく必要があります 汎用の RL78 シリーズの SAU の UART 機能にはバッファ メモリは内蔵されていないので, ソフトウェアで処理 ( リング バッファを構成 ) する必要があります 図 8 に受信時のバッファ管理の概要を示します 受信完了割り込み 書き込み用オフセット 受信バッファ 読み出し用オフセット バッファ先頭 受信データ空のバッファ 受信データ読み出し 空きが 3 キャラクタで RTS を立ち上げ データが 3 キャラクタ以下で RTS を立ち下げ 図 8. ハードウェアによるハンドシェイクのバッファ管理 受信バッファに十分に空きがある場合には RTS 信号を立ち下げます 受信完了割り込み処理 プログラムで受信データのバッファ格納を繰り返し, 受信バッファの空きが少なくなったとき には RTS 信号を立ち上げます メイン処理プログラムがバッファからデータを読み出して, バ page. 7
ッファに十分な空きができたら RTS 信号を立ち下げます これを送信側は CTS 信号として確 認し, 新たな送信の停止 / 再開を制御します 受信側 受信側処理 バッファ空き発生 バッファ空き不足 送信側 RTS CTS 送信側処理 INTP またはポート確認 送信許可 INTP または, ポート確認 送信禁止 図 9. ハードウェアでのハンドシェイク動作の概要 ソフトウェアによるフロー制御は, 主にプリンタのようにバイナリデータではなく, 表示可能なデータを転送する場合に使用された方法として,ASCII コードで定義されている制御信号 XON/XOFF を使用する方法です 受信側が送信側に XON(0x11) を送信許可コード,XOFF (0x13) を送信禁止コードとして送信することで制御するものです 図 10 にフロー制御動作の概要を示します 受信側 バッファ受信側処理 空き発生 XON 送信 空き不足 XOFF 送信 空き発生 XON 送信 送信側 XON 受信 XOFF 受信 XON 受信 送信側処理 送信許可 送信禁止 送信許可 送信処理 送信中止 送信処理 図 10. ソフトウェアでのフロー制御動作の概要 ソフトウェアによるフロー制御では, 制御コードの送信時間が余分に必要となるので, その 分はバッファに余裕を持たせておく必要があります page. 8
プリンタのようにデータの通信方向が一方向で, 印字可能キャラクタが対象であれば, 比較 的簡単な制御方法です しかし, 双方向にしたり, バイナリデータの転送をしたりするには, データと制御コードを明確に区別できる必要があり, そのための処理が必要になります [UART 関連のインタフェース ] UART がサポートしている調歩同期通信から派生したインタフェースにも少し触れておきます 古くは, 赤外線通信の IrDA も UART の追加機能としてサポートされていました 新しい規格の IrDA は UART ではなくなっているようです 照明関係のインタフェースである DALI(Digital Addressable Lighting Interface) や DMX512 も UART の追加機能で実現されているようです 基本的には,UART は 2 点間を結ぶインタフェースですが, これをシリアルのバスとして使うようにしたのが, 自動車関係で使用されている LIN(Local Interconnect Network) です これは, 単線での通信 ( 単線 UART) 方式になります LIN は比較的低速 (20kbps 以下 ) の通信を行います システムコストを抑えるために, マスタは比較的正確なクロックをもちますが, スレーブのクロックの精度はそれほど要求されません その代わりに, 通信の最初に通信速度 ( 通信クロック ) を確定するためのシンク フィールド (0x55 のデータ ) をマスタが送信することで, スレーブはマスタの通信速度に合わせることが可能になります この 0x55(ASCII コードで u ) を最初に送るのは昔からよく行われていました もっとも, 昔は端末側で u のキーを押して,0x55 を送信し, マイコン側が受信したデータから 4800bps か 9800bps かなどを自動で判定するような使い方でした また,RL78 では, 異電位 (RL78 より電源電圧が低い ) デバイスとの通信を行う機能が追加されているチャネルがあります 通常,CMOS のハイレベルの入力閾値は電源電圧の 70%~ 80% と規定されています 異電位対応の入力は TTL 入力として 2.2V( 電源電圧が 4V 以上時 ) になっています 出力はオープン ドレイン出力になるので, 電源電圧が低い方の電源に抵抗でプルアップすることになります このような追加機能は個々のデバイスや, 使用するチャネルによって異なるので, 目的に応じてデバイスやチャネルを選択する必要があります 寄り道が長くなりましたが, 次ページから RL78 での調歩同期通信について触れていきます page. 9
[RL78 の UART] RL78 での調歩同期通信を行う UART は SAU( シリアル アレイ ユニット ) でサポートされています RL78 には最大 4 チャネルのシリアル チャネルで構成されたユニットが 1 または 2 個内蔵されています ( 図 11 は SAU0 と SAU1 で構成された例を示します SAU ユニット 0(SAU0) チャネル 0 チャネル 1 チャネル 2 チャネル 3 ユニット 1(SAU1) チャネル 0 チャネル 1 チャネル 2 チャネル 3 図 11. RL78 の SAU クロック同期式シリアル (CSI) や簡易 I2C は 1 チャネルで一つのインタフェースとして動作しますが,UART として使用する場合には,2 チャネルで 1 つの UART を構成します これは,CSI では全二重通信とは言っても送信と受信は同じクロックで行うために 1 個のシフトレジスタを共用できますが,UART では送信と受信は独立して行う必要があることから 2 個のシフトレジスタが必要になるためです このため, 送信側と受信側の両方のチャネルの設定を行う必要があります このように送信と受信で独立しているため, コード生成機能を使って動作モードを変更する場合に受信側のボーレートは変更したのに送信側の変更を忘れてしまい, 自分自身の送信データを正常に受信できないなんて話をよく聞きました ここらは, コード生成が気をきかせて両方の設定を変更してくれればいいのにというぼやきも聞いたことがありますが, 基本的に UART で受信と送信は異なる条件で動作可能である必要があるため不可能です SAU の制御では, 初期設定の最初に周辺イネーブルレジスタ (PER0 等 ) でクロックを供給した後にレジスタの設定を行うことになります しかし,RL78/I1D では周辺リセット制御レジスタ (PRR0) が追加されており, ひと手間かける必要があります コード生成を使えば, その分のコードも生成されるので, あまり意識する必要はないかと思いますが [RL78 の UART 制御 ] RL78 の UART は初期設定完了後にシリアル チャネル開始 (SSm) レジスタで使用するチャネルの動作開始をトリガすることで, 通信待機状態になります これは,RxD 端子に信号がくれば, また, 送信データが書き込まれれば, 受信や送信ができる状態です チャネルの状態を示すために, チャネルごとにシリアル ステータス レジスタ (SSRmn) が準備されています この中のフラグを使って UART 通信を制御できます page. 10
よく, 割り込みを使わないで制御したい との要望がありますが, 基本的にこの SSRmn を 使うことで実現可能です 使用するフラグは SSRmn のビット 5 のバッファレジスタ状態表示 フラグ (BFFmn) になります このフラグは, バッファレジスタに有効なデータが入っている と 1 に, 入っていないと 0 になります ただ,SSRmn レジスタは 16 ビット (SSRmnL では 8 ビット ) でのアクセスのみで, ビット操作 ( ビット名称での参照 ) ができないので, ビット 位置を意識しておく必要があります UART0 で, 受信完了を待って受信データを読み出す場合の処理例は以下のようになります ここでは,while 文で SSR01L レジスタのビット 5 が 0 の間はループし, ビット 5 が 1 にな り, ループを抜けたら, シリアル データ レジスタ (SDR01) の下位 8 ビットからデータを 読み出します なお,UART 受信時には SDR01 の下位 8 ビットは RXD0 の名称で使うことが できます ( この処理では, 受信のエラーは無視しています ) uint8_t UART_RX(void) uint8_t work; while( 0 == ( SSR01L & 0x20 ) ) NOP(); work = RXD0; return(work); // 受信完了待ち // 受信データ読み出し 同様に送信は以下のようにすると, 引数 tx_data のデータを送信できます void UART_TX(uint8_t tx_data) while( 0 == ( SSR00L & 0x20 ) ) NOP(); TXD0 = tx_data; // 送信完了待ち // 送信データ設定 なお, 割り込みを使わない は, ほとんどの場合, ベクタ割り込みの意味で使われているようです そうすると, 割り込み要求フラグ (SRIF0 や STIF0) を使った制御も可能です ただし, ベクタ割り込みが発生しないように割り込みをマスク (SRMK0 = 1; や STMK0 = 1;) しておくか, 割り込み禁止 (DI();) にしておく必要があります この場合の受信処理は以下のようになります uint8_t UART_RX(void) while( 0 == SRIF0 ) NOP(); SRIF0 = 0; return(rxd0); // 受信完了割り込み待ち // 割り込み要求フラグをクリア // 受信データ読み出し この方法は, 他の周辺機能でも使うことが可能です 例えば,A/D では SRIF0 を ADIF に RXD0 を ADCR( ただし,work は uint16_t) に置き換えるだけです page. 11
なお, 送信の場合には, そのままでは使えません と言うのも, 送信時はあくまで, 送信完 了の割り込み割り込みであり, 最初のデータに対しては, そのままでは使えません 同じよう にやろうとすると, 初期化完了後にダミーで STIF0 を 1 にしておく必要があります STIF0 = 1; // ダミーの送信完了割り込みセット void UART_TX(uint8_t tx_data) while( 0 == STIF0 ) NOP(); STIF0 = 0; TXD0 = tx_data; // 送信完了待ち // 割り込み要求フラグをクリア // 送信データ設定 受信処理でエラーも確認したいときには, 戻り値を 16 ビットにして, その下位 8 ビットに受 信データ, 上位 8 ビットに SSR01L の値を入れることが考えられます uint16_t UART_RX(void) uint16_t work; while( 0 == ( SSR01L & 0x20 ) ) NOP(); work = SSR01; SIR01 = work; work = work << 8; work = RXD0; return(work); // 受信完了待ち // ステータス読み出し // エラーフラグをクリア // エラーフラグを上位に // 受信データ読み出し ここでは, 特に断らない限り, コード生成のプロパティのファイル生成モードは 初期化関 数のみ出力する に設定してあるものとしておきます [UART での受信エラー対応 ] 通常,UART を割り込みで処理していれば, オーバランは発生しません そうすると, 発生する可能性があるエラーはパリティ エラーとフレーミング エラーです この 2 つのエラーについて考えてみます 通常, マイコン同士の UART での通信では, 対応しているマイコンで, リセットを解除して初期化が完了, 通信を開始するまでの時間が同じということはありません 必ず, どちらかが先に初期化を完了して, メイン処理を開始することになります ハードウェア ハンドシェイクしていなければ, 先にメイン処理を開始した方が, そのまま UART での送信を開始してしまうと, 受信側の準備が整っていない場合には, 受信側でエラーが発生することがあります また, エラーは発生しなくても, 間違えたデータを受信してしまうことが考えられます page. 12
図 12 に, この時のタイミングを示します ここでは, 最初に 0x55 を送信し, その後 1 ビット分の時間をおいて次のデータを送信する例を示しています 1のタイミングまでに受信が起動されていれば,( ボーレートが合っていれば ) 正常に受信できます しかし,2のタイミングで受信を起動すると,b1 をスタートビットと解釈して受信動作を開始します すると, 次のデータのスタートビットがストップビットと解釈され, フレーミング エラーが発生することになります このように, キャラクタ同期ができていないと, エラーが発生することがあります その後も, ビットずれでデータ 0 をスタートビットと解釈してしまい, 受信データがおかしくなったり, フレーミング エラーが発生したりします RxD 信号 ST b0 b1 b7 SP ST 受信起動 1 2 正常終了 図 12. UART スタート時の問題 この状態から抜け出すためには,1 キャラクタ分以上の時間送信しないようにするだけです こうすると, 送信していない時間の信号はハイレベルが保持され, その間に受信は完了してスタートビット待ちとなり, その後はきちんとスタートビットを検出できます RL78 のハードウェアマニュアルには 受信動作を停止して, とありますが, その必要はなく, 送信側に送信停止要求を送り, 一定時間データが送信されてこなくなったら (SSRmn の TSFmn ビットが一定時間 0 なら ), そこまでの受信データを捨てて, 送信側に送信許可を通知すれば大丈夫です ここらは, クロック同期式の CSI よりは簡単です 似たような問題として,RxD 信号がロウレベルの状態で受信が起動された場合があります RxD の立下りでスタートビット検出といっているのに,UART によってはロウレベルだけでスタートビットとみなしていることがあります ( 昔はほとんどの UART がそうなっていました ) RL78 では, きちんと立下りエッジを検出しているようです 話がそれましたが, エラーの話に戻ります 調歩同期通信で, ボーレートに誤差があると, 後ろの方のビットからおかしくなります つまり, フレーミング エラーが出る状態が, 少し誤差がある状態で, パリティ エラーはさらに誤差が大きい状態です パリティの設定があっているのにパリティ エラーが発生する時にはボーレート誤差も疑ってみる必要があります 思いついた内容を書いてきましたが, そろそろおしまいにします 次は実際のサンプルコー ドをアップしていきます 以上 page. 13