No.180
PICでDMX512を出力する際、面倒なのがBreakTimeです。
一般的なUARTでDMX512の様に長いBreakTimeが使われることは無いためか、PICにはそのような機能がありません。何らかのチカラ技で作らないといけません。
私が最終的にたどり着いた方法は、
1)USARTが出力されるI/Oピンをプルダウンしてアイドル・ローにしておく。
2)BreakTimeは0x00の空送信で作る。ただし、0x00送信でもStopBit(H)が発生するので、以下(3)の方法で消す。
3)BreakTimeの空送信が始まってからStopBitが始まるまでの間(Lが続く間)にTRIS(I/Oピンの入出力方向を決めるフラグ)を入力に切り替える。入力にするとI/Oピンがハイインピーダンス(Z)になり、プルダウンされているためRS485ドライバに届く信号はLを維持する。
4)BreakTimeの時間に相当する空送信する。
5)BreakTimeの終わりというか次のフレームの送信開始前に0x00を送信してTRISを出力に切り替える。0x00送信のStopBitがMarkAfterBreakとなる。ただ、MarkAfterBreakは少し長い方が安定するので、0xCO(b11000000)などのMSB詰めの数値を使ってMarkAfterBreakを長くしてもいい。
といった内容です。
これならタイマー処理をせずにBreakTimeを作れます。
BreakTimeを表すデータをBreakTimeZero、BreakTimeZeroの始まりのバイトをBreakTimeNose、最後をBreakTimeTailと勝手に呼んでますが、RaspberryPiからのSPIデータをBreakTimeTailから始まるモノにしておけばPIC側の処理は凄く簡単です。
0)RaspberryPiからRESET信号(実際にはCSを用いる)をPICに送り、PICはこれを見て送信カウンタをクリアしてUSART.TXピンのTRISを入力に切り替えておく。アイドル・ロー。
1)SPIの最初のバイト(BreakTimeTail)を受信したら、USARTに渡して送信し、3bit分待ってからUSART.TXピンのTRISを出力に切り替える。以下、受信値を1バイト送信するごとに送信カウンタをインクリメントする。
2)512スロットを送信した後のバイトはBreakTimeNoseになる。ただ、PICのUSARTは1ワード分のキャッシュを持っているので、BreakTimeZeroの2バイト目をUSARTに渡した後(BreakTimeNoseが送信開始された後)、3bit分待ってからTRISを入力に切り替えてBrakTimeとする。送信制御は送信カウンタを用いる。
3)以下、SPIのデータが終了(RaspberryPiからのCSで確認)したら、送信カウンタをクリアしてSPIを受信待機にする。=>(1)に戻る。
4)BreakTimeZeroを送信する前にSPIが終わってしまったらエラー。TRISを入力に切り替えてBrakTimeにしておくなど、エラー処理を行う。
5)TRISの切り替えの前に3bit分待つのは、次の送信バイトの受け入れがStopBit中に可能になるからです。
こんな感じかな。
#電子工作
一般的なUARTでDMX512の様に長いBreakTimeが使われることは無いためか、PICにはそのような機能がありません。何らかのチカラ技で作らないといけません。
私が最終的にたどり着いた方法は、
1)USARTが出力されるI/Oピンをプルダウンしてアイドル・ローにしておく。
2)BreakTimeは0x00の空送信で作る。ただし、0x00送信でもStopBit(H)が発生するので、以下(3)の方法で消す。
3)BreakTimeの空送信が始まってからStopBitが始まるまでの間(Lが続く間)にTRIS(I/Oピンの入出力方向を決めるフラグ)を入力に切り替える。入力にするとI/Oピンがハイインピーダンス(Z)になり、プルダウンされているためRS485ドライバに届く信号はLを維持する。
4)BreakTimeの時間に相当する空送信する。
5)BreakTimeの終わりというか次のフレームの送信開始前に0x00を送信してTRISを出力に切り替える。0x00送信のStopBitがMarkAfterBreakとなる。ただ、MarkAfterBreakは少し長い方が安定するので、0xCO(b11000000)などのMSB詰めの数値を使ってMarkAfterBreakを長くしてもいい。
といった内容です。
これならタイマー処理をせずにBreakTimeを作れます。
BreakTimeを表すデータをBreakTimeZero、BreakTimeZeroの始まりのバイトをBreakTimeNose、最後をBreakTimeTailと勝手に呼んでますが、RaspberryPiからのSPIデータをBreakTimeTailから始まるモノにしておけばPIC側の処理は凄く簡単です。
0)RaspberryPiからRESET信号(実際にはCSを用いる)をPICに送り、PICはこれを見て送信カウンタをクリアしてUSART.TXピンのTRISを入力に切り替えておく。アイドル・ロー。
1)SPIの最初のバイト(BreakTimeTail)を受信したら、USARTに渡して送信し、3bit分待ってからUSART.TXピンのTRISを出力に切り替える。以下、受信値を1バイト送信するごとに送信カウンタをインクリメントする。
2)512スロットを送信した後のバイトはBreakTimeNoseになる。ただ、PICのUSARTは1ワード分のキャッシュを持っているので、BreakTimeZeroの2バイト目をUSARTに渡した後(BreakTimeNoseが送信開始された後)、3bit分待ってからTRISを入力に切り替えてBrakTimeとする。送信制御は送信カウンタを用いる。
3)以下、SPIのデータが終了(RaspberryPiからのCSで確認)したら、送信カウンタをクリアしてSPIを受信待機にする。=>(1)に戻る。
4)BreakTimeZeroを送信する前にSPIが終わってしまったらエラー。TRISを入力に切り替えてBrakTimeにしておくなど、エラー処理を行う。
5)TRISの切り替えの前に3bit分待つのは、次の送信バイトの受け入れがStopBit中に可能になるからです。
こんな感じかな。
#電子工作