LIST p=12f683 INCLUDE "p12f683.inc" __CONFIG _CP_OFF & _CPD_OFF & _WDT_OFF & _BOD_ON & _IESO_OFF& _PWRTE_ON & _INTOSCIO & _MCLRE_OFF ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;; ;;;;; ワンコインFLデコーダ3 ;;;;; ;;;;; Web Nucky http://web.nucky.jp/ ;;;;; ;;;;; Copyright (C) 2007-2015 Nucky ;;;;; ;;;;; DCC Signal Analysis (0/1 Detection part) ;;;;; Original Programmed by T.Shimizu (Copyright 2007/6) ;;;;; http://www.dokidoki.ne.jp/home2/tohrus/marklin.html ;;;;; ;;;;; 使用PICマイコン PIC16F683  内部発振8MHzモード ;;;;; ;;;;; 2009.03.14 Ver 0.9  PIC12F684版Ver0.95を元に移植 ;;;;;  アナログモードサポート(CV29,CV13) ;;;;; PageModeCV書き込みサポート ;;;;; 2009.04.21 Ver 0.91 14STEP、28STEPサポート ;;;;; 2009.09.07 Ver 1.00 112-127アドレス不具合対策 ;;;;; PageMode CV読み出し機能対応 ;;;;; 2009.09.23 Ver 1.01 PICの5,6,7番ピンの使用方法を変更 ;;;;; 2009.11.03 Ver 1.02 アナログモードへの移行基準変更(32->65mS) ;;;;; 2009.12.11 Ver 1.03 集電不良時の出力断(チラつき)改善 蓄電式対応 ;;;;; 2015.11.07 Ver 3.00 スマイルコネクタ対応専用基板のピン配列に変更 ;;;;; F0以外のファンクション無効化(ICSP端子専用化) ;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;; ;;;;; DCC信号受信タイミング調整 標準値 0x10 ;;;;; ;;;;; 製作後DCC信号の受信に失敗する場合は0x0E〜0x12(16進数)の間で ;;;;;  設定を変えて試してみてください。 ;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; #define CNT 0x10 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;; 入出力ピンの割り当て(定義) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; #define DCC_IN GPIO,2 ; DCC信号入力 #define F0_REV_OUT GPIO,4 ; F0出力(逆方向) #define F0_FOR_OUT GPIO,5 ; F0出力(正方向) ;以下はピン指定なし ;#define F1_OUT GPIO,0 ; F1出力(拡張用) ;#define F2_OUT GPIO,0 ; F2出力(拡張用) ;#define F3_OUT GPIO,0 ; F3出力(拡張用) ;#define F4_OUT GPIO,0 ; F4出力(未使用) ;#define F5_OUT GPIO,0 ; F5出力(未使用) ;#define F6_OUT GPIO,0 ; F6出力(未使用) ;#define F7_OUT GPIO,0 ; F7出力(未使用) ;#define F8_OUT GPIO,0 ; F8出力(未使用) ;#define F9_OUT GPIO,0 ; F9出力(未使用) ;#define F10_OUT GPIO,0 ; F10出力(未使用) ;#define F11_OUT GPIO,0 ; F11出力(未使用) ;#define F12_OUT GPIO,0 ; F12出力(未使用) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;; CV初期値の設定(EEPROMへのデータ定義) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; org 0x2100 ; ;----- 初期データ -------- CV値 ---------------------- de 0x03 ;CV1 2桁アドレス de 0x00 ;CV2    スタート電圧 de 0x00 ;CV3 未使用 加速率 de 0x00 ;CV4 未使用 減速率 de 0xFF ;CV5 最大電圧 de 0x00 ;CV6 未使用 中間点電圧 de .030 ;CV7 Version Number de 0x1D ;CV8 (Manufacturer ID is Public Domain & Do-It-Yourself Decoders 0x0D) CV値RESETに使用 de 0x04 ;CV9 PWM周波数設定 de 0x00 ;CV10 de 0x00 ;CV11 de 0x00 ;CV12 de 0x01 ;CV13 アナログ線路上で運転する場合のファンクションの設定 de 0x00 ;CV14 de 0x00 ;CV15 de 0x00 ;CV16 de 0xC0 ;CV17 4桁アドレス(上位) de 0x80 ;CV18 4桁アドレス(下位) de 0x00 ;CV19 未使用 アドバンストコンシストの制御 de 0x00 ;CV20 de 0x00 ;CV21 未使用 アドバンストコンシストの制御 de 0x00 ;CV22 未使用 アドバンストコンシストの制御 de 0x00 ;CV23 de 0x00 ;CV24 de 0x00 ;CV25 de 0x00 ;CV26 de 0x00 ;CV27 de 0x00 ;CV28 de 0x02 ;CV29 デコーダ機能設定(2桁アドレス使用) ; de 0x26 ;CV29 デコーダ機能設定(4桁アドレス使用) de 0x00 ;CV30 de 0x00 ;CV31 de 0x00 ;CV32 de 0x00 ;CV33 未使用 ファンクションモード選択(0のみ) de 0x00 ;CV34 de 0x00 ;CV35 de 0x00 ;CV36 de 0x00 ;CV37 de 0x00 ;CV38 de 0x00 ;CV39 de 0x00 ;CV40 de 0x00 ;CV41 de 0x00 ;CV42 de 0x00 ;CV43 de 0x00 ;CV44 de 0x00 ;CV45 de 0x00 ;CV46 de 0x00 ;CV47 de 0x00 ;CV48 de 0x00 ;CV49 de 0x00 ;CV50 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;; 変数の定義 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; cblock 0x20 TCNT1 ;DCC信号受信用カウント1 TCNT2 ;DCC信号受信用カウント2 DATA1 ;受信バイト1 DATA2 ;受信バイト2 DATA3 ;受信バイト3 DATA4 ;受信バイト4 DATA5 ;受信バイト5 DATA6 ;受信バイト6 CV01 ;2桁アドレス(16進数) CV02 ;スタート電圧 CV05 ;最高電圧 CV09 ;PWM機能設定 CV13 ;アナログ運転ファンクション設定 CV17 ;4桁アドレス(千、百の位:16進数) CV18 ;4桁アドレス(十、一の位:16進数) CV29 ;デコーダ機能設定 ;CV33 ;入換動力車標識モード DIR_REV ;CV29bit0を反映した方向制御 逆方向で1 正方向で0 DIR_FOR ;CV29bit0を反映した方向制御 逆方向で0 正方向で1 ;SPEED ;速度(PWM) P_REG ;PAGEモード書き込み用変数1 D_REG ;PAGEモード書き込み用変数2 PM_STATUS ;PAGEモード書き込み用STATUS CVEEDATA ;EEPROM書き込み用一時変数 COMMAND ;命令分類用一時変数 W_TEMP ;wレジスタ退避 ST_TEMP ;STATUS退避 CNT1 ;TIMER用変数 CNT2 CNT3 endc ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;; PICマイコンの初期設定 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ORG 0x00 GOTO MAINSTART ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;; 割り込み処理  アナログ運転用簡易処理 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ORG 0x04 ANA_START MOVWF W_TEMP ; WレジスタとSTATUSレジスタの退避 SWAPF STATUS,W MOVWF ST_TEMP BCF PIR1,TMR1IF ; 割り込みフラグクリア ; CLRF GPIO ; GPIO初期化 ←検証要 出力が保持されることの防止 ; BSF CCP1CON,6 ; ここでやっとFull-Bridgeモードに設定 ; ForかRevかは後処理で決定(読込済情報を引き継げるように) ANA_DIR ; アナログ方向制御 BTFSC DCC_IN ;DCC信号入力部の電圧検知して方向判別 0なら次命令をスキップ GOTO ANA_FOR ANA_REV BSF DIR_REV,0 BCF DIR_FOR,0 GOTO ANA_CV29_CHK ANA_FOR BSF DIR_FOR,0 BCF DIR_REV,0 ANA_CV29_CHK MOVLW .28 ; EEPROMから CV29 を読み込み CALL EEPROM_READ MOVWF CV29 BTFSS CV29,2 ; CV29 BIT2=1なら次命令をスキップ GOTO ANA_END ; BIT2=0 なら ANA_END (アナログ変換OFF) BTFSS CV29,0 ; CV29 BIT0=1なら次命令をスキップ GOTO ANA_FUNC ; BIT0=0 なら ANA_FUNC (ファンクション制御へ) MOVF DIR_REV,W ; DIR_REV bit0を 0->1 1->0 と入れ替えてDIR_REVに書き出し XORLW B'00000001' ; MOVWF DIR_REV ; MOVF DIR_FOR,W ; DIR_FOR bit0を 0->1 1->0 と入れ替えてDIR_FORに書き出し XORLW B'00000001' ; MOVWF DIR_FOR ; ANA_FUNC MOVLW .12 ; EEPROMから CV13 を読み込み CALL EEPROM_READ MOVWF CV13 ;F1〜F4をCV13の値に従って出力指示 ; BTFSC CV13,1 ;F1の出力 ; BSF F1_OUT ; BTFSC CV13,2 ;F2の出力 ; BSF F2_OUT ; BTFSC CV13,3 ;F3の出力 ; BSF F3_OUT ; BTFSC CV13,4 ;F4の出力 ; BSF F4_OUT BTFSS CV13,0 ;CV13 Bit0=1なら次命令スキップ GOTO ANA_END BTFSS DIR_REV,0 ;DIR_REV Bit0=1なら次命令スキップ GOTO ANA_F0_FOR ANA_FO_REV ;F0逆方向の出力 BCF F0_FOR_OUT BSF F0_REV_OUT GOTO ANA_END ANA_F0_FOR ;F0正方向の出力 BCF F0_REV_OUT BSF F0_FOR_OUT ;ANA_SPEED ; MOVLW 0xFF ; MOVWF SPEED ; MOVWF CCPR1L ANA_END SWAPF ST_TEMP,W ;WレジスタとSTATUSレジスタの復帰 MOVWF STATUS SWAPF W_TEMP,F SWAPF W_TEMP,W RETFIE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;; メインループ処理 PICマイコンの初期設定 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MAINSTART CLRF GPIO ; GPIO初期化 MOVLW B'00000111' ; コンパレータ使用しない(コンパレータピンはデジタルIO) MOVWF CMCON0 BSF STATUS,RP0 ; バンク1に切り替え CLRF ANSEL ; デジタルIO(AN機能を使用しない) MOVLW B'01110000' ; CLOCK=8MHz MOVWF OSCCON MOVLW B'00001111' ; GP0-3を入力、,GP4-5は出力とする MOVWF TRISIO BSF PIE1,TMR1IE ; TMR1割り込み使用 BCF STATUS,RP0 ; バンク0に切り替え ; MOVLW B'00000001' ; タイマ1オン プリスケーラ1:1 32.768mS MOVLW B'00010001' ; タイマ1オン プリスケーラ1:2 65.536mS ; MOVLW B'00100001' ; タイマ1オン プリスケーラ1:4 131.072mS ; MOVLW B'00110001' ; タイマ1オン プリスケーラ1:8 262.144mS MOVWF T1CON ; BSF INTCON,PEIE ; 割り込み許可 BSF INTCON,GIE ; ; MOVLW B'00001100' ; CCP1CONの初期設定 ; まずは、あえてSingle outputで起動する ; その後bit6,7を設定しFull-Bridgeにする ; これによりDCC信号認識までのRC3の出力を無くす ; MOVLW B'11001100' ; CCP1初期設定 Rev方向 ;; MOVLW B'01001100' ; CCP1初期設定 For方向 ; MOVWF CCP1CON ; ; CLRF CCPR1L ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;; PICマイコンの初期設定 タイマー2(PWM)関連制御 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CV09の値 初期値0x04=00000100 ; *****100 約7.8KHz (2倍時約15.6KHz) ; *****101 約2.0KHz (2倍時約4.0KHz) ; *****110 約500Hz (2倍時約1.0KHz) ; ; ****1*** 周波数の設定を2倍にする ;PWM ; MOVLW .08 ; CV09をEEPROMから読み込む ; CALL EEPROM_READ ; MOVWF CV09 ; BTFSC CV09,3 ; CV09のbit3でPWM周波数が2倍設定が有効となっているかの確認 ; GOTO PWM2_SET ;PWM_SET ; BSF STATUS,RP0 ; MOVLW 0xff ; PR2の最大値0xFF(PWM周波数を1倍に設定) ; MOVWF PR2 ; BCF STATUS,RP0 ; GOTO TIMER2_SET ;PWM2_SET ; BSF STATUS,RP0 ; MOVLW 0x7f ; PR2の最大値0x7F(PWM周波数を2倍に設定) ; MOVWF PR2 ; BCF STATUS,RP0 ;TIMER2_SET ; MOVLW 0x07 ; ANDWF CV09,W ;CV09の下位3BITをT2Conへ ; 0x04 プリスケーラ値1 ; 0x05 プリスケーラ値4 ; 0x06 プリスケーラ値16 ; MOVWF T2CON ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;; 変数初期化 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MAIN CLRF GPIO ; GPIO初期化 ; CLRF SPEED ; SPEED = 0 CLRF PM_STATUS ; PageMode書き込みflagのクリア ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 速度制御 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;STEP000 ; MOVLW .32 ; CV33をEEPROMから読み込む ; CALL EEPROM_READ ; MOVWF CV33 ; BTFSC CV33,1 ; CV33のbit1で両極性FX専用デコーダモードか確認 ; GOTO STEP001 ; 速度処理せずにDCC信号を読み込みする為にJUMP ;CHK_SPEED ; IF SPEED = 0 THEN 0 ; MOVF SPEED,W ; BTFSC STATUS,Z ; GOTO CHK_SPEED_END ; IF SPEED < CV02 THEN CV02 -> SPEED ;CHK_CV02 ; MOVLW .01 ; EEPROM CV02の内容を読み込み ; CALL EEPROM_READ ; MOVWF CV02 ; SUBWF SPEED,W ; BTFSC STATUS,C ; GOTO CHK_CV05 ; MOVF CV02,W ; MOVWF SPEED ; IF SPEED > CV05 THEN CV05 -> SPEED ;CHK_CV05 ; MOVLW .04 ; EEPROM CV05の内容を読み込み ; CALL EEPROM_READ ; MOVWF CV05 ; SUBWF SPEED,W ; BTFSS STATUS,C ; GOTO CHK_SPEED_END ; MOVF CV05,W ; MOVWF SPEED ;CHK_SPEED_END ; BTFSS CV09,3 ; CV09のbit3でPWM周波数が2倍設定が有効となっているかの確認 ; GOTO SET_SPEED ; ; BCF STATUS,C ; フラグCをクリア ; RRF SPEED,F ; SPEED / 2 -> SPEED PR2の最大値7Fにあわせる ;SET_SPEED ; MOVF SPEED,W ; SPEED値をPWM制御に反映 ; MOVWF CCPR1L ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DCCパケット読み込み処理 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; STEP001 CLRF DATA1 CLRF DATA2 CLRF DATA3 CLRF DATA4 CLRF DATA5 CLRF DATA6 CLRF TCNT1 CLRF TCNT2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; プリアンブル検出 ("1"の14個連続を検出) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; AA01 BTFSC DCC_IN GOTO AA05 BTFSC DCC_IN GOTO AA06 MOVLW 0x00 SUBWF TCNT1,W BTFSC STATUS,Z GOTO AA01 MOVLW CNT SUBWF TCNT1,W BTFSC STATUS,C GOTO AA07 INCF TCNT2,F MOVLW 0x0C ; 0x0C(14)bitの"1" SUBWF TCNT2,W BTFSC STATUS,Z GOTO STEP002 CLRF TCNT1 GOTO AA01 AA05 NOP NOP AA06 NOP NOP INCF TCNT1,F GOTO AA01 AA07 CLRF TCNT1 CLRF TCNT2 GOTO AA01 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;     パケットスタートビット検出 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; STEP002 CLRF TCNT1 CLRF TCNT2 BB01 BTFSC DCC_IN GOTO BB05 BTFSC DCC_IN GOTO BB06 MOVLW 0x00 SUBWF TCNT1,W BTFSC STATUS,Z GOTO BB01 MOVLW CNT SUBWF TCNT1,W BTFSC STATUS,C GOTO STEP003 CLRF TCNT1 GOTO BB01 BB05 NOP NOP BB06 NOP NOP INCF TCNT1,F GOTO BB01 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 第1バイト読み込み ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; STEP003 CLRF TMR1L ; パケットスタートビットを正常読み込みしたらTMR1を0に CLRF TMR1H ; (DCC信号がない場合、一定時間でアナログ制御をする為) CLRF TCNT1 CLRF TCNT2 BSF TCNT2,3 CC01 BTFSC DCC_IN GOTO CC05 BTFSC DCC_IN GOTO CC06 MOVLW 0x00 SUBWF TCNT1,W BTFSC STATUS,Z GOTO CC01 MOVLW CNT SUBWF TCNT1,W BTFSC STATUS,C GOTO CC08 RLF DATA1,F BSF DATA1,0 DECFSZ TCNT2,F GOTO CC09 GOTO CC20 CC09 CLRF TCNT1 GOTO CC01 CC05 NOP NOP CC06 NOP NOP INCF TCNT1,F GOTO CC01 CC08 RLF DATA1,F BCF DATA1,0 DECFSZ TCNT2,F GOTO CC09 CC20 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; データバイトスタートビット検出 (1→2) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; STEP004 CLRF TCNT1 CLRF TCNT2 DD01 BTFSC DCC_IN GOTO DD05 BTFSC DCC_IN GOTO DD06 MOVLW 0x00 SUBWF TCNT1,W BTFSC STATUS,Z GOTO DD01 MOVLW CNT SUBWF TCNT1,W BTFSC STATUS,C GOTO STEP005 CLRF TCNT1 GOTO STEP001 DD05 NOP NOP DD06 NOP NOP INCF TCNT1,F GOTO DD01 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 第2 バイト読み込み ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; STEP005 CLRF TCNT1 CLRF TCNT2 BSF TCNT2,3 EE01 BTFSC DCC_IN GOTO EE05 BTFSC DCC_IN GOTO EE06 MOVLW 0x00 SUBWF TCNT1,W BTFSC STATUS,Z GOTO EE01 MOVLW CNT SUBWF TCNT1,W BTFSC STATUS,C GOTO EE08 RLF DATA2,F BSF DATA2,0 DECFSZ TCNT2,F GOTO EE09 GOTO EE20 EE09 CLRF TCNT1 GOTO EE01 EE05 NOP NOP EE06 NOP NOP INCF TCNT1,F GOTO EE01 EE08 RLF DATA2,F BCF DATA2,0 DECFSZ TCNT2,F GOTO EE09 EE20 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; データバイトスタートビット検出 (2→3) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; STEP006 CLRF TCNT1 CLRF TCNT2 FF01 BTFSC DCC_IN GOTO FF05 BTFSC DCC_IN GOTO FF06 MOVLW 0x00 SUBWF TCNT1,W BTFSC STATUS,Z GOTO FF01 MOVLW CNT SUBWF TCNT1,W BTFSC STATUS,C GOTO STEP007 CLRF TCNT1 GOTO STEP001 FF05 NOP NOP FF06 NOP NOP INCF TCNT1,F GOTO FF01 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 第三バイト読み込み ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; STEP007 CLRF TCNT1 CLRF TCNT2 BSF TCNT2,3 GG01 BTFSC DCC_IN GOTO GG05 BTFSC DCC_IN GOTO GG06 MOVLW 0x00 SUBWF TCNT1,W BTFSC STATUS,Z GOTO GG01 MOVLW CNT SUBWF TCNT1,W BTFSC STATUS,C GOTO GG08 RLF DATA3,F BSF DATA3,0 DECFSZ TCNT2,F GOTO GG09 GOTO GG20 GG09 CLRF TCNT1 GOTO GG01 GG05 NOP NOP GG06 NOP NOP INCF TCNT1,F GOTO GG01 GG08 RLF DATA3,F BCF DATA3,0 DECFSZ TCNT2,F GOTO GG09 GG20 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; データバイトスタートビット検出 (3→4) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; STEP008 CLRF TCNT1 CLRF TCNT2 HH01 BTFSC DCC_IN GOTO HH05 BTFSC DCC_IN GOTO HH06 MOVLW 0x00 SUBWF TCNT1,W BTFSC STATUS,Z GOTO HH01 MOVLW CNT SUBWF TCNT1,W BTFSC STATUS,C GOTO STEP081 CLRF TCNT1 GOTO CHK_ERR ; パケットエンドならエラー判別へ HH05 NOP NOP HH06 NOP NOP INCF TCNT1,F GOTO HH01 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 第四バイト読み込み ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; STEP081 CLRF TCNT1 CLRF TCNT2 BSF TCNT2,3 II01 BTFSC DCC_IN GOTO II05 BTFSC DCC_IN GOTO II06 MOVLW 0x00 SUBWF TCNT1,W BTFSC STATUS,Z GOTO II01 MOVLW CNT SUBWF TCNT1,W BTFSC STATUS,C GOTO II08 RLF DATA4,F BSF DATA4,0 DECFSZ TCNT2,F GOTO II09 GOTO II20 II09 CLRF TCNT1 GOTO II01 II05 NOP NOP II06 NOP NOP INCF TCNT1,F GOTO II01 II08 RLF DATA4,F BCF DATA4,0 DECFSZ TCNT2,F GOTO II09 II20 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; データバイトスタートビット検出 (4→5) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; STEP082 CLRF TCNT1 CLRF TCNT2 JJ01 BTFSC DCC_IN GOTO JJ05 BTFSC DCC_IN GOTO JJ06 MOVLW 0x00 SUBWF TCNT1,W BTFSC STATUS,Z GOTO JJ01 MOVLW CNT SUBWF TCNT1,W BTFSC STATUS,C GOTO STEP083 CLRF TCNT1 GOTO CHK_ERR ;パケットエンドビット「1」を検出したらCHK_ERRへ JJ05 NOP NOP JJ06 NOP NOP INCF TCNT1,F GOTO JJ01 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 第5バイト読み込み ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; STEP083 CLRF TCNT1 CLRF TCNT2 BSF TCNT2,3 KK01 BTFSC DCC_IN GOTO KK05 BTFSC DCC_IN GOTO KK06 MOVLW 0x00 SUBWF TCNT1,W BTFSC STATUS,Z GOTO KK01 MOVLW CNT SUBWF TCNT1,W BTFSC STATUS,C GOTO KK08 RLF DATA5,F BSF DATA5,0 DECFSZ TCNT2,F GOTO KK09 GOTO KK20 KK09 CLRF TCNT1 GOTO KK01 KK05 NOP NOP KK06 NOP NOP INCF TCNT1,F GOTO KK01 KK08 RLF DATA5,F BCF DATA5,0 DECFSZ TCNT2,F GOTO KK09 KK20 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; データバイトスタートビット検出 (5→6) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; STEP084 CLRF TCNT1 CLRF TCNT2 LL01 BTFSC DCC_IN GOTO LL05 BTFSC DCC_IN GOTO LL06 MOVLW 0x00 SUBWF TCNT1,W BTFSC STATUS,Z GOTO LL01 MOVLW CNT SUBWF TCNT1,W BTFSC STATUS,C GOTO STEP009 CLRF TCNT1 GOTO CHK_ERR ;パケットエンドビット「1」を検出したらCHK_ERRへ LL05 NOP NOP LL06 NOP NOP INCF TCNT1,F GOTO LL01 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 第6バイト読み込み (最終バイト) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; STEP009 CLRF TCNT1 CLRF TCNT2 BSF TCNT2,3 MM01 BTFSC DCC_IN GOTO MM05 BTFSC DCC_IN GOTO MM06 MOVLW 0x00 SUBWF TCNT1,W BTFSC STATUS,Z GOTO MM01 MOVLW CNT SUBWF TCNT1,W BTFSC STATUS,C GOTO MM08 RLF DATA6,F BSF DATA6,0 DECFSZ TCNT2,F GOTO MM09 GOTO MM20 MM09 CLRF TCNT1 GOTO MM01 MM05 NOP NOP MM06 NOP NOP INCF TCNT1,F GOTO MM01 MM08 RLF DATA6,F BCF DATA6,0 DECFSZ TCNT2,F GOTO MM09 MM20 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;; DCCパケット エラーチェック ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CHK_ERR MOVF DATA1,W ; DATA1 -> W XORWF DATA2,W ; W XOR DATA2 -> W XORWF DATA3,W ; W XOR DATA3 -> W XORWF DATA4,W ; W XOR DATA4 -> W XORWF DATA5,W ; W XOR DATA5 -> W XORWF DATA6,W ; W XOR DATA6 -> W BTFSS STATUS,Z GOTO STEP001 ; 結果が0にならない(=エラー)ならSTEP001へ戻る ; パケットスタートビットを認識したらタイマーをリセットする処理に変更した ; CLRF TMR1L ; DCCパケットを正常読み込みしたらTMR1を0に ; CLRF TMR1H ; (自分のアドレス以外の正常読み込みでも0にする) ; (DCC信号を読み取れなくなったら一定時間でアナログ制御をする為) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;; 第一バイトの判別 (アドレスの処理) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;00000000 (0) : Broadcast address ;00000001-01101111 (001-111): Multi-Function decoders with 7 bit addresses ;01110000-01111111 (112-127): Service Mode ;10000000-10111111 (128-191): Basic Accessory Decoders with 9 bit addresses and Extended Accessory Decoders with 11-bit addresses ;11000000-11100111 (192-231): Multi Function Decoders with 14 bit addresses ;11101000-11111110 (232-254): Reserved for Future Use ;11111111 (255) : Idle Packet CHK_DATA1 COMF DATA1,W ; アイドルパケット? BTFSS STATUS,Z GOTO CHK_DATA1_2 ; CLRF PM_STATUS ; アイドルパケットならSM_STATUSクリアし GOTO STEP001 ; STEP001に戻る CHK_DATA1_2 MOVF DATA1,W ; ブロードキャストアドレスなら BTFSC STATUS,Z GOTO DCDR_CNT ; 停止制御 BTFSC DATA1,7 ; DATA1のbit7を確認し「0」なら次命令をスキップ GOTO CHK_LONGADR ; 4桁アドレスの確認処理へ ANDLW 0x70 ; サービスモードの確認へ XORLW 0x70 BTFSC STATUS,Z GOTO CHECK_SM CHK_ADR CLRF PM_STATUS ; PageMode書き込みflagのオールクリア MOVLW .28 ; CV29をEEPROMから読み込む CALL EEPROM_READ MOVWF CV29 BTFSC CV29,5 ; CV29のbit5で2桁アドレスが有効となっているかの確認 GOTO STEP001 ; 有効でないならSTEP001へ戻る MOVLW .00 ; 2桁アドレスの確認  第一バイトがCV01と一致か? (EEPROMのアドレスはCV番号-1) CALL EEPROM_READ XORWF DATA1,W BTFSS STATUS,Z GOTO STEP001 ; 不一致ならSTEP001へ GOTO DECODE ; 一致ならDECODE処理へ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;; 4桁アドレスの処理 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CHK_LONGADR CLRF PM_STATUS ; PageMode書き込みflagのオールクリア MOVLW .28 ; CV29をEEPROMから読み込む CALL EEPROM_READ MOVWF CV29 BTFSS CV29,5 ; CV29のbit5で4桁アドレスが有効となっているかの確認 GOTO STEP001 ; 有効でないならSTEP001へ戻る MOVF DATA1,W addlw 0xff - .230 ; CV17の最高値は230である 231以上か?(data1 + .25 で桁上がり発生?) BTFSC STATUS,C GOTO STEP001 MOVLW .16 ;第一バイトがCV17と一致か? (EEPROMのアドレスはCV番号-1) CALL EEPROM_READ XORWF DATA1,W BTFSS STATUS,Z GOTO STEP001 MOVLW .17 ;第二バイトがCV18と一致か? (EEPROMのアドレスはCV番号-1) CALL EEPROM_READ XORWF DATA2,W BTFSS STATUS,Z GOTO STEP001 MOVF DATA3,W ; 4桁アドレスのとき、データをシフトする(後の処理を2桁アドレスと同じにする) MOVWF DATA2 MOVF DATA4,W MOVWF DATA3 MOVF DATA5,W MOVWF DATA4 ; DATA6はエラーチェックバイトのためシフトしない ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;; 第二バイトの判別 (命令の処理) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DECODE MOVF DATA2,W ; 命令判断処理 andlw B'11100000' ; DATA2の先頭3バイトで区別する MOVWF COMMAND XORLW B'00100000' ; アドバンスト動作命令 BTFSC STATUS,Z GOTO ADVANCE MOVF COMMAND,W XORLW B'10000000' ; ファンクション(機能)1グループ命令 BTFSC STATUS,Z GOTO FUNCTION1 MOVF COMMAND,W XORLW B'11100000' ; 動作モードCV命令 BTFSC STATUS,Z GOTO CV_Access MOVF COMMAND,W XORLW B'00000000' ; デコーダ、統括制御命令 BTFSC STATUS,Z GOTO DCDR_CNT MOVF COMMAND,W XORLW B'01000000' ; 速度方向命令(逆方向)(14,28ステップ)(未サポート) BTFSC STATUS,Z GOTO SPEEDDIRECTION MOVF COMMAND,W XORLW B'01100000' ; 速度方向命令(正方向)(14,28ステップ)(未サポート) BTFSC STATUS,Z GOTO SPEEDDIRECTION MOVF COMMAND,W XORLW B'10100000' ; ファンクション(機能)2グループ命令 BTFSC STATUS,Z GOTO FUNCTION2 GOTO STEP001 ; 予約(未使用命令) もしくは それ以外 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;; 速度方向命令(逆、正方向)(14,28ステップ)処理 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SPEEDDIRECTION ; 方向命令の読み出しと演算 MOVLW .28 ; EEPROMから CV29 を読み込み CALL EEPROM_READ MOVWF CV29 BTFSS CV29,0 ; CV29 BIT0=1なら次命令をスキップ GOTO CHK_14STEP ; BIT=0 なら CHK_14STEPへ MOVF DATA2,W ; CV29 Bit1=1のとき方向命令を0->1 1->0に入替 XORLW B'00100000' ; DATA2 bit5 を 0->1 1->0 と入れ替えてDATA2に書き出し MOVWF DATA2 ; CHK_14STEP BTFSC CV29,1 ; CV29 BIT1=0なら次命令をスキップ GOTO SD_SPEED ; BIT=1 なら SD_SPEED F0_14STEP BTFSS DATA2,4 ; F0制御(Bit4および方向速度命令、CV29のbit0) GOTO F0_14STEP_C ; BIT4=0なら消灯 F0_14STEP_FOR BTFSS DATA2,5 ; DATA2 bit5=1 なら次命令をスキップ GOTO F0_14STEP_REV BSF F0_FOR_OUT ; F0正方向点灯 BCF F0_REV_OUT ; F0逆方向消灯 GOTO F0_14STEP_END F0_14STEP_REV BSF F0_REV_OUT ; F0逆方向点灯 BCF F0_FOR_OUT ; F0正方向消灯 GOTO F0_14STEP_END F0_14STEP_C BCF F0_REV_OUT ; F0逆方向消灯 BCF F0_FOR_OUT ; F0正方向消灯 F0_14STEP_END BSF DATA2,4 ; 強制的にbit4=1とし28ステップの偶数ステップに揃える SD_SPEED ; BSF STATUS,C ; Bit5をBit1に左シフトする前に ; BTFSS DATA2,4 ; DATA2 bit4の内容をCフラグに代入しておく ; BCF STATUS,C ; ; MOVF DATA2,W ; ANDLW B'00001111' ; MOVWF SPEEDTBL ; RLF SPEEDTBL,F ; SPEEDTBL 1bitシフト -> SPEEDTBL ; BSF SPEEDTBL,5 ; SPEEDTBL bit5=1 ; MOVF SPEEDTBL,W ; CALL EEPROM_READ ; EEPROMからSPEEDTBLに応じたCV値を読み込んで ; MOVWF SPEED ; SPEEDへ代入する ; BSF CCP1CON,6 ; ここでやっとFull-Bridgeモードに設定 ; ForかRevかは後処理で決定(読込済情報を引き継げるように) SD_CHK_DIR ; 方向の制御ビットで処理分岐 BTFSC DATA2,5 ; 命令バイトのbit5が0なら逆方向制御 GOTO SD_FOR SD_REV ; 逆方向制御 bit7=0 BSF DIR_REV,0 ; DIR_REVを1に BCF DIR_FOR,0 ; DIR_FORを0に ; BSF CCP1CON,7 ; Full-Bridge output reverseに設定 GOTO STEP001 ; DCC信号読み取り SD_FOR ; 正方向制御 Bit7=1 BSF DIR_FOR,0 ; DIR_FORを1に BCF DIR_REV,0 ; DIR_REVを0に ; BCF CCP1CON,7 ; Full-Bridge output forwardに設定 GOTO STEP001 ; DCC信号読み取り ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;; アドバンスト動作命令処理 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ADVANCE MOVLW 0x3F ; 命令第一バイトが00111111(0x3F)の場合128step速度制御命令 SUBWF DATA2,W BTFSS STATUS,Z GOTO STEP001 ; 命令が一致しなければGOTO STEP001 ; 命令第二バイトの解析 ;CHK_SPD ; 速度命令の読み出しと演算 ; MOVF DATA3,W ; DATA3 -> W ; MOVWF SPEED ; W -> SPEED ; BCF STATUS,C ; フラグCをクリア ; RLF SPEED,F ; SPEED * 2 -> SPEED ; BSF CCP1CON,6 ; ここでやっとFull-Bridgeモードに設定 ; ForかRevかは後処理で決定(読込済情報を引き継げるように) CHK_DIR ; 方向命令の読み出しと演算 MOVLW .28 ; EEPROMから CV29 を読み込み CALL EEPROM_READ MOVWF CV29 BTFSS CV29,0 ; CV29 BIT0=1なら次命令をスキップ GOTO CHK_DIR2 ; BIT=0 なら CHK_DIR2 MOVF DATA3,W ; DATA3を 0->1 1->0 と入れ替えてDATA3に書き出し XORLW B'11111111' ; MOVWF DATA3 ; CHK_DIR2 ; 方向の制御ビットで処理分岐 BTFSC DATA3,7 ; 命令第二バイトのbit7が0なら逆方向制御 GOTO AD_FOR AD_REV ; 逆方向制御 bit7=0 BSF DIR_REV,0 ; DIR_REVを1に BCF DIR_FOR,0 ; DIR_FORを0に ; BSF CCP1CON,7 ; Full-Bridge output reverseに設定 GOTO STEP001 ; 速度制御してからDCC信号読み取り AD_FOR ; 正方向制御 Bit7=1 BSF DIR_FOR,0 ; DIR_FORを1に BCF DIR_REV,0 ; DIR_REVを0に ; BCF CCP1CON,7 ; Full-Bridge output forwardに設定 GOTO STEP001 ; 速度制御してからDCC信号読み取り ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;; ファンクション(機能)1グループ命令 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; FUNCTION1 ; MOVLW .32 ; EEPROMから CV33 を読み込み ; CALL EEPROM_READ ; MOVWF CV33 ; BTFSC CV33,0 ; BIT0=0なら次命令をスキップ ; GOTO Switching_Mode ; 入換動力車標識モードへ ; BTFSC CV33,1 ; BIT1=0なら次命令をスキップ ; GOTO Function_Mode ; 両極性FX専用デコーダモードへ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;; ファンクション(機能)1グループ命令 通常処理 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;CHK_F1 ; BTFSS DATA2,0 ; F1制御(bit0) ; GOTO C_F1 ;S_F1 ; BSF F1_OUT ; GOTO E_F1 ;C_F1 ; BCF F1_OUT ;E_F1 ;CHK_F2 ; BTFSS DATA2,1 ; F2制御(bit1) ; GOTO C_F2 ;S_F2 ; BSF F2_OUT ; GOTO E_F2 ;C_F2 ; BCF F2_OUT ;E_F2 ;CHK_F3 ; BTFSS DATA2,2 ; F3制御(bit2) ; GOTO C_F3 ;S_F3 ; BSF F3_OUT ; GOTO E_F3 ;C_F3 ; BCF F3_OUT ;E_F3 ;CHK_F4 ; BTFSS DATA2,3 ; F4制御(bit3) ; GOTO C_F4 ;S_F4 ; BSF F4_OUT ; GOTO E_F4 ;C_F4 ; BCF F4_OUT ;E_F4 CHK_F0 ; BTFSC CV33,1 ; BIT1=0なら次命令をスキップ ; GOTO Function_Mode ; 両極性FX専用デコーダモードへ ; CV29のbit1が0のときは無視する(NMRA) MOVLW .28 ; EEPROMから CV29 を読み込み CALL EEPROM_READ MOVWF CV29 BTFSS CV29,1 ; CV29 BIT1=1なら次命令をスキップ GOTO STEP001 ; BIT1=0 なら STEP001 BTFSS DATA2,4 ; F0制御(bit4および方向速度命令、CV29のbit1) GOTO C_F0 ; BIT4=0ならCLR_F0 S_F0_FOR BTFSS DIR_FOR,0 ; DIR_FOR=1なら次命令をスキップ GOTO S_F0_REV BSF F0_FOR_OUT ; F0正方向点灯 BCF F0_REV_OUT ; F0逆方向消灯 GOTO STEP001 S_F0_REV BSF F0_REV_OUT ; F0逆方向点灯 BCF F0_FOR_OUT ; F0正方向消灯 GOTO STEP001 C_F0 BCF F0_REV_OUT ; F0逆方向消灯 BCF F0_FOR_OUT ; F0正方向消灯 GOTO STEP001 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;; ファンクション(機能)1グループ命令 入換動力車標識モード処理 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Switching_Mode ;SM_CHK_F1 ; BTFSS DATA2,0 ; F1制御(bit0) ; GOTO SM_C_F1 ; BIT0=0ならSM_C_F1 ;SM_S_F1_FOR ; BTFSS DIR_FOR,0 ; DIR_FOR=1なら次命令をスキップ ; GOTO SM_S_F1_REV ; BSF F3_OUT ; F3正方向点灯 ; BSF F4_OUT ; F4正方向点灯 ; BCF F1_OUT ; F1逆方向消灯 ; BCF F2_OUT ; F2逆方向消灯 ; GOTO SM_CHK_F3 ;SM_S_F1_REV ; BSF F1_OUT ; F1逆方向点灯 ; BSF F2_OUT ; F2逆方向点灯 ; BCF F3_OUT ; F3正方向消灯 ; BCF F4_OUT ; F4正方向消灯 ; GOTO SM_CHK_F3 ;SM_C_F1 ; BCF F1_OUT ; F1逆方向消灯 ; BCF F2_OUT ; F2逆方向消灯 ; BCF F3_OUT ; F3正方向消灯 ; BCF F4_OUT ; F4正方向消灯 ;SM_CHK_F3 ; BTFSS DATA2,2 ; F3制御(bit2) ; GOTO SM_CHK_F0 ;SM_S_F3 ; BSF F2_OUT ; BSF F4_OUT ; BCF F1_OUT ; BCF F3_OUT ; GOTO SM_CHK_F0 ;SM_C_F3 ; BCF F1_OUT ; BCF F2_OUT ; BCF F3_OUT ; BCF F4_OUT ;SM_CHK_F0 ; CV29のbit1が0のときは無視する(NMRA) ; MOVLW .28 ; EEPROMから CV29 を読み込み ; CALL EEPROM_READ ; MOVWF CV29 ; BTFSS CV29,1 ; CV29 BIT1=1なら次命令をスキップ ; GOTO SM_C_F0 ; BIT1=0 なら CLR_F0 ; BTFSS DATA2,4 ; F0制御(bit4および方向速度命令、CV29のbit0) ; GOTO SM_C_F0 ; BIT4=0ならCLR_F0 ;SM_S_F0_FOR ; BTFSS DIR_FOR,0 ; DIR_FOR=1なら次命令をスキップ ; GOTO SM_S_F0_REV ; BSF F0_FOR_OUT ; F0正方向点灯 ; BCF F0_REV_OUT ; F0逆方向消灯 ; GOTO STEP001 ;SM_S_F0_REV ; BSF F0_REV_OUT ; F0逆方向点灯 ; BCF F0_FOR_OUT ; F0正方向消灯 ; GOTO STEP001 ;SM_C_F0 ; BCF F0_REV_OUT ; F0逆方向消灯 ; BCF F0_FOR_OUT ; F0正方向消灯 ; GOTO STEP001 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;; ファンクション(機能)1グループ命令 両極性FX専用デコーダモード ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Function_Mode ;FM_CHK_F0 ; CV29のbit1が0のときは無視する(NMRA) ; MOVLW .28 ; EEPROMから CV29 を読み込み ; CALL EEPROM_READ ; MOVWF CV29 ; BTFSS CV29,1 ; CV29 BIT1=1なら次命令をスキップ ; GOTO FM_C_F0 ; BIT1=0 なら CLR_F0 ; BTFSS DATA2,4 ; F0制御(bit4および方向速度命令、CV29のbit0) ; GOTO FM_C_F0 ; BIT4=0ならCLR_F0 ;FM_S_F0 ; MOVLW 0xFF ; F0点灯->SPEED ; MOVWF SPEED ; GOTO CHK_SPEED_END ;FM_C_F0 ; CLRF SPEED ; F0消灯->SPEED ; GOTO CHK_SPEED_END ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;; ファンクション(機能)2グループ命令 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; FUNCTION2 BTFSS DATA2,5 ; S=1なら次命令をスキップ GOTO FUNC2_S0 ;S=1 F5-F8 FUNC2_S1 ;CHK_F5 ; BTFSS DATA2,0 ; F5制御(bit0) ; GOTO C_F5 ;S_F5 ; BSF F5_OUT ; GOTO E_F5 ;C_F5 ; BCF F5_OUT ;E_F5 ;CHK_F6 ; BTFSS DATA2,1 ; F6制御(bit1) ; GOTO C_F6 ;S_F6 ; BSF F6_OUT ; GOTO E_F6 ;C_F6 ; BCF F6_OUT ;E_F6 ;CHK_F7 ; BTFSS DATA2,2 ; F7制御(bit2) ; GOTO C_F7 ;S_F7 ; BSF F7_OUT ; GOTO E_F7 ;C_F7 ; BCF F7_OUT ;E_F7 ;CHK_F8 ; BTFSS DATA2,3 ; F8制御(bit3) ; GOTO C_F8 ;S_F8 ; BSF F8_OUT ; GOTO E_F8 ;C_F8 ; BCF F8_OUT ;E_F8 GOTO STEP001 ;S=0 F9-F12 FUNC2_S0 ;CHK_F9 ; BTFSS DATA2,0 ; F9制御(bit0) ; GOTO C_F9 ;S_F9 ; BSF F9_OUT ; GOTO E_F9 ;C_F9 ; BCF F9_OUT ;E_F9 ;CHK_F10 ; BTFSS DATA2,1 ; F10制御(bit1) ; GOTO C_F10 ;S_F10 ; BSF F10_OUT ; GOTO E_F10 ;C_F10 ; BCF F10_OUT ;E_F10 ;CHK_F11 ; BTFSS DATA2,2 ; F11制御(bit2) ; GOTO C_F11 ;S_F11 ; BSF F11_OUT ; GOTO E_F11 ;C_F11 ; BCF F11_OUT ;E_F11 ;CHK_F12 ; BTFSS DATA2,3 ; F12制御(bit3) ; GOTO C_F12 ;S_F12 ; BSF F12_OUT ; GOTO E_F12 ;C_F12 ; BCF F12_OUT ;E_F12 GOTO STEP001 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;; 動作モードCV命令 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CV_Access MOVLW B'11101100' ; CVのバイト書き込みのみサポート(内容確認、ビット操作は未サポート) SUBWF DATA2,W BTFSS STATUS,Z GOTO STEP001 ; 命令が一致しなければSTEP001へ MOVLW .07 ; 書き込み命令のCVはCV8か? XORWF DATA3,W BTFSC STATUS,Z GOTO CV_RESET ; CV8ならCV_RESETへ MOVF DATA4,W ; 書き込むデータをCVEEDATAに読み込み MOVWF CVEEDATA MOVF DATA3,W ; 書き込むアドレスをWに読み込み CALL EEPROM_WRITE GOTO MAIN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;; サービスモード解析 PAGEモードのみサポート ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CHECK_SM ; アドレス112-127かサービスモードかのチェックを行う BTFSS PM_STATUS,0 ; リセットパケットは受信済みか? GOTO CHK_ADR ; アドレス112-127として2桁アドレス処理へ ; BTFSS DATA1,3 ; WRITEモードか? (Verifyは未サポート) ; GOTO STEP001 ; BIT3=1(Writeモード)ならスキップ BTFSS DATA1,2 ; BIT2が0ならDataRegister 0-3 GOTO DATA_REG ; BIE2=1ならスキップ BTFSC DATA1,1 ; BIT1が0ならBasicConfRegiかPagingRegister GOTO STEP001 ; Bit=0ならスキップ BTFSS DATA1,0 ; BIT1が 0ならBasicConfRegi 1ならPagingRegister GOTO BSC_CNF_REG ; BIT=1ならスキップ GOTO PAGE_REG ; PAGE_REG MOVF DATA2,W ; DATA2 -> W MOVWF P_REG ; W -> P_REG DECF P_REG,F ; P_REG - 1 -> P_REG BCF STATUS,C ; P_REG * 4 -> P_REG RLF P_REG ; BCF STATUS,C ; RLF P_REG ; BSF PM_STATUS,1 ; PageMode PageRegi読み込み済み CALL BASIC_ACK ; BASIC ACK 応答 GOTO STEP001 ; DATA_REG BTFSS PM_STATUS,1 ; PM_STATUSのBIT1が1なら処理継続、0ならSTEP001へ GOTO STEP001 ; BIT1=1ならスキップ MOVF DATA1,W ; DATA1 -> W ANDLW B'00000011' ; BIT0,1を取り出し ADDWF P_REG,W ; P_REGに加え、D_REGに代入 MOVWF D_REG ; cv8ならCV_default_WRITEへ MOVLW .07 ; CV8への処理か? (書き込み命令か?) XORWF D_REG,W BTFSC STATUS,Z GOTO PM_CV_RESET ; 8ならCV_default_WRITEへ BTFSS DATA1,3 ; WRITEモード? Verify? GOTO DATA_REG_VERIFY ; BIT3=1(Writeモード)ならスキップ DATA_REG_WRITE MOVF DATA2,W ; DATA2の内容をCVに書き込む MOVWF CVEEDATA ; MOVF D_REG,W ; D_REG -> W CALL EEPROM_WRITE ; CLRF D_REG CLRF PM_STATUS ; PageMode書込み完了 CALL BASIC_ACK ; BASIC ACK 応答 GOTO STEP001 ; DATA_REG_VERIFY MOVF D_REG,W ; D_REGで指定のCV読み込み CALL EEPROM_READ SUBWF DATA2,W ; DATA2と比較する BTFSS STATUS,Z ; 一致Z=1 不一致Z=0 GOTO STEP001 ; 不一致なら読み込み継続 CLRF D_REG ; 一致したらレジスタクリアしてACK処理 CLRF PM_STATUS ; PageMode書込み完了 CALL BASIC_ACK ; BASIC ACK 応答 GOTO STEP001 ; BSC_CNF_REG BTFSS PM_STATUS,1 ; PM_STATUSのBIT1が1なら書き込み、0なら書き込まない GOTO STEP001 ; BIT1=1ならスキップ BTFSS DATA1,3 ; WRITEモード? Verify? GOTO BSC_CNF_VERFY ; BIT3=1(Writeモード)ならスキップ BSC_CNF_WRITE MOVF DATA2,W ; DATA2の内容をCV29に書き込む MOVWF CVEEDATA ; MOVLW .28 ; CALL EEPROM_WRITE ; CLRF P_REG CLRF PM_STATUS ; PageMode書込み完了 CALL BASIC_ACK ; BASIC ACK 応答 GOTO STEP001 ; BSC_CNF_VERFY MOVLW .28 ; CV29の読み込み CALL EEPROM_READ SUBWF DATA2,W ; DATA2と比較する BTFSS STATUS,Z ; 一致Z=1 不一致Z=0 GOTO STEP001 ; 不一致なら読み込み継続 CLRF P_REG ; 一致したらレジスタクリアしてACK処理 CLRF PM_STATUS ; PageMode書込み完了 CALL BASIC_ACK ; BASIC ACK 応答 GOTO STEP001 ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;; デコーダ、統括制御命令 (一斉停止のみサポート) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DCDR_CNT MOVF DATA1,W ; 第1バイトが0x00、第2バイトが0x00なら XORWF DATA2,W ; デコーダリセット命令である BTFSS STATUS,Z ; Xorして0なら次命令をスキップ GOTO STEP001 BSF PM_STATUS,0 ; RESETパケット受信済みフラグセット ; CLRF SPEED ; 速度0、ファンクション出力0 制御 ; CLRF PORTA ; CLRF PORTC CLRF GPIO GOTO STEP001 ; 速度情報を反映したのちDCC信号の読み取り ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;; EEPROMの書き込み、読み込み (サブルーチン) CV設定をEEPROMに保存、読み出し ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; EEPROM_WRITE ; 書き込みアドレスをWに、書き込みデータをCVEEDATAに BSF STATUS,RP0 MOVWF EEADR BCF STATUS,RP0 MOVF CVEEDATA,W BSF STATUS,RP0 MOVWF EEDATA BSF EECON1,WREN MOVLW 0x55 MOVWF EECON2 MOVLW 0xAA MOVWF EECON2 BSF EECON1,WR WRITE_WAIT BTFSC EECON1,WR GOTO WRITE_WAIT BCF STATUS,RP0 RETURN EEPROM_READ ; 読み込みアドレスをWに、読み込んだデータをWへ BSF STATUS,RP0 MOVWF EEADR BSF EECON1,RD MOVF EEDATA,W BCF STATUS,RP0 RETURN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;; CV値のリセット PageMode の際 CV8書き込み命令の値は8か? ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; PM_CV_RESET MOVLW .08 XORWF DATA2,W BTFSS STATUS,Z GOTO CV_default_WRITE_END ; 8以外ならCV_default_WRITE_ENDへ GOTO CV_default_WRITE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;; CV値のリセット CV8書き込み命令の値は8か? ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CV_RESET MOVLW .08 XORWF DATA4,W BTFSS STATUS,Z GOTO STEP001 ; 8以外ならSTEP001へ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;; CV値のリセット (サブルーチン) CV設定を初期状態にもどす ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CV_default_WRITE ;===== CV01 2桁アドレス 01〜127 ====================================== MOVLW 0x03 ; 初期値03 MOVWF CVEEDATA ; MOVLW .00 ; CALL EEPROM_WRITE; ;===== CV02 スタート電圧 00〜255 ====================================== ; MOVLW 0x00 ; 初期値00 ; MOVWF CVEEDATA ; ; MOVLW .01 ; ; CALL EEPROM_WRITE; ;===== CV05 最大電圧 00〜255 ======================================== ; MOVLW 0xFF ; 初期値255 ; MOVWF CVEEDATA ; ; MOVLW .04 ; ; CALL EEPROM_WRITE; ;===== CV13 アナログ線路上で運転する場合のファンクションの設定 0〜15 ============= MOVLW 0x01 ; 初期値1(F0のみ) MOVWF CVEEDATA ; MOVLW .12 ; CALL EEPROM_WRITE; ; bit[0]: F0をアナログ運転時に[0]OFF/[1]ON ; bit[1]: F1をアナログ運転時に[0]OFF/[1]ON ; bit[2]: F2をアナログ運転時に[0]OFF/[1]ON ; bit[3]: F3をアナログ運転時に[0]OFF/[1]ON ; bit[4]: F4をアナログ運転時に[0]OFF/[1]ON 未使用 ; bit[5]: 未使用 ; bit[6]: 未使用 ; bit[7]: 未使用 ;===== CV17 4桁アドレス(上位) 192〜230 ================================= MOVLW 0xC0 ; 初期値192 MOVWF CVEEDATA ; 4桁アドレスは0128〜9983 MOVLW .16 ;   アドレス0128はCV17=192、CV18=128 CALL EEPROM_WRITE;   アドレス9983はCV17=230、CV18=255 ;===== CV18 4桁アドレス(下位) 128〜255 ================================= MOVLW 0x80 ; 初期値128 MOVWF CVEEDATA ; MOVLW .17 ; CALL EEPROM_WRITE; ;===== CV29 デコーダ動作設定 0〜55 ====================================== MOVLW 0x02 ; 初期値02 MOVWF CVEEDATA ; MOVLW .28 ; CALL EEPROM_WRITE; ; bit[0]: [0]進行方向「正」 / [1]進行方向逆 :サポート ; bit[1]: [0]14ステップ / [1]28,128ステップ :サポート ; bit[2]: [0]アナログ変換OFF / [1]アナログ変換ON :サポート ; bit[3]: :不使用 ; bit[4]: [0]スピードテーブルOFF / [1]スピードテーブルON :不使用 ; bit[5]: [0]2桁アドレス / [1]4桁アドレス :サポート(本機能で2/4桁アドレスを切り替え) ; bit[6]: :不使用 ; bit[7]: :不使用 ;===== CV33 ファンクション設定切替 ==============================  0のみ ==== ; MOVLW 0x00 ; 初期値0 ; MOVWF CVEEDATA ; ; MOVLW .32 ; ; CALL EEPROM_WRITE; ; 0:通常モード F0〜F3個別出力 ;===== CV9 モータPWM周波数設定 ======================================== ; MOVLW 0x04 ; 初期値04 ; MOVWF CVEEDATA ; ; MOVLW .08 ; ; CALL EEPROM_WRITE; CV_default_WRITE_END CLRF P_REG BCF PM_STATUS,0 ; PageMode flagクリア(書込み完了) GOTO MAIN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Basic Acknowlegment ; 6mSec +-1mS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; BASIC_ACK ; MOVLW B'11001100' ; CCP1初期設定 Rev方向 ; MOVWF CCP1CON ; ; MOVLW 0xFF ; MOVWF SPEED ; MOVWF CCPR1L MOVLW 0xFF ; MOVWF PORTA ; MOVWF PORTC MOVWF GPIO CALL TIME1mS CALL TIME1mS CALL TIME1mS CALL TIME1mS CALL TIME1mS CALL TIME1mS ; CLRF PORTA ; CLRF PORTC ; CLRF SPEED ; CLRF CCPR1L ; CLRF CCP1CON CLRF GPIO RETURN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Timer Routine at 8MHz (1COMMAND=0.5uS) ; TIME10uS :10uSec ; TIME1mS :1mSec ; TIME60mS :60mSec ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; TIME10uS ; 1+1+(1+2)*5-1+2=18 10uS=20Cycle MOVLW D'5' ; 1 MOVWF CNT1 ; 1 T_LP1 DECFSZ CNT1,F ; 1 OR 2 GOTO T_LP1 ; 2 RETURN ; 2 TIME1mS ; 1+1+(20+2+2)*83-1+1+2=1996 1mS=2000Cycle MOVLW D'83' ; 1 MOVWF CNT2 ; 1 T_LP2 CALL TIME10uS ; 20 GOTO $+1 ; 2 DECFSZ CNT2,F ; 1 OR 2 GOTO T_LP2 ; 2 NOP ; 1 RETURN ; 2 TIME60mS ; 1+1+(1998+2)*60-1+2=120003 60mS=120000Cycle MOVLW D'60' ; 1 MOVWF CNT3 ; 1 T_LP3 CALL TIME1mS ; 1998 DECFSZ CNT3,F ; 1 OR 2 GOTO T_LP3 ; 2 RETURN ; 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;; 終了 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; END