« じつは年周視差よりむずかしそうな年周光行差の観測 | トップページ | 掩蔽観測用GPS/1PPS発光器(弐) - 潜入・出現時刻の求め方 »

2015年10月11日 (日)

掩蔽観測用GPS/1PPS発光器(弐) - LED駆動ユニット - プログラム(PIC16F648A)

“星食観測用1PPS発光器・2号機 - 取り扱い説明書”の一部です。

最近のソースはきちんと整理してあるですが、この頃は管理が杜撰でした。それらしいソースが見つかったので”保守用”に記事にしておきます。アッセンブルして現在のROMの内容とコンペアする必要があるのですが、まだやってません。

掩蔽(星食)観測用GPS/1PPS発光器の仕様とバグ」で問題になったところです。プログラムを修正するかそのままにしておくかお悩み中。1、2週間のうちに出荷するという約束なのでもうさわらない方がいいかも。

掩蔽(星食)観測用GPS/1PPS発光器の仕様とバグ」では

  割り込みがかかったところで秒をプラス1する。
  割り込みがかかるまえに"$GPRMC"の受信が終わるGE-612Tではこれで問題ない
  割り込みがかかったときには"$GPRMC"の受信が終わっていないGM-5157Aが問題

というようなことを書いていたのですが、実際にソースを見ると

  割り込みがかかったところでLED駆動用のポートを書き換える
  割り込みがかかる前に"$GPRMC"の受信が終わっているGE-612Tは正しい秒を使い
  割り込みがかかったとき"$GPRMC"の受信が終わっていないGM-5157Aは一つ前の秒を使う

というところが問題でした。
だから、1秒プラスするところを省いても両者で挙動が違う、という問題は解決しません。

プリスケーラとタイマーの設定値を調整して1PPS発光直前にPORTAを書き換えるというのがいちばん問題がない解決策です。

でも現在の挙動を仕様と考えるのがもっとも適切(=現実的)な解決策だと思われます (^^;;

	LIST	P=pic16f648a
#include	

; 測位情報の秒、十秒の値を三色LEDで表示します。 ; 測位情報から得られる時刻は遅れがあるので1秒プラスして表示に使います。
  <== 今考えるとわざわざ1秒プラスする必要はなかったです。   <== ただ1秒プラスしていること自体が問題なわけではないです。 ; ピンアサイン - 括弧内はDIPのピン番号 ; LEDはアノードコモンを使っています。 ; 三色LEDのRGBピン1kΩ程度の電流制限抵抗を介してPICに接続してあります ; LEDのコモンピンは1PPSでドライブされるTrをとおしてVDDに接続してあります。 ; **重要** PICの処理はLEDの色を変えるためだけに行っています。 ; 処理が1PPSの発光タイミングに影響することはありません。              ; RA0(17) R1 ; RA1(18) G1 ; RA2(01) B1 ; RA3(02) - ; RA4(03) R2 ; RA5(04) - Vpp/MCLR ; RA6(15) G2 ; RA7(16) B2 ; RB0(06) IN ; RB1(07) - RX ; RB2(08) - TX ; RB3(09) - ; RB4(10) - ; RB5(11) - ; RB6(12) - PGC ; RB7(13) - PGD ; VSS(05) - VSS ; VDD(14) - VDD ; _INTOSC_OSC_NOCLKOUT と _MCLRE_OFF を同時に指定すると警告されます (^^;; __CONFIG _INTOSC_OSC_NOCLKOUT & _WDTE_OFF & _PWRTE_ON & _MCLRE_ON & _BOREN_OFF & _LVP_OFF & _CPD_OFF & _CP_OFF ; Messageが嫌いなのでBank1のレジスタは再定義してあります。 ; 再定義してあるレジスタをバンク切り替えなしに使っていたらどこか間違ってます。 _OPTION EQU H'01' _TRISA EQU H'05' _TRISB EQU H'06' _PIE1 EQU H'0C' _TXSTA EQU H'18' _SPBRG EQU H'19' CBLOCK 20h DG1 ; 表示データ下位 DG2 ; 表示データ上位 PON ; ------- SAVE_W ; 割り込みルーチンのレジスタ退避用 SAVE_S ; 〃 ほんとはスタックにすべきだと思います。 TMP ; 表示用データの変換用作業領域 BUF ; 受信データのバッファ IDX ; 受信データのカウンタ DGT ; ちらつきを押さえるための作業用 HH ; 時(TXを使って録音・記録用に出力します) MM ; 分(〃) SS ; 秒(〃) SH ; RA5,RA6のところをシフトしたもの SSD ; 秒(表示用) N0 ; 時上位カウンター N1 ; 時下位カウンター N2 ; 分上位カウンター N3 ; 分下位カウンター N4 ; 秒上位カウンター N5 ; 秒下位カウンター N6 ; PFI PFI ; Position Fix Indicator(〃) ; 0: Fix not available or invalid, ; 1: GPS SPS Mode, fix valid, ; 2: Differential GPS, SPS Mode, fix valid, ; 3~5: Not supported, ; 6: Dead Reckoning Mode, fix valid NCM ; コンマの数 ENDC ORG H'0000' GOTO INIT ; 割り込みルーチン(タイマー割り込み用) ORG H'0004' ; レジスタの退避 ; 割り込みの使い方 http://www.picfun.com/pic08.html を参考にさせていただきました。 ; 二種類以上の割り込みがあるときこれでいいのか?スタックを使うべき?         MOVWF   SAVE_W         SWAPF   STATUS,W         MOVWF   SAVE_S ; 1PPS信号出力後にPORTAを書き換えます。 ; こうしないと1PPS出力中に色が変わってしまいます (^^;; ; なおここでは1PPSの極性が逆になっていることが前提です。   <== 1PPS信号出力後にPORTAを書き換える、は誤り
  <== 1PPS信号出力後かつ"$GPRMC"受信後にPORTAを書き換える、が正しい

BTFSS PORTB,0 GOTO PEND MOVF SS,W MOVWF PORTA PEND ; 一定時間ごとに割り込みをしたいときはここでタイマーを再開します。 ; なおUSARTの割り込みのときはこういう操作は不要です。 BCF     INTCON,T0IF ; 退避していたレジスタを戻します。 ; 割り込みの使い方は http://www.picfun.com/pic08.html を参考にさせていただきました。 ENDI SWAPF   SAVE_S,W MOVWF   STATUS SWAPF   SAVE_W,F SWAPF   SAVE_W,W RETFIE ; 電源投入後の実行ポイント ; CLRWDT はタイマー割り込みを行うための準備です ; (データシートにこうしろと書いてありました) INIT CLRWDT ; Bank1 ------------------------------- BSF STATUS,RP0 ; タイマーのプリスケーラ-分周比 ; 1PPS信号出力後にPORTAを書き換えるためにタイマーを使います。 ; b'00000000' 1:2 ; b'00000010' 1:4 ; b'00000010' 1:8 ; b'00000011' 1:16 ; b'00000100' 1:32 ; b'00000101' 1:64 ; b'00000110' 1:128 ; b'00000111' 1:256 MOVLW b'00000100' MOVWF _OPTION MOVLW   B'00100000' MOVWF   _TRISA ; USARTを使うために<2:1>をセットします。 ; MOVLW   B'11000110' ; さらにRB0から1PPS信号を読み取ります。 ; (表示切替のタイミングを図るためです) MOVLW   B'11000111' MOVWF   _TRISB         ; Bank0 ------------------------------- BCF     STATUS,RP0 MOVLW B'00000111' MOVWF CMCON ; LED消灯 MOVLW 0xFF MOVLW PORTA ; タイマー割り込みの周期の設定(プリスケーラ-はOPTIONにあります) MOVLW 0x00 MOVWF TMR0 ; 全般的な割り込み許可 BSF INTCON,GIE ; タイマー割り込み許可 BSF INTCON,T0IE ; ペリフェラルの割り込み許可(USARTの割り込みを許可する場合にセットします) BSF INTCON,PEIE ; Bank1 ------------------------------- BSF     STATUS,RP0 ; USARTも割り込みで処理するときは_PIE1

をセットします。 ; BSF _PIE1,RCIE ; USART(送信)も割り込みで処理するときは_PIE1

をセットします。 ; BSF _PIE1,TXIE ; 非同期通信 BCF _TXSTA,SYNC ; ボーレートジュネレーターをHigh設定しします。 ; こちらの方がボーレートの誤差が出にくいはずです。 BSF _TXSTA,BRGH ; ボーレートジュネレータの設定です ; 4MHzクロック、4800bpsの場合です(データシートの計算式と表参照) ; MOVLW 0x33 ; 4MHzクロック、9600bpsの場合です(データシートの計算式と表参照) MOVLW 0x19 MOVWF _SPBRG ; パリティーなし(送信) BCF _TXSTA,TX9 ; USART(送信)の使用を可能にします。 BSF _TXSTA,TXEN ; Bank0 ------------------------------- BCF     STATUS,RP0 ; パリティーなし(受信) BCF RCSTA,RX9 ; USART(受信)の使用を可能にします。 BSF RCSTA,SPEN ; 連続受信可(意味はよくわからないがデータシートにはこうしろと書いてあったような....) BSF RCSTA,CREN ; 表示桁位置の制御用 MOVLW 4 MOVWF PON ; 受信データのカウンタをクリアします。 CLRF IDX ; 受信データがあるかチェックします。 MAIN BTFSS PIR1,RCIF GOTO MAIN ; フレームエラーがあるかチェックします。 BTFSC RCSTA,FERR GOTO M_FERR ; オーバーランエラーがあるかチェックします。 BTFSC RCSTA,OERR GOTO M_OERR
  以下恥を忍んで公開 (^^;; ; "$GPRMC"の文字列を探しそのあとにある分秒のデータを取得し表示します。 ; メッセージは"$GPRMC,HHMMSS.SS,......"の形式になっています。 MOVF IDX,W XORLW 0x00 BTFSS STATUS,Z GOTO C1 MOVF RCREG,W MOVWF BUF XORLW 0x24 ; '$' ? BTFSS STATUS,Z GOTO C0 INCF IDX,F ; '$'だったとき GOTO MAIN C0 CLRF IDX ; 該当文字列ではないとき GOTO MAIN C1 MOVF IDX,W ; '$'から2文字目以降 XORLW 0x01 BTFSS STATUS,Z GOTO C2 MOVF RCREG,W ; '$'から2文字目の処理 MOVWF BUF XORLW 0x47 ; 'G' ? BTFSS STATUS,Z GOTO C0 INCF IDX,F GOTO MAIN C2 MOVF IDX,W ; '$'から3文字目以降 XORLW 0x02 BTFSS STATUS,Z GOTO C3 MOVF RCREG,W ; '$'から3文字目の処理 MOVWF BUF XORLW 0x50 ; 'P' ? BTFSS STATUS,Z GOTO C0 INCF IDX,F GOTO MAIN C3 MOVF IDX,W ; '$'から4文字目以降 XORLW 0x03 BTFSS STATUS,Z GOTO C4 MOVF RCREG,W ; '$'から4文字目の処理 MOVWF BUF XORLW 0x52 ; 'R' ? BTFSS STATUS,Z GOTO C0 INCF IDX,F GOTO MAIN C4 MOVF IDX,W ; '$'から5文字目以降 XORLW 0x04 BTFSS STATUS,Z GOTO C5 MOVF RCREG,W ; '$'から5文字目の処理 MOVWF BUF XORLW 0x4D ; 'M' ? BTFSS STATUS,Z GOTO C0 INCF IDX,F GOTO MAIN C5 MOVF IDX,W ; '$'から6文字目以降 XORLW 0x05 BTFSS STATUS,Z GOTO C6 MOVF RCREG,W ; '$'から6文字目の処理 MOVWF BUF XORLW 0x43 ; 'C' ? BTFSS STATUS,Z GOTO C0 INCF IDX,F GOTO MAIN C6 ; '$'から7文字目以降 MOVF IDX,W XORLW 0x07 BTFSC STATUS,Z GOTO C_H1 MOVF IDX,W XORLW 0x08 BTFSC STATUS,Z GOTO C_H2 MOVF IDX,W XORLW 0x09 BTFSC STATUS,Z GOTO C_M1 MOVF IDX,W XORLW 0x0A BTFSC STATUS,Z GOTO C_M2 MOVF IDX,W XORLW 0x0B BTFSC STATUS,Z GOTO C_S1 MOVF IDX,W XORLW 0x0C BTFSC STATUS,Z GOTO C_S2 MOVF IDX,W XORLW 0x2B BTFSC STATUS,Z GOTO C_PFI MOVF RCREG,W INCF IDX,F GOTO MAIN C_H1 MOVF RCREG,W MOVWF HH SWAPF HH,W ANDLW 0xF0 MOVWF HH INCF IDX,F GOTO MAIN C_H2 MOVF RCREG,W ANDLW 0x0F IORWF HH,W MOVWF HH MOVWF TXREG INCF IDX,F GOTO MAIN C_M1 MOVF RCREG,W MOVWF MM SWAPF MM,W ANDLW 0xF0 MOVWF MM INCF IDX,F GOTO MAIN C_M2 MOVF RCREG,W MOVWF DGT ANDLW 0x0F IORWF MM,W MOVWF MM MOVWF TXREG INCF IDX,F GOTO MAIN C_S1 MOVF RCREG,W MOVWF SS ANDLW 0x0F SWAPF SS,W ANDLW 0xF0 MOVWF SS INCF IDX,F GOTO MAIN C_S2 MOVF RCREG,W MOVWF DGT ANDLW 0x0F IORWF SS,F ; 時刻を1秒進めます。
  <== "$GPRMC"を受信したらすぐにプラス1秒してました。 INCF SS,F BTFSS SS,3 GOTO C_S2_N BTFSS SS,1 GOTO C_S2_N MOVLW 0xF0 ANDWF SS,F SWAPF SS,F INCF SS,F SWAPF SS,F BTFSS SS,6 GOTO C_S2_N BTFSS SS,5 GOTO C_S2_N CLRF SS ; RA5がOutputとして使えないのでRA4,RA6,RA7を使います。
  <== RA5はぜったい使えないというわけではないのですがICSPがややこしくなるので.... C_S2_N RLF SS,W ANDLW 0XC0 MOVWF SH MOVF SS,W ANDLW 0x1F MOVWF SS MOVF SH,W ADDWF SS,F ; MOVWF PORTA ; MOVF SS,W ; 必要? MOVWF SSD MOVWF TXREG INCF IDX,F ; タイマー割り込みを再開します ; BCF     INTCON,T0IF GOTO MAIN C_PFI MOVF RCREG,W MOVWF PFI ANDLW 0x0F IORWF DGT,W MOVWF DG1 ANDLW 0xF0 BTFSS STATUS,Z GOTO SEC1 MOVLW 0 MOVWF TXREG CLRF IDX GOTO MAIN SEC1 MOVF SS,W ANDLW 0x0F SUBLW 0x01 BTFSS STATUS,Z GOTO SEC2 MOVF HH,W MOVWF TXREG CLRF IDX GOTO MAIN SEC2 MOVF SS,W ANDLW 0x0F SUBLW 0x02 BTFSS STATUS,Z GOTO SEC3 MOVF MM,W MOVWF TXREG CLRF IDX GOTO MAIN SEC3 MOVF SS,W ANDLW 0x0F SUBLW 0x03 BTFSS STATUS,Z GOTO SEC4 MOVF SS,W MOVWF TXREG CLRF IDX GOTO MAIN SEC4 MOVF SS,W ANDLW 0x0F SUBLW 0x04 BTFSS STATUS,Z GOTO SEC5 MOVF PFI,W ANDLW 0x0F MOVWF TXREG CLRF IDX GOTO MAIN SEC5 CLRF IDX GOTO MAIN ; フレームエラー ; ボーレートが間違っているかシリアルデータの品質に問題があります。 ; データを読み込むことによってRCSTA

はクリアされます。 ; エラー処理は適当です。 M_FERR MOVLW 0xFF MOVWF DG1 MOVF RCREG,W GOTO MAIN ; オーバーランエラー ; 処理が間に合っていない? ; RCSTA

をクリアして再度セットします。 ; エラー処理は適当です。 M_OERR BCF RCSTA,CREN BSF RCSTA,CREN MOVLW 0xFE MOVWF DG1 GOTO MAIN END

« じつは年周視差よりむずかしそうな年周光行差の観測 | トップページ | 掩蔽観測用GPS/1PPS発光器(弐) - 潜入・出現時刻の求め方 »

時刻と時間」カテゴリの記事

コメント

惑さんへ出荷するのに精力的に動いてますね^^。
恥を忍んで公開・・・のコードで面白かったので少し笑ってしまいました^^(ごめんなさいm(_ _)m)。
でも間違いなく動くし、生産性もいいし可読性もいいのでありだと思います。
アセンブラは面倒で勘違いもすぐ起きますから。

おかえりなさい!
暖かいお言葉ありがとうございます m(._.)m
今度書くんだったらぜったいCにします (^^;;

取説というようり保守用資料なんですが、ソースも回路も忘れてしまっていて自分のなのに、あれどうしてこんなことしてるんだろう?の連続です。

この記事へのコメントは終了しました。

トラックバック

« じつは年周視差よりむずかしそうな年周光行差の観測 | トップページ | 掩蔽観測用GPS/1PPS発光器(弐) - 潜入・出現時刻の求め方 »

フォト

サイト内検索

  • 記事を探されるんでしたらこれがいちばん早くて確実です。私も使ってます (^^;; 検索窓が表示されるのにちょっと時間がかかるのはどうにかしてほしいです。

新着記事

リンク元別アクセス数

  • (アクセス元≒リンク元、原則PCのみ・ドメイン別、サイト内等除く)

人気記事ランキング

  • (原則PCのみ、直近2週間)
無料ブログはココログ