掩蔽(星食)観測用GPS/1PPS発光器(弐) - 時刻表示ユニット - プログラム
先日は新しいユニットを作るのに現在使っている基板上のPICからバイナリーを吸い上げて書き込むということで済ませたのですが、今後のことを考えるとちゃんとソースもおいておいた方がよさそうです。
吸い上げたバイナリーを逆アッセンブルしたところどうも手元にあるソースと違っているようです。特にLED駆動ユニットがひどくて、なんだか洗練されたプログラムになっておりちょっと見たぐらいでは何をやっているかさっぱりわかりません。
おおかたほよほよ さんの「GPGGAメッセージからUTC Timeを取り出す 」あたりのソースを丸パクリしたもののようです。FSRとか使ってありますから。じつはほよほよ さんのこの記事を見つけるのにも時間がかかってしまいました (^^;;
で、結論としては恥ずかしくても作ったソースや参考にした記事へのリンクはブログの記事にして残しておいた方がよさそうだということになりました。いつ時点のソースがどれだかすぐわかりますから。
LED駆動ユニットはこれからですが、作りが単純(?)な時刻表示ユニットの方はソースらしくなったのでさっそく記事にすることにしました。使っていない変数も消していないとかあちこちおぞましい(?)ところがあります。
これはもともと4bit使ってダイナミック点灯する4桁LED用なのですが、次に作成する予定の3bit使ってダイナミック点灯する8桁LED用と条件付きアッセンブルで兼用できるようにしました。
そういえばUTCからJSTに変更したんですがまだ24時間とおしてテストはしていなかったような....
==> 19時JSTになったら表示がおかしくなりました (^^;;
以下のソースはその後修正したものです。
--------
関連
「掩蔽(星食)観測用GPS/1PPS発光器(弐) - 動作・機能の確認方法」
「掩蔽観測用GPS/1PPS発光器(弐) - 組み立て(あるいは梱包)」
「掩蔽観測用GPS/1PPS発光器(弐) - GPS受信モジュールユニット」
「掩蔽観測用GPS/1PPS発光器(弐) - LED駆動ユニット - 配線図」
「掩蔽観測用GPS/1PPS発光器(弐) - LED駆動ユニット - プログラム(PIC16F648A)」
「掩蔽観測用GPS/1PPS発光器(弐) - 潜入・出現時刻の求め方」
「掩蔽観測用GPS/1PPS発光器(弐/参) - LED駆動ユニット - 使い方」
「掩蔽観測用GPS/1PPS発光器(弐) - RS232C I/Fユニット」
「掩蔽観測用GPS/1PPS発光器(弐/参) - 時刻表示ユニット - 概要」
「掩蔽観測用GPS/1PPS発光器(弐) - 時刻表示ユニット - 配線」
「星食観測用1PPS発光器取扱説明書 - 6」
「星食観測でのGPS・1PPS信号の利用法 (1)」
「デジカメのセンサー走査時間を測る方法」
「動画の撮影時刻を知る(1)」
「動画の撮影時刻を知る(2)」
「NY NEX-5Nの1/15秒露出の動画を調べてみた」
「デジカメの特性を比較する」
『「掩蔽(星食)の予測と観測」記事目次とリンク集』
「時刻標準について」
「GPS受信モジュールあれこれ」
「過去記事の一覧(測定、電子工作、天文計算): セッピーナの趣味の天文計算」
「記事一覧(測定): セッピーナの趣味の天文計算」
-----
LIST P=pic16f648a #includee <p16f648a.inc>; 測位情報の分の一位の桁、秒、受信状況を4桁あるいは8桁7セグメントLEDに表示するします。 ; 実際の時刻より十分の数秒表示が遅れます。 ; ほんとは時刻を取得したあと秒をインクリメントしておき1PPS信号を ; 受信したところで表示すべきでしょう。 ; ピンアサイン - 括弧内はDIPのピン番号 ; LEDはアノードコモンを使っています。 ; 7seg LEDのA,B,C,..,Gピンは2.7kΩの電流制限抵抗を介してPICに接続してあり ; Digit1-4は直接PICのピンに接続してあります。 ; 電源電圧が5Vでも一つのセグメントあたりの電流は0.7mA程度になるのでドライブ用のTr・FETは不要です。 ; 夜使うのが前提なので電流を抑えてありますが、夜見るとこれでも明るいです (^^;; ; 8桁の場合は DG1、DG2、DG3を使います。 ; RA0(17) 7seg.LED - A ; RA1(18) 7seg.LED - B ; RA2(01) 7seg.LED - C ; RA3(02) 7seg.LED - D ; RA4(03) 7seg.LED - E ; RA5(04) - Vpp/MCLR ; RA6(15) 7seg.LED - F ; RA7(16) 7seg.LED - G ; RB0(06) DG4 (いちばん右側) ; RB1(07) - RX ; RB2(08) - TX ; RB3(09) DG3 ; RB4(10) DG2 ; RB5(11) DG1 ; RB6(12) - PGC 時分秒切替 3.3kΩを介しグランドに落とす ; RB7(13) - PGD ; VSS(05) ; VDD(14) ; ****************************************************************** ;#define LED8 ; ****************************************************************** ; _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 ; 表示データ下位 0x20 DG2 ; 表示データ上位 0x21 PON ; 表示データ制御用(表示スべき桁-1) 0x22 SAVE_W ; 割り込みルーチンのレジスタ退避用 0x23 SAVE_S ; 〃 ほんとはスタックにすべきだと思います。 0x24 TMP ; 表示用データの変換用作業領域 0x25 BUF ; 受信データのバッファ 0x26 IDX ; 受信データのカウンタ 0x27 DGT ; ちらつきを押さえるための作業用 0x28 HH ; 時(TXを使って録音・記録用に出力します) 0x29 MM ; 分(〃) 0x2A SS ; 秒(〃) 0x2B N0 ; 時上位カウンター N1 ; 時下位カウンター N2 ; 分上位カウンター N3 ; 分下位カウンター N4 ; 秒上位カウンター N5 ; 秒下位カウンター N6 ; PFI PFI ; Position Fix Indicator(〃) 0x33 ; 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 ; コンマの数 HD1 ; 十進数で表した時(上位) HD2 ; 十進数で表した時(下位) HDT ; 十進数で表した時(上位+下位) MD1 ; 十進数で表した分(上位) MD2 ; 十進数で表した分(下位) MDT ; 十進数で表した分(上位+下位) SD1 ; 十進数で表した秒(上位) SD2 ; 十進数で表した秒(下位) SDT ; 十進数で表した秒(上位+下位) ENDC ORG H'0000' GOTO INIT ; 割り込みルーチン(タイマー割り込み用) ORG H'0004' ; レジスタの退避 ; 割り込みの使い方 http://www.picfun.com/pic08.html を参考にさせていただきました。 ; 二種類以上の割り込みがあるときこれでいいのか?スタックを使うべき? MOVWF SAVE_W SWAPF STATUS, W MOVWF SAVE_S ; LED消灯 MOVLW 0x00 MOVWF PORTB #ifndef LED8 ; 時分/分秒切替 BTFSC PORTB, 0x6 GOTO NEXT4 #endif ; 分秒表示 ; PONがNのとき右からN+1桁目の表示 ; DECFSZ PON, F BTFSS PON,0 GOTO NEXT1 ; 秒一桁目の表示 MOVF SS, W CALL SETP MOVWF PORTA #ifdef LED8 MOVLW b'00000000' #else MOVLW b'00000001' #endif MOVWF PORTB GOTO PEND ; 秒二桁目の表示 NEXT1 BTFSS PON, 1 ; L15 GOTO NEXT2 MOVF SS, W MOVWF TMP SWAPF TMP, W CALL SETP MOVWF PORTA #ifdef LED8 MOVLW b'00001000' #else MOVLW b'00001000' #endif MOVWF PORTB GOTO PEND ; 三桁目の表示 NEXT2 BTFSS PON, 2 ; L1F GOTO NEXT3 MOVF MM, W CALL SETP MOVWF PORTA #ifdef LED8 MOVLW b'00010000' #else MOVLW b'00010000' #endif MOVWF PORTB GOTO PEND NEXT3 BTFSS PON, 3 ; L1F #ifdef LED8 GOTO NEXT6 #else GOTO PEND #endif MOVF MM, W ; L27 MOVWF TMP SWAPF TMP, W CALL SETP MOVWF PORTA #ifdef LED8 MOVLW b'00011000' #else MOVLW b'00100000' #endif MOVWF PORTB GOTO PEND #ifndef LED8 ; 1桁目の表示 NEXT4 BTFSS PON, 0 ; L1F GOTO NEXT5 MOVF MM, W CALL SETP MOVWF PORTA MOVLW b'00000001' MOVWF PORTB GOTO PEND NEXT5 BTFSS PON, 1 ; L1F GOTO NEXT6 MOVF MM, W ; L27 MOVWF TMP SWAPF TMP, W CALL SETP MOVWF PORTA MOVLW b'00001000' MOVWF PORTB GOTO PEND NEXT6 BTFSS PON, 2 ; L43 GOTO NEXT7 MOVF HH, W CALL SETP MOVWF PORTA MOVLW b'00010000' MOVWF PORTB GOTO PEND NEXT7 BTFSS PON, 3 ; L43 GOTO PEND MOVF HH, W ; L48 MOVWF TMP SWAPF TMP, W CALL SETP MOVWF PORTA MOVF HH, W MOVLW b'00100000' MOVWF PORTB #endif #ifdef LED8 NEXT6 BTFSS PON, 4 ; L43 GOTO NEXT7 MOVF HH, W CALL SETP MOVWF PORTA MOVLW b'00100000' MOVWF PORTB GOTO PEND NEXT7 BTFSS PON, 5 ; L43 GOTO PEND MOVF HH, W ; L48 MOVWF TMP SWAPF TMP, W CALL SETP MOVWF PORTA MOVF HH, W MOVLW b'00101000' MOVWF PORTB #endif ; タイマー割り込みを有効にします ; なおUSARTのときはこういう操作は不要です。 PEND BTFSS PON,0 GOTO RRPON #ifdef LED8 MOVLW 0x20 #else MOVLW 0x08 #endif MOVWF PON GOTO SKPRR RRPON RRF PON,f SKPRR BCF INTCON,T0IF ; L52 ; 最初USARTも割り込みで処理していたのでエントリーが作ってあります。 ; 退避していたレジスタを戻します。 ; 割り込みの使い方 http://www.picfun.com/pic08.html を参考にさせていただきました。 SWAPF SAVE_S, W MOVWF STATUS SWAPF SAVE_W, F SWAPF SAVE_W, W RETFIE ; 16進一桁のデータをLEDの表示セグメントに変換します。 ; 上位桁はマスクします。 SETP ANDLW 0xF ; L58 ADDWF PCL, F RETLW b'10000000' ; '0' RETLW b'11011001' ; '1' RETLW b'01000100' ; '2' RETLW b'01010000' ; '3' RETLW b'00011001' ; '4' RETLW b'00010010' ; '5' RETLW b'00000010' ; '6' RETLW b'11011000' ; '7' RETLW b'00000000' ; '8' RETLW b'00011000' ; '9' RETLW b'00001000' ; 'A' RETLW b'00000011' ; 'B' RETLW b'01000111' ; 'C' RETLW b'01000001' ; 'D' RETLW b'00000110' ; 'E' RETLW b'00001110' ; 'F' ; 電源投入後の実行ポイント ; CLRWDT はタイマー割り込みを行うための準備です ; (データシートにこうしろと書いてありました) INIT CLRWDT ; Bank1 BSF STATUS,RP0 ; タイマーの分周比はLED表示の見栄えを考えながらお好みで.... MOVLW b'00000011' MOVWF _OPTION MOVLW B'00100000' MOVWF _TRISA ; USARTUSARTを使うために<2:1>をセットします。 MOVLW B'11000110' MOVWF _TRISB ; Bank0 BCF STATUS, RP0 MOVLW B'00000111' MOVWF CMCON ; LED消灯 MOVLW 0x00 MOVWF PORTB MOVLW 0xFF CLRF PORTA ; タイマー割り込みの周期の設定(プリスケーラ-はOPTIONにあります) MOVLW 0x00 MOVWF TMR0 ; 全般的な割り込み許可 BSF INTCON, GIE ; タイマー割り込み許可 BSF INTCON, T0IE ; ペリフェラルの割り込み許可(USARTの割り込みを許可する場合にセットします) BSF INTCON, PEIE ; Bank1 BSF STATUS, RP0 ; 非同期通信 BCF _TXSTA,SYNC ; ボーレートジュネレーターをHigh設定しします。 ; こちらの方がボーレートの誤差が出にくいはずです。 BSF _TXSTA,BRGH ; ボーレートジュネレータの設定です ; 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 ; 表示桁位置の制御用 #ifdef LED8 MOVLW 0x20 #else MOVLW 0x08 #endif MOVWF PON ; 受信データのカウンタをクリアします。 CLRF IDX MOVLW 0xFF MOVWF SS MOVWF MM MOVWF HH ; 受信データがあるかチェックします。 MAIN BTFSS PIR1, RCIF ; L90 GOTO MAIN ; フレームエラーがあるかチェックします。 BTFSC RCSTA, FERR GOTO M_FERR ; オーバーランエラーがあるかチェックします。 BTFSC RCSTA, OERR GOTO M_OERR ; echo back ? MOVWF TXREG ; "$GPRMC"の文字列を探しそのあとにある分秒のデータを取得し表示します。 ; メッセージは"$GPRMC,HHMMSS.SSS,......"の形式になっています。 MOVF IDX, W ; 0x27 XORLW 0x00 BTFSS STATUS, Z GOTO C1 MOVF RCREG, W MOVWF BUF ; 0x26 XORLW 0x24 ; '$' ? BTFSS STATUS, Z GOTO C0 INCF IDX, F GOTO MAIN C0 CLRF IDX ; LA2 GOTO MAIN C1 MOVF IDX, W ; LA4 XORLW 0x01 BTFSS STATUS, Z GOTO C2 MOVF RCREG, W MOVWF BUF XORLW 0x47 ; 'G' ? BTFSS STATUS, Z GOTO C0 INCF IDX, F GOTO MAIN C2 MOVF IDX, W ; LAF XORLW 0x02 BTFSS STATUS, Z GOTO C3 MOVF RCREG, W MOVWF BUF XORLW 0x50 ; 'P' ? BTFSS STATUS, Z GOTO C0 INCF IDX, F GOTO MAIN C3 MOVF IDX, W ; LBA XORLW 0x03 BTFSS STATUS, Z GOTO C4 MOVF RCREG, W MOVWF BUF XORLW 0x52 ; 'R' ? BTFSS STATUS, Z GOTO C0 INCF IDX, F GOTO MAIN C4 MOVF IDX, W ; LC5 XORLW 0x04 BTFSS STATUS, Z GOTO C5 MOVF RCREG, W MOVWF BUF XORLW 0x4D ; 'M' ? BTFSS STATUS, Z GOTO C0 INCF IDX, F GOTO MAIN C5 MOVF IDX, W ; LD0 XORLW 0x05 BTFSS STATUS, Z GOTO C6 MOVF RCREG, W MOVWF BUF XORLW 0x43 ; 'C' ? BTFSS STATUS, Z GOTO C0 INCF IDX, F GOTO MAIN C6 MOVF IDX, W ; LDB 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 ; LFA
ANDLW 0x0F
MOVWF HD1
SWAPF HD1, W
MOVWF HDT
INCF IDX, F
GOTO MAIN C_H2 MOVF RCREG, W ; L101 ANDLW 0x0F MOVWF HD2 IORWF HDT, W MOVWF HDT MOVWF TXREG ; >= 15 ? MOVLW 0x15 SUBWF HDT,W BTFSC STATUS,C GOTO Over14 ; HD2 == 0 ? MOVF HD2,W SUBLW 0x00 BTFSS STATUS,Z GOTO Not0 ; HH < 15 and HD2==0
; 00,10(UTC) = 09,19(JST) MOVLW 0x09 MOVWF HD2 GOTO MakeHH; 01-09,11-14(UTC) = 10-18,20-23(JST)
Not0 DECF HD2,f INCF HD1,f GOTO MakeHH Over14 ; >= 20 ? MOVLW 0x20 SUBWF HDT,W BTFSC STATUS,C GOTO Over19 ; 14 < HH < 20 ; 15-19(UTC) = 00-04(JST)
MOVLW 0x05 SUBWF HD2,f DECF HD1 GOTO MakeHH Over19
; 20-23(UTC) = 05-08(JST) MOVLW 0x05 ADDWF HD2,f CLRF HD1 MakeHH SWAPF HD1,W ADDWF HD2,W MOVWF HH INCF IDX, F GOTO MAIN C_M1 MOVF RCREG, W ; L108 ANDLW 0x0F MOVWF MD1 SWAPF MD1, W MOVWF MD1 IORWF MD2,W MOVWF MM INCF IDX, F GOTO MAIN C_M2 MOVF RCREG, W ; L10F ANDLW 0xF MOVWF MD2 IORWF MD1, W MOVWF MM MOVWF TXREG INCF IDX, F GOTO MAIN C_S1 MOVF RCREG, W ; L11A ANDLW 0x0F MOVWF SD1 SWAPF SD1, f MOVF SD1, W IORWF SD2, W MOVWF SS INCF IDX, F GOTO MAIN C_S2 MOVF RCREG, W ; L124 ANDLW 0x0F MOVWF SD2 IORWF SD1, W MOVWF SS MOVWF TXREG INCF IDX, F GOTO MAIN C_PFI MOVF RCREG, W ; L12F MOVWF PFI ANDLW 0x0F IORWF DGT, W MOVWF DG1 ANDLW 0xF0 BTFSS STATUS, Z GOTO SEC1 MOVLW 0 CLRF IDX GOTO MAIN SEC1 MOVF SS, W ; L13A ANDLW 0x0F SUBLW 0x01 BTFSS STATUS, Z GOTO SEC2 MOVF HH, W CLRF IDX GOTO MAIN SEC2 MOVF SS, W ; L142 ANDLW 0x0F SUBLW 0x02 BTFSS STATUS, Z GOTO SEC3 MOVF MM, W CLRF IDX GOTO MAIN SEC3 MOVF SS, W ; L14A ANDLW 0x0F SUBLW 0x03 BTFSS STATUS, Z GOTO SEC4 MOVF SS, W CLRF IDX GOTO MAIN SEC4 MOVF SS, W ; L152 ANDLW 0x0F SUBLW 0x04 BTFSS STATUS, Z GOTO SEC5 MOVF PFI, W ANDLW 0x0F CLRF IDX GOTO MAIN SEC5 CLRF IDX ; L15B GOTO MAIN ; フレームエラー ; ボーレートが間違っているかシリアルデータの品質に問題があります。 ; データを読み込むことによってRCSTAはクリアされます。 ; エラー処理は適当です。 M_FERR MOVLW 0xFF ; L15D MOVWF DG1 MOVF RCREG, W GOTO MAIN ; オーバーランエラー ; 処理が間に合っていない? ; RCSTA
をクリアして再度セットします。 ; エラー処理は適当です。 M_OERR BCF RCSTA, CREN ; L161 BSF RCSTA, CREN MOVLW 0xFE MOVWF DG1 GOTO MAIN END
« (ネットで見つけた観測結果・写真へのリンクつき)小惑星2015 TB145の位置予測記事の一覧/まとめ | トップページ | 小惑星2015 TB145の光度等級、高度、月との離角のグラフ »
「時刻と時間」カテゴリの記事
- 星食観測ハンドブック2016とaitendoのGPS受信モジュールNEO6M-ANT-4P(2016.03.15)
- 毎日送信してほしいJJY(標準電波/電波時計)の試験電波(2016.01.26)
- GPS受信モジュールu-blox6/NEO6M-ANT-4Pと温度補償型水晶発振器VM39S5Gの周波数(位相)を比較してみた(2016.01.15)
- GPS受信モジュールNEO6M-ANT-4Pはまじおすすめ、現在在庫数 76(2016.01.13)
- (非公式)JJY(標準電波/電波時計)の呼び出し符号(コールサイン)送出方法(2016.01.13)
コメント
この記事へのコメントは終了しました。
« (ネットで見つけた観測結果・写真へのリンクつき)小惑星2015 TB145の位置予測記事の一覧/まとめ | トップページ | 小惑星2015 TB145の光度等級、高度、月との離角のグラフ »




久々にリンク先にある自分のソースコードを見ましたが、解説がなければ難しくて読めませんね^^;
PICはC言語に移行してしまったらアセンブラで書く気が起きません。メモリがきついとかタイミングがシビアとかいった事情があるときだけでしょうか。
あ、でもこちらのアセンブラはコメントが多くてわかりやすいです^^。
投稿: ほよほよ | 2015年10月27日 (火) 17時04分
ほよほよさんのソースを拝借したというのに気が付くまでにも時間がかかってしまいました (^^;;
お世話になっております m(._.)m
アッセブラーは書くのも大変ですが、逆アッセンブルしたのを読むのはもっと大変でした。
ほんとはCで書き直せばいいんでしょうが....
投稿: セッピーナ | 2015年10月27日 (火) 17時26分