;********************************************************************** ; インテリジェント空線信号キャンセラー by. 気の迷い 2008/4 Ver1.01 ;********************************************************************** ; Editor TAB = 4 list p=12f629 ; list directive to define processor #include ; processor specific variable definitions errorlevel -302 ; suppress message 302 from list file __CONFIG _INTRC_OSC_NOCLKOUT & _CP_OFF & _PWRTE_ON & _WDT_OFF & _MCLRE_OFF & _CPD_OFF & _BODEN_ON ; ■今回の使用ポート ; PIC12F629 ; ┏━━━━┓ ; + ┃Vdd Vss┃− ; VOICE ON ┃GP5 GP0┃LED NEC MSK ; SELECT SW ┃GP4 GP1┃LED JR-AKI ; AUDIO IN ┃GP3 GP2┃LED JR-TEST ; ┗━━━━┛ ;********************************************************************** ; 各種設定 (設定変更時はここの数値を変えるだけでOK) ;********************************************************************** VOICE_SENSE EQU 3 ; 音声入力ビット DANZOKU_SW EQU 4 ; NEC MSK 連続/断続の切替スイッチ接続ビット LED_NEC EQU B'000001' ; LED を点灯させるビット指定 LED_JR_B EQU B'000010' LED_JR_T EQU B'000010' LED_OTHER EQU B'000100' VOICE_ON EQU B'100000' ; VOICE ON 制御ビット指定 ; ★★ 今回の最も重要な判定ルーチン用パラメータ ★★ ; 一定期間(約100msec)連続したと判定するカウント数と ; その期間が何回続くと「確定」とさせるかのスパン ; **** 禁止動作等の設定 INH_SET_data EQU B'00000000' ; 禁止動作設定 bit 0:NEC判定禁止, 1:JR判定禁止 7:ロジック判定禁止 ; **** NEC NSK 判定部のパラメータ NEC_hold EQU D'80' ; NEC MSK(連続) は80回 NEC_hold2 EQU D'50' ;  断続型は50回カウントで NEC_span EQU D'25' ; NEC MSK(連続)の判定 NEC_span2 EQU D'3' ;  断続型の判定 NEC_JR_span EQU D'70' ; JR空線時のNEC MSK(連続)の判定(すごく遅くする) ; **** JR空線 判定部のパラメータ JR_B_hold EQU D'114' ; JR空線 は114回 JR_B_span EQU D'15' ; 判定 JR_B_NEC_span EQU D'70' ; NEC時の判定(すごく遅くする) JR_B_TEST_span EQU D'5' ; 試験信号中はすぐ戻るように早くする ; **** JR呼出 判定部のパラメータ JR_Y_hold EQU D'98' ; JR呼出 は98回 JR_Y_span EQU D'5' ; 判定 ; **** JR試験良好 判定部のパラメータ JR_T_hold EQU D'40' ; JR試験良好 は40回 JR_T_span EQU D'5' ; 判定 ; **** その他(VOICE) 判定部のパラメータ OTHER_hold EQU D'100' ; その他 は100回(様々な周波数のデータが来るので…だいたい平均) OTHER_span EQU D'6' ; その他の 基本 判定(一度判定したらこれにリセットされる) OTHER_NEC_span EQU D'6' ;  NEC連続時の 判定 (短い目) OTHER_NEC_span2 EQU D'12' ;  NEC断続時の 判定 (断続するので長い目) OTHER_JR_span EQU D'20' ;  JR空線時の 判定 (試験信号に切り替わる際の空白を消す為長い) ;********************************************************************** ; RAMファイル(内蔵メモリー)の割り当てなど ; PIC12F29 RAM 0x20〜0x5F の64バイト (バンク 0,1 で共通アクセス) ;********************************************************************** PULSE_COUNT EQU 0x20 ; パルス幅の計測用 ; ◆ パルスカウント(100msec間継続したかのチェック用) PC_NEC_MSK EQU 0x21 ; NEC MSK 1200Hz/1800Hz/切替 共通カウント PC_JR_AKI EQU 0x22 ; JR 空線信号 2280Hz PC_JR_YOBI EQU 0x23 ; JR 呼出信号 1960Hz PC_JR_TEST EQU 0x24 ; JR 試験良好 800Hz PC_OTHER EQU 0x25 ; その他検知 ; ◆ 承認カウント(n回間継続したかのチェック用) CT_NEC_MSK EQU 0x26 ; NEC MSK 1200Hz/1800Hz/切替 共通カウント CT_JR_AKI EQU 0x27 ; JR 空線信号 2280Hz CT_JR_YOBI EQU 0x28 ; JR 呼出信号 1960Hz CT_JR_TEST EQU 0x29 ; JR 試験良好 800Hz CT_OTHER EQU 0x2A ; その他検知 JR_B_NINTEI EQU 0x2B ; JR-B の認定判定回数を可変にする為 NEC_NINTEI EQU 0x2C ; NEC MSK の認定判定回数を可変にする為 OTHER_NINTEI EQU 0x2D ; その他 の認定判定回数を可変にする為 DANZOKU EQU 0x2E ; NEC MSK の断続型に対応するスイッチ DETECT_MODE EQU 0x2F ; 判定したモード bit 0:NEC, 1:JR-B, 2:JR-TEST INH_FLAG EQU 0x30 ; 禁止動作設定 bit 0:NEC判定禁止, 1:JR判定禁止 7:ロジック判定禁止 WAIT_COUNT EQU 0x50 ; 汎用1msecタイマー用 WAIT_COUNT2 EQU 0x51 ; WK EQU 0x52 ; 汎用ワーク ;********************************************************************** ; START point 0x000 ;********************************************************************** ORG 0x000 ; goto MAIN_INIT ; ; ※ 今回は割り込み処理を行わないので、0x004からの割り込み処理部は無し ;********************************************************************** ; PIC ハードウェアの初期化 ;********************************************************************** MAIN_INIT BANKSEL OSCCAL ; OSC補正値の設定 call 0x3FF movwf OSCCAL ; /////////////////////////////////////// ; ポート・A/D・コンパレータの初期化 ; /////////////////////////////////////// BANKSEL GPIO clrf GPIO ; 先にGPIO出力設定 (all = 0) ; **** コンパレータ、A/Dコンバータとの割り振り **** movlw 0x07 ; コンパレータは使用しない movwf CMCON ; GP0,1,2 A/D or Digital ; アナログ/デジタルポートとの使用区分を決める ; ※ 12F629はA/Dコンバータは無いのでA/D初期化ルーチンは無し ; **** GPIOのポート使用設定 **** BANKSEL TRISIO movlw B'011000' ; GPIO 入出力設定 (0=OUTPUT/1=INPUT) movwf TRISIO movlw B'010000' ; GPIO プルアップ (0=OFF / 1=ON) movwf WPU bcf OPTION_REG,NOT_GPPU ; GPIO ウィークアップ機能 ON ; ※ 今回はタイマーは使用しないのでタイマー初期化は無し ; ※ 今回は割り込みは使用しないので割り込み初期化は無し ;********************************************************************** ; ******** 電源ON時のLEDのテスト点灯 LED_TEST BANKSEL GPIO movlw D'3' ; 繰り返し回数 = 3 movwf WK LED_W_TIME EQU D'200' ; 1個のLED点灯時間 = 200msec LED_TEST_LOOP movlw LED_NEC | VOICE_ON ; LED 「私鉄」点灯 / 音声出力 = ON movwf GPIO movlw LED_W_TIME ; 一個ぶん時間待つ call WAIT_1msec_w movlw LED_JR_B | VOICE_ON ; LED 「JR」点灯 / 音声出力 = ON movwf GPIO movlw LED_W_TIME ; 一個ぶん時間待つ call WAIT_1msec_w movlw LED_OTHER | VOICE_ON ; LED 「通話」点灯 / 音声出力 = ON movwf GPIO movlw LED_W_TIME ; 一個ぶん時間待つ call WAIT_1msec_w decfsz WK,f goto LED_TEST_LOOP ;********************************************************************** ; MAIN ユーザープログラム本体 ;********************************************************************** MAIN movlw INH_SET_data ; 禁止動作設定 bit 0:NEC判定禁止, 1:JR判定禁止 7:ロジック判定禁止 movwf INH_FLAG clrf PC_NEC_MSK ; 全計測カウンタをリセットする clrf PC_JR_AKI clrf PC_JR_YOBI clrf PC_JR_TEST clrf PC_OTHER clrf CT_NEC_MSK ; 全認定カウンタをリセットする clrf CT_JR_AKI clrf CT_JR_YOBI clrf CT_JR_TEST clrf CT_OTHER movlw JR_B_span ; JRの認定判定回数を標準に movwf JR_B_NINTEI movlw NEC_span ; NEC通常の認定判定回数を標準に movwf NEC_NINTEI movlw OTHER_span ; その他の認定判定回数を標準に movwf OTHER_NINTEI ; 通常は 6 (NEC MSK 用) clrf DETECT_MODE ; 判定したモード = 0 に ; **** 音声通す **** movlw LED_OTHER | VOICE_ON ; LED 「通話」(その他) / 音声出力 = ON movwf GPIO ; ///////////////////////////////////////////////////////////////// ; パルス幅のチェック一回 ; ///////////////////////////////////////////////////////////////// CHECK_PULSE clrf PULSE_COUNT ; パルスカウンタをリセット ; **** NEC MSKの「断続型」への対応スイッチ btfsc GPIO,DANZOKU_SW ; スイッチ状態の読み込み goto SW_H ; SW = L (ON) bsf DANZOKU,0 ; 1:南北線(断続型) goto CHECK_PULSE_BEGIN SW_H ; SW = H (OFF) bcf DANZOKU,0 ; 0:通常 ; //// 立ち上がりを待つ //// CHECK_PULSE_BEGIN btfsc GPIO,VOICE_SENSE ; 音声センス goto CHECK_PULSE_ONE ; 立ち上がったのでカウントを開始する ; 下がったままなのでエラーカウント++ incf PULSE_COUNT,f movf PULSE_COUNT,w andlw B'01111111' ; ここは7FH 128でエラー btfss STATUS,Z goto CHECK_PULSE_BEGIN ;NZ = LOOP ; Zero = オーバーフロー = 「無音」 goto PC_UP_OTHER ; **** 「その他」を検出した ; //// 立ち上がったのでカウント開始 //// CHECK_PULSE_ONE clrf PULSE_COUNT ; //// 立ち下がりを待つ //// CHECK_PULSE_L btfss GPIO,VOICE_SENSE ; +1 / skip = +2 goto CHECK_PULSE_H ; +1 ; まだ上がったままなのでカウント++ incf PULSE_COUNT,f ; +1 movf PULSE_COUNT,w ; +1 andlw B'11111111' ; +1 btfss STATUS,Z ; +1 goto CHECK_PULSE_L ;NZ = LOOP ; +2 1loop = 8step ; Zero = オーバーフロー = 「周波数が低すぎ」または「レベルオーバー」 goto PC_UP_OTHER ; **** 「その他」を検出した ; //// 立ち上がりを待つ //// CHECK_PULSE_H btfsc GPIO,VOICE_SENSE goto CHECK_PULSE_OK ; **** 立ち上がったのでこの回の測定終了、判定へ **** ; まだ下がったままなのでカウント++ incf PULSE_COUNT,f ; +1 movf PULSE_COUNT,w ; +1 andlw B'11111111' ; +1 btfss STATUS,Z ; +1 goto CHECK_PULSE_H ;NZ = LOOP ; +2 1loop = 8step ; Zero = オーバーフロー = 「無音」または「周波数が低すぎ」 goto PC_UP_OTHER ; **** 「その他」を検出した ; ///////////////////////////////////////////////////////////////// ; 立ち上がったので時間による判定計算 ; ///////////////////////////////////////////////////////////////// CHECK_PULSE_OK ; **** 高すぎる周波数の信号はノイズとして除去 **** movlw D'21' ; 約 6KHz以上 ([21] より少し下) ;; movlw D'42' ; 約 3KHz以上 ([42] より少し下) subwf PULSE_COUNT,w ; PULSE_COUNT - w btfss STATUS,C ; IF B goto **** goto CHECK_PULSE ; **** ノイズを検出したので再スタート ; **** JR 空線 のチェック 2280Hz **** movlw D'48' ; JR 空線 [55] より少し下 subwf PULSE_COUNT,w ; PULSE_COUNT - w btfss STATUS,C ; IF B goto **** goto PC_UP_OTHER ; **** 「その他」を検出した movlw D'57' ; JR 空線 [55] より少し上 subwf PULSE_COUNT,w ; PULSE_COUNT - w btfss STATUS,C ; IF B goto **** goto PC_UP_JR_AKI ; **** 「JR 空線」を検出した ; **** JR-B判定=ONの場合のみ「一斉呼」信号を検出させる ; 「一斉呼」1960HzはNEC MSK 1800Hzとあまりに近いので ; JR空線中に呼出信号が来る時のみ検出させる為 btfss DETECT_MODE,1 ; 判定したモード bit 0:NEC, 1:JR-B, 2:JR-TEST goto CHECK_NEC_MSK ; 違うので NEC チェックへ ; **** JR 一斉呼 のチェック 1960Hz **** ; JR空線より上側-呼出間で「その他」判定はできないので無し movlw D'69' ; JR 一斉呼 [64] より少し上 subwf PULSE_COUNT,w ; PULSE_COUNT - w btfss STATUS,C ; IF B goto **** goto PC_UP_JR_YOBI ; **** 「JR 呼び出し」を検出した ; 個別呼 2400Hz [52]は空線 2280Hz [55]と近すぎる為判定しない CHECK_NEC_MSK ; **** NEC MSK のチェック1 1800Hz(スペース) **** movlw D'60' ; NEC MSK 1800Hz [69] より少し下 subwf PULSE_COUNT,w ; PULSE_COUNT - w btfss STATUS,C ; IF B goto **** goto PC_UP_OTHER ; **** 「その他」を検出した movlw D'74' ; NEC MSK 1800Hz [69] より少し上 subwf PULSE_COUNT,w ; PULSE_COUNT - w btfss STATUS,C ; IF B goto **** goto PC_UP_NEC_MSK ; **** 「NEC MSK」を検出した ; **** NEC MSK のチェック2 1440Hz(マークとスペースの切替点) **** ;; movlw D'78' ; NEC MSK 切替 [87] より少し下 ;; subwf PULSE_COUNT,w ; PULSE_COUNT - w ;; btfss STATUS,C ; IF B goto **** ;; goto PC_UP_OTHER ; **** 「その他」を検出した ;;ここの「その他」判定は無くして1440Hz判定の幅を広く持たせるほうが安定する movlw D'88' ; NEC MSK 切替 [87] より少し上 subwf PULSE_COUNT,w ; PULSE_COUNT - w btfss STATUS,C ; IF B goto **** goto PC_UP_NEC_MSK ; **** 「NEC MSK」を検出した ; **** NEC MSK のチェック3 1200Hz(マーク) **** movlw D'90' ; NEC MSK 1200Hz [104] より少し下 subwf PULSE_COUNT,w ; PULSE_COUNT - w btfss STATUS,C ; IF B goto **** goto PC_UP_OTHER ; **** 「その他」を検出した movlw D'115' ; NEC MSK 1200Hz [104] より少し上 subwf PULSE_COUNT,w ; PULSE_COUNT - w btfss STATUS,C ; IF B goto **** goto PC_UP_NEC_MSK ; **** 「NEC MSK」を検出した ; **** 「JR 試験良好」はJR空線中とJR試験中のみ判定する btfsc DETECT_MODE,1 ; JR判定中か? goto CHECK_JR_TEST ; 中なのでOK、判定する btfss DETECT_MODE,2 ; JR判定中か? goto CHECK_JR_TEST_OVER ; 違うので次へ ; **** JR 試験良好 のチェック 800Hz **** CHECK_JR_TEST movlw D'140' ; JR 空線 [156] より少し下 subwf PULSE_COUNT,w ; PULSE_COUNT - w btfss STATUS,C ; IF B goto **** goto PC_UP_OTHER ; **** 「その他」を検出した movlw D'162' ; JR 空線 [156] より少し上 subwf PULSE_COUNT,w ; PULSE_COUNT - w btfss STATUS,C ; IF B goto **** goto PC_UP_JR_TEST ; **** 「JR 試験良好」を検出した CHECK_JR_TEST_OVER ; **** それ以上、どれにも当てはまらなかった **** goto PC_UP_OTHER ; **** 「その他」を検出した ; ///////////////////////////////////////////////////////////////// ; 検出結果のカウントアップ ; ///////////////////////////////////////////////////////////////// ; ----------------------------------------------------------------- ; **** 「NEC MSK」を検出した **** PC_UP_NEC_MSK btfsc INH_FLAG,0 ; 動作禁止設定 bit 0:NEC判定禁止 goto PC_UP_OTHER ; **** 禁止なので「その他」を検出した処理へ ; パルス幅を検出したカウントアップ incf PC_NEC_MSK,f ; 計測カウンタ++ btfsc DANZOKU,0 ; 通常/南北線(断続型)? goto NEC_PC_DANZOKU ; 通常処理 movf PC_NEC_MSK,w sublw NEC_hold ; NEC MSK は(80回)カウントで約100msecぶん連続したとみなす btfss STATUS,Z ; IF NZ goto **** goto PC_UP_END ; まだなのでカウントアップ処理を抜ける goto NEC_PC_FULL ; フルカウント ; 南北線(断続型)処理 NEC_PC_DANZOKU movf PC_NEC_MSK,w sublw NEC_hold2 ; 断続型は(50回)カウントで btfss STATUS,Z ; IF NZ goto **** goto PC_UP_END ; まだなのでカウントアップ処理を抜ける NEC_PC_FULL ; 100msec連続したので今はこの状態と判定 clrf PC_NEC_MSK ; 全計測カウンタをリセットする clrf PC_JR_AKI clrf PC_JR_TEST clrf PC_OTHER btfsc INH_FLAG,7 ; 動作禁止設定 bit 7:ロジック判定禁止 goto NEC_KAKUTEI ; ロジック判定は禁止なので即座にモード確定へ ; 認定カウンタ、カウントアップ incf CT_NEC_MSK,f ; 認定カウンタ++ btfsc DANZOKU,0 ; 通常/南北線(断続型)? goto NEC_CT_DANZOKU ; //// 通常処理 movf CT_NEC_MSK,w subwf NEC_NINTEI,w ; 通常処理のみ認定カウントは可変(JR時延ばす為) btfsc STATUS,C ; IF NB goto **** goto PC_UP_END ; まだなのでカウントアップ処理を抜ける goto NEC_KAKUTEI ; 確定! ; //// 断続対応処理 NEC_CT_DANZOKU movf CT_NEC_MSK,w sublw NEC_span2 ; 断続型はは(3回)カウントで認定 btfss STATUS,Z ; IF NZ goto **** goto PC_UP_END ; まだなのでカウントアップ処理を抜ける NEC_KAKUTEI ; 「NEC MSK」と確定 clrf CT_NEC_MSK ; 全認定カウンタをリセットする clrf CT_JR_AKI clrf CT_JR_TEST clrf CT_OTHER movlw B'00000001' ; 判定したモード bit 0:NEC, 1:JR-B, 2:JR-TEST movwf DETECT_MODE btfsc DANZOKU,0 ; 通常/南北線(断続型)? goto NEC_KAKUTEI_DANZOKU ; //// 通常処理 ; **** NECシフトの各種認定回数の変更 **** movlw JR_B_NEC_span ; JR_Bの認定判定回数をNEC用に長くする movwf JR_B_NINTEI movlw OTHER_NEC_span ; その他の認定判定回数を可変にする為 (6回) movwf OTHER_NINTEI ; 通常は 6 (NEC MSK 用) movlw NEC_span ; NEC自身の認定判定回数を正常値にする (JR判定時に書き換えられている) movwf NEC_NINTEI goto NEC_KAKUTEI_1 ; //// 断続対応処理 NEC_KAKUTEI_DANZOKU ; **** NECシフトの各種認定回数の変更 **** movlw JR_B_NEC_span ; JR_Bの認定判定回数をNEC用に長くする movwf JR_B_NINTEI movlw OTHER_NEC_span2 ; その他の認定判定回数を可変にする為 movwf OTHER_NINTEI ; 通常は 6 / NEC断続 は 12 (NEC断続は判定を緩くする) movlw NEC_span2 ; NEC自身の認定判定回数を正常値に戻す (JR判定時に書き換えられている) movwf NEC_NINTEI NEC_KAKUTEI_1 ; **** 音声カット **** movlw LED_NEC ; NEC MSK 点灯 / 音声出力 = OFF movwf GPIO goto PC_UP_END ; カウントアップ処理を抜ける ; ----------------------------------------------------------------- ; **** 「JR 空線」を検出した **** PC_UP_JR_AKI btfsc INH_FLAG,1 ; 動作禁止設定 bit 1:JR判定禁止 goto PC_UP_OTHER ; **** 禁止なので「その他」を検出した処理へ ; パルス幅を検出したカウントアップ incf PC_JR_AKI,f ; 計測カウンタ++ movf PC_JR_AKI,w sublw JR_B_hold ; JR 空線 は(114回)カウントで約100msecぶん連続したとみなす btfss STATUS,Z ; IF NZ goto **** goto PC_UP_END ; まだなのでカウントアップ処理を抜ける ; 100msec連続したので今はこの状態と判定 clrf PC_NEC_MSK ; 全計測カウンタをリセットする clrf PC_JR_AKI clrf PC_JR_YOBI clrf PC_JR_TEST clrf PC_OTHER btfsc INH_FLAG,7 ; 動作禁止設定 bit 7:ロジック判定禁止 goto JR_AKI_KAKUTEI ; ロジック判定は禁止なので即座にモード確定へ ; 認定カウンタ、カウントアップ incf CT_JR_AKI,f ; 認定カウンタ++ movf CT_JR_AKI,w subwf JR_B_NINTEI,w ; 認定カウントは可変 btfsc STATUS,C ; IF NB goto **** goto PC_UP_END ; まだなのでカウントアップ処理を抜ける JR_AKI_KAKUTEI ; 「JR 空線」と確定 clrf CT_NEC_MSK ; 全認定カウンタをリセットする clrf CT_JR_AKI clrf CT_JR_YOBI clrf CT_JR_TEST clrf CT_OTHER movlw B'00000010' ; 判定したモード bit 0:NEC, 1:JR-B, 2:JR-TEST movwf DETECT_MODE ; **** JRシフトの各種認定回数の変更 **** movlw JR_B_span ; JRの認定判定回数を標準に戻す movwf JR_B_NINTEI movlw NEC_JR_span ; NECの認定判定回数を長くするする movwf NEC_NINTEI ; 通話中の類似音声で間違ってカットされるのを防ぐ movlw OTHER_JR_span ; その他の認定判定回数を長くする movwf OTHER_NINTEI ; 空線信号から試験良好に切り替わる時の空白で音を出さない為 ; **** 音声カット **** movlw LED_JR_B ; JR-AKI 点灯 / 音声出力 = OFF movwf GPIO goto PC_UP_END ; カウントアップ処理を抜ける ; ----------------------------------------------------------------- ; **** 「JR 試験良好」を検出した **** PC_UP_JR_TEST btfsc INH_FLAG,1 ; 動作禁止設定 bit 1:JR判定禁止 goto PC_UP_OTHER ; **** 禁止なので「その他」を検出した処理へ ; パルス幅を検出したカウントアップ incf PC_JR_TEST,f ; 計測カウンタ++ movf PC_JR_TEST,w sublw JR_T_hold ; JR 試験良好 は(40回)カウントで約100msecぶん連続したとみなす btfss STATUS,Z ; IF NZ goto **** goto PC_UP_END ; まだなのでカウントアップ処理を抜ける ; 100msec連続したので今はこの状態と判定 clrf PC_NEC_MSK ; 全計測カウンタをリセットする clrf PC_JR_AKI clrf PC_JR_YOBI clrf PC_JR_TEST clrf PC_OTHER btfsc INH_FLAG,7 ; 動作禁止設定 bit 7:ロジック判定禁止 goto JR_TEST_KAKUTEI ; ロジック判定は禁止なので即座にモード確定へ ; 認定カウンタ、カウントアップ incf CT_JR_TEST,f ; 認定カウンタ++ movf CT_JR_TEST,w sublw JR_T_span ; JR 試験良好 は(5回)カウントで認定できるとみなす btfss STATUS,Z ; IF NZ goto **** goto PC_UP_END ; まだなのでカウントアップ処理を抜ける JR_TEST_KAKUTEI ; 「JR 試験良好」と確定 clrf CT_NEC_MSK ; 全認定カウンタをリセットする clrf CT_JR_AKI clrf CT_JR_YOBI clrf CT_JR_TEST clrf CT_OTHER movlw B'00000100' ; 判定したモード bit 0:NEC, 1:JR-B, 2:JR-TEST movwf DETECT_MODE ; **** JRシフト(但しテスト良)の各種認定回数の変更 **** movlw JR_B_TEST_span ; JR_Bの認定判定回数を試験からの復帰用に短くする movwf JR_B_NINTEI ; **** 音声カット **** movlw LED_JR_T ; JR-TEST 点灯 / 音声出力 = OFF movwf GPIO goto PC_UP_END ; カウントアップ処理を抜ける ; ----------------------------------------------------------------- ; **** 「JR 呼出」を検出した **** PC_UP_JR_YOBI btfsc INH_FLAG,1 ; 動作禁止設定 bit 1:JR判定禁止 goto PC_UP_OTHER ; **** 禁止なので「その他」を検出した処理へ ; パルス幅を検出したカウントアップ incf PC_JR_YOBI,f ; 計測カウンタ++ movf PC_JR_YOBI,w sublw JR_Y_hold ; JR 呼出 は(114回)カウントで約100msecぶん連続したとみなす btfss STATUS,Z ; IF NZ goto **** goto PC_UP_END ; まだなのでカウントアップ処理を抜ける ; 100msec連続したので今はこの状態と判定 clrf PC_NEC_MSK ; 全計測カウンタをリセットする clrf PC_JR_AKI clrf PC_JR_YOBI clrf PC_JR_TEST clrf PC_OTHER btfsc INH_FLAG,7 ; 動作禁止設定 bit 7:ロジック判定禁止 goto JR_YOBI_KAKUTEI ; ロジック判定は禁止なので即座にモード確定へ ; 認定カウンタ、カウントアップ incf CT_JR_YOBI,f ; 認定カウンタ++ movf CT_JR_YOBI,w sublw JR_Y_span ; JR 空線 は(5回)カウントで認定できるとみなす btfss STATUS,Z ; IF NZ goto **** goto PC_UP_END ; まだなのでカウントアップ処理を抜ける JR_YOBI_KAKUTEI ; 「JR 個別呼」と確定 clrf CT_NEC_MSK ; 全認定カウンタをリセットする clrf CT_JR_AKI clrf CT_JR_YOBI clrf CT_JR_TEST clrf CT_OTHER movlw B'00000000' ; 判定したモード bit 0:NEC, 1:JR-B, 2:JR-TEST movwf DETECT_MODE ; **** 音声通す **** movlw LED_OTHER | VOICE_ON ; LED その他 / 音声出力 = ON movwf GPIO goto PC_UP_END ; カウントアップ処理を抜ける ; ----------------------------------------------------------------- ; **** 「その他」を検出した **** PC_UP_OTHER incf PC_OTHER,f ; 計測カウンタ++ movf PC_OTHER,w sublw OTHER_hold ; 「その他」 は(100回)カウントで約100msecぶん連続したとみなす btfss STATUS,Z ; IF NZ goto **** goto PC_UP_END ; まだなのでカウントアップ処理を抜ける ; 100msec連続したので今はこの状態と判定 clrf PC_NEC_MSK ; 全計測カウンタをリセットする clrf PC_JR_AKI clrf PC_JR_YOBI clrf PC_JR_TEST clrf PC_OTHER btfsc INH_FLAG,7 ; 動作禁止設定 bit 7:ロジック判定禁止 goto OTHER_KAKUTEI ; ロジック判定は禁止なので即座にモード確定へ ; 認定カウンタ、カウントアップ incf CT_OTHER,f ; 認定カウンタ++ movf CT_OTHER,w subwf OTHER_NINTEI,w ; 認定カウントは可変 btfsc STATUS,C ; IF NB goto **** goto PC_UP_END ; まだなのでカウントアップ処理を抜ける OTHER_KAKUTEI ; 「その他」と確定 clrf CT_NEC_MSK ; 全認定カウンタをリセットする clrf CT_JR_AKI clrf CT_JR_YOBI clrf CT_JR_TEST clrf CT_OTHER movlw OTHER_span ; その他の認定判定回数を可変にする為 movwf OTHER_NINTEI ; 通常は 6 movlw B'00000000' ; 判定したモード bit 0:NEC, 1:JR-B, 2:JR-TEST movwf DETECT_MODE ; **** 音声通す **** movlw LED_OTHER | VOICE_ON ; LED その他 / 音声出力 = ON movwf GPIO ;; goto PC_UP_END ; カウントアップ処理を抜ける ; ----------------------------------------------------------------- ; **** カウントアップ処理終了 PC_UP_END ; **** JR-TEST判定中の「LED点滅」処理 btfss DETECT_MODE,2 ; bit-2:JR-TEST はON? goto CHECK_PULSE ; 次のパルス幅のチェックへ! incf WK,f ; 汎用ワークを点滅カウンタとして使用 btfss WK,7 ; bit-3を判定 goto BLINK_1 movlw B'000000' ; 点滅の為LED消灯 / 音声出力 = OFF movwf GPIO goto CHECK_PULSE ; 次のパルス幅のチェックへ! BLINK_1 movlw LED_JR_T ; JR-TEST 点灯 / 音声出力 = OFF movwf GPIO goto CHECK_PULSE ; 次のパルス幅のチェックへ! ; ------------------------------------------------------- ; 1m秒 × w 待つ (だいたいタイマー) WAIT_1msec_w movwf WAIT_COUNT2 ; カウント数セット 1msex × n 回 WAIT_1msec_LOOP ; PICのクロック周波数によってカウント数を変える ; CLK = 2MHz … 1cycle = 2μsec , COUNT = 25 ; CLK = 4MHz … 1cycle = 1μsec , COUNT = 50 ; CLK = 8MHz … 1cycle = 0.5μsec , COUNT =100 ; CLK = 16MHz … 1cycle = 0.5μsec , COUNT =200 ; CLK = 20MHz … 1cycle = 0.5μsec , COUNT =250 ; 但しカウント数セットとreturnは除く(ので微妙) ; 1m秒待ち部分 movlw D'50' ; カウント数セット movwf WAIT_COUNT nop ; 1cycle nop ; 1cycle nop ; 1cycle nop ; 1cycle nop ; 1cycle nop ; 1cycle nop ; 1cycle nop ; 1cycle decfsz WAIT_COUNT,f ; スルー時 1cycle / Skip時 2cycle goto $-9 ; 1cycle LOOP時には1回で10サイクル decfsz WAIT_COUNT2,f goto WAIT_1msec_LOOP return ; 2cycle ;********************************************************************** ; OSC 補正値設定 ;********************************************************************** ORG 0x3FF ; 秋月PICライターでは自動的に retlw 0x00 ; 固体別のOSC補正値を保存してくれるので ; ここはダミー ;********************************************************************** ; EEPROM 初期焼き込みデータ ;********************************************************************** ; ※ 今回はEEPROMは使用しない ;********************************************************************** END