シリアル通信では多くの場合、スタートビットにより通信開始を相手側に知らせます。RS232Cでは、連続したHレベルに続いて、1bitのスタートビット(Lレベル)から通信が始まります。DCCでは14個以上のプリアンブル(1)で予告しておいて、スタートビット(0)の後からデータを流します。
一方、MMプロトコルではパケットの開始を示すスタートビットのたぐいがありません。そこで、パケット取得のタイミングを何らかの方法で決める必要があります。各パルス間のLレベルの間隔に注目すると、次の図に示すように4種類の間隔があることがわかります。
パケット中での間隔は192.5 μsまたは27.5 μsと短い間隔であるのに対し、ダブルパケット中のパケット間では約1.35 ms、ダブルパケットどうしの間隔は4 ms以上となっています。したがって、この間隔が約1.35 ms, または4 ms以上の場合にパケット取得を開始すれば良いことになります。また、この間隔の違いによりダブルパケットの一番目のパケットか、二番目のパケットかを判別することもできます。以上の記述は機関車向けのパケットについて述べたものですが、アクセサリ向けの場合には時間はすべて1/2となります。
そこで、各パルス間の間隔を測定します。この間隔は単純にパルスの立ち下がりでタイマをスタートさせて、次のパルスの立ち上がりでタイマを止めれば測定できるはずです。また、PIC12F1822のタイマ1にはゲート機能があるので、入力ピンRA4(RXPINと定義)がLowの条件でのみカウントさせるようにもしています。(これは必要ないかもしれません。)
RA4(RXPIN)の状態変化(IOCIF, IOCAF4)で割り込みをかけます。割り込み関数では、立ち下がりの場合にはカウンタレジスタ(TMR1H, TMR1L)をリセットしてタイマ1(TMR1ON)をスタートさせます。立ち上がりの場合は、タイマ1を止めてカウンタレジスタを他の変数(TMH, TML)に退避させます。
メイン関数では、パルスが立ち上がりの場合にTMHの値によりパルスの間隔を評価します。ここはおおよその値でも問題ないので、カウンタの下位8bitは無視しています。TMHが0の場合はパケット中のパルスとして読み飛ばします。実測よりダブルパケット中の間隔は約750 μs以上なのでTMHは2,3,4(1024 μs-512 μs)、ダブルパケット間の間隔は、約1500 μs以上でTMHは5(1280 μs)以上としました。TMHが最長の場合は一番目のパケットを取得し、データを他の変数に退避させます。TMHが中間の場合は二番目のパケットなのでパケットを取得し、退避させていたデータと比較します。これらが一致すれば、パケットの取得に成功しているので、アクセサリ用パケットであることを確認、アドレスを比較します。自分に向けたものであれば、信号機を動かし、現在の信号機の状態(赤か緑か)をEEPROMに書き込みます。パケットの取得については次章で述べます。
なお、クロック8 MHz、プリスケーラ1/8の条件ではタイマ1の1カウントは1 μsに相当します。
割り込み処理では、RXPINの状態変化割り込みにより、各パルスの間隔を測定します。メイン主要部は信号機処理のほとんどが記述されています。まだ、説明していない部分もありますが、流れはおおよそわかると思います。
6.テスト用回路 | TOP pageへ | 8.パケット取得(タイマ2) |
---|