;--------------------------------------------------------------------- ; 周波数カウンタプログラム ; 2010.11 naka ; ; ・電子工作の実験室(後閑氏)の下記ページのソースを流用 ; http://www.picfun.com/equipj45.html ; 汎用8桁周波数カウンタ ; ; 【変更点】 ; ・デバイス変更(PIC16F84→PIC16F648A) ; ・データ転送速度変更(100us/bit→20us/bit);表示部のちらつき防止の為 ; ・低周波/高周波、ゲートタイム1秒/0.1秒の設定を表示部に転送(2bit) ; ・ゲートタイム0.1秒の際、10倍した値を表示部に転送 ; ・ラジオの周波数直読機能として、中間周波数455KHz加算モード追加 ; ・電源オン時、テストデータ(12345678)を表示部に転送、1秒後測定開始 ; ・ゲートオープンと転送時のLED表示廃止 ; ・電源オン時の動作確認用ダイアグLED追加 ; ;--------------------------------------------------------------------- ;******************************************************************** ; 汎用8桁周波数カウンタ カウンタ部 ;  ・ゲートタイム:1秒/0.1秒切替可能 ;  ・低周波(2.3MHz)/高周波(18MHz)切替可能 ;  ・0.1/1 sec gate time ;  ・クロックは12.8MHzの高精度発振器 ;******************************************************************** LIST P=PIC16F648A INCLUDE "P16F648A.INC" __CONFIG _HS_OSC & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _BODEN_ON & _LVP_OFF ;**************************************************** ; 変数定義とレジスタ割付 ;**************************************************** BYTE0 EQU 20H ;周波数カウンタ0 BYTE1 EQU 21H ;周波数カウンタ1 BYTE2 EQU 22H ;周波数カウンタ2 MODE EQU 23H ;動作モード(上位2ビット) BAND EQU 24H ;Max周波数切替 CNT1 EQU 25H ;タイマ用カウンタ CNT2 EQU 26H CNT3 EQU 27H DAT_CNT EQU 28H TEMP EQU 29H LPCNT1 EQU 2AH ;Loop Counter LPCNT2 EQU 2BH ;Loop Counter SHIFT EQU 2CH ;Shift counter GATE EQU 2DH ;ゲートタイムフラグ OVRFLW EQU 2EH ;Over Flow Flag BYTE0_2 EQU 2FH BYTE1_2 EQU 30H BYTE2_2 EQU 31H RADIO EQU 32H ORG 0 ;******************************** ; メインプログラム ;******************************** ;**** 初期化 **** MAIN MOVLW H'07' MOVWF CMCON BSF STATUS,RP0 ;Page1へ CLRF TRISA ;PortA すべて出力 MOVLW B'00111000' MOVWF TRISB ;Port B 3-5入力 BCF STATUS,RP0 ;Page0に戻る MOVLW B'00000001' MOVWF PORTA ;ダイアグLEDオン ; CALL TIME10MS ;約10ミリ秒待ち(表示部の準備ができるまで) CALL TESTDT CALL TXDATA ;データを表示部へ転送 ; CALL TIME1S MOVLW B'00000101' MOVWF PORTA ;ダイアグLEDオフ ;**** メインループ ***** MAINLP CALL SENSE ;スイッチ読み込み CALL MESURE ;計測実行 CALL CONVRT ;計測値調整 CALL TXDATA ;データを表示部へ転送 GOTO MAINLP ; TESTDT ; 12,345,678 MOVLW H'4E' MOVWF BYTE0 MOVLW H'61' MOVWF BYTE1 MOVLW H'BC' MOVWF BYTE2 MOVLW H'00' MOVWF MODE RETURN ;*********** サブルーチン群 ****************************** ;***************************************** ; スイッチチェックとフラグセット ; 広帯域(1/8)モード:BAND=1 ; 狭大域(1/1)モード:BAND=0 ; 0.1秒ゲートタイム:GATE=1 ; 1秒ゲートタイム :GATE=0 ;***************************************** SENSE BTFSC PORTB,4 ;1/1,1/8モード切替 GOTO LOWBAND HIGHBAND BSF BAND,0 ;1/8モード(BAND=1) BSF MODE,7 BSF STATUS,RP0 ;バンク1に切替え MOVLW 062H ;プリスケーラ8倍にセット MOVWF OPTION_REG ; BCF STATUS,RP0 ;バンク0に戻る GOTO SKIP1 LOWBAND BCF BAND,0 ;1/1モード(BAND=0) BCF MODE,7 BSF STATUS,RP0 ;バンク1に切替え MOVLW 068H ;プリスケーラ無しにセット MOVWF OPTION_REG ; BCF STATUS,RP0 ;バンク0に戻る SKIP1 BCF GATE,0 ;set 1sec BCF MODE,6 ;set 1sec BTFSC PORTB,5 ;ゲートタイムチェック GOTO SKIP2 BSF GATE,0 ;set 0.1sec BSF MODE,6 SKIP2 BCF RADIO,0 ;ラジオの周波数直読用 BTFSC PORTB,3 ;中間周波数加算モード RETURN BSF RADIO,0 RETURN ;************************************ ; 計測実行サブルーチン ; ゲートタイムは0.1秒か1秒 ; PORTAのRA4がゲート制御用出力ピン ; クロックは12.8MHz ;************************************ MESURE BCF PORTA,4 ;ゲートを閉める CLRF BYTE0 ;ALL RESET CLRF BYTE1 CLRF BYTE2 CLRF TMR0 ;カウンタリセット BTFSC GATE,0 ;ゲートタイム確認 GOTO SHORT ;100msec GOTO LONG ;1sec ;**** ゲートタイム100msecの場合 ***** SHORT ;; BCF PORTA,2 ;Green on CLRF OVRFLW ;OverFlowフラグをクリア MOVLW 075H ;117 BSF PORTA,4 ;ゲートを開ける CALL MESLOOP ;319997+2cycle BCF PORTA,4 ;ゲートを閉める(320000CCycle) ;; BSF PORTA,2 ;Green off short1 RETURN ;**** ゲート1secの場合 ****** LONG ;; BCF PORTA,2 ;Green on BSF PORTA,4 ;ゲートを開ける CLRF OVRFLW ;overflowフラグをクリア MOVLW 05H ;計測ループ5回 MOVWF TEMP ; LONGLP MOVLW 0EAH ;ループ繰り返しカウンタ=234 NOP ;dumy NOP CALL MESLOOP ;LOOP 639992+2cycle DECFSZ TEMP,F ; GOTO LONGLP ;(639994+5)*5-1=3199994 NOP ;dumy NOP NOP BCF PORTA,4 ;close GATE(3199994+6=3200000) ;; BSF PORTA,2 ;Green off RETURN ;**** 計測実行ループ(319,997cycleまたは639,992cycle) **** MESLOOP MOVWF LPCNT1 ;++++++++++ MESLP1 MOVLW 0D2H ;第二カウンタ=210 MOVWF LPCNT2 ; ;*********** MESLP2 BTFSS INTCON,T0IF ;13 cycle loop GOTO DUMY1 BCF INTCON,T0IF ;T0IFフラグをリセット MOVLW 1 ;カウント更新用定数 GOTO NEXT DUMY1 NOP ;時間調整用NOP NOP MOVLW 0 ;カウンタ更新用定数 NEXT ADDWF BYTE1,F ;BYTE1+T0IF RLF BYTE1,W ;carry to d<0> ANDLW 1 ;キャリーだけ取り出し ADDWF BYTE2,F ;BYTE2+Carry DECFSZ LPCNT2,F ;ループ終了か? GOTO MESLP2 ; ;********** NOP MESLP3 DECFSZ LPCNT1,F ;(13*LPCNT2+5)*LPCNT1 GOTO MESLP1 ;(13*210+5)*117-1=319994 ;または(13*210+5)*234-1=639989 ;+++++++++++++++ RETURN ;最初の1命令分+1+2=319997 ;または639992 ;************************************ ; 計測値の桁補正 1/1 1/8 ;************************************ CONVRT ;**** 1/1,1/8モード確認 **** BTFSC BAND,0 ;HIGH/LOW BAND GOTO WIDE ;1/8モード処理へ ;**** 1/1モードの場合 **** LOW1 MOVF TMR0,W ;TMR0をBYTE0に取出し MOVWF BYTE0 GOTO CHKGATE ;**** 1/8の場合 **** WIDE MOVF TMR0,W ;get timer0 to BYTE0 MOVWF BYTE0 ;プリスケーラ8倍 BCF STATUS,C RLF BYTE0,F ;2倍を3回実行する RLF BYTE1,F RLF BYTE2,F BCF STATUS,C RLF BYTE0,F ;×2 RLF BYTE1,F RLF BYTE2,F BCF STATUS,C RLF BYTE0,F ;×2 RLF BYTE1,F RLF BYTE2,F BTFSC STATUS,C ;オーバーフローか? BSF OVRFLW,0 ;overflowフラグをON ; CHKGATE BTFSS GATE,0 ;ゲートタイム0.1秒のとき、10倍する GOTO ADDIF MUL10 BCF STATUS,C RLF BYTE0,F ;×2 RLF BYTE1,F RLF BYTE2,F ; MOVF BYTE0,W ;2倍した値を記憶 MOVWF BYTE0_2 MOVF BYTE1,W MOVWF BYTE1_2 MOVF BYTE2,W MOVWF BYTE2_2 ; BCF STATUS,C RLF BYTE0,F ;×2=4倍 RLF BYTE1,F RLF BYTE2,F BCF STATUS,C RLF BYTE0,F ;×2=8倍 RLF BYTE1,F RLF BYTE2,F CALL ADD24 ; 2倍した値+8倍した値=10倍 ; ADDIF BTFSS RADIO,0 ; ラジオ周波数表示モード RETURN ; MOVLW H'58' ; 中間周波数455KHz MOVWF BYTE0_2 MOVLW H'F1' MOVWF BYTE1_2 MOVLW H'06' MOVWF BYTE2_2 CALL ADD24 ; 局発周波数+中間周波数 -> 受信周波数 RETURN ;--------------------------------------------------------------------- ADD24 ; 24ビット加算(BYTEn = BYTEn + BYTEn_2) MOVF BYTE0_2,W ADDWF BYTE0,F MOVLW D'1' BTFSC STATUS,C ADDWF BYTE1,F BTFSC STATUS,C ADDWF BYTE2,F ; MOVF BYTE1_2,W ADDWF BYTE1,F BTFSC STATUS,C INCF BYTE2,F ; MOVF BYTE2_2,W ADDWF BYTE2,F RETURN ;*************************************** ;* Subroutine for Send to LED controler ;* 20us/bit ;*************************************** TXDATA ;**** START BIT BCF PORTA,0 ;Start Bit Send CALL TM16 ;16.25usec ;***** DATA 2 + 8*3 BIT MOVF MODE,W CALL TX_2BIT MOVF BYTE2,W CALL TX_BYTE MOVF BYTE1,W CALL TX_BYTE MOVF BYTE0,W CALL TX_BYTE ;***** STOP BIT BSF PORTA,0 CALL TM16 RETURN ;******* 1バイト転送サブルーチン ****** TX_BYTE MOVWF TEMP ;save temporaly MOVLW 8H ;8bit counter GOTO TX_S TX_2BIT MOVWF TEMP ;save temporaly MOVLW 2H ;2bit counter TX_S MOVWF DAT_CNT TX_LP RLF TEMP,F ;Bit shift BTFSS STATUS,C ;0,1 check GOTO TX_0 GOTO TX_1 TX_0 NOP BCF PORTA,0 ;0 send GOTO TX_NEXT TX_1 BSF PORTA,0 ;1 send GOTO TX_NEXT ;dummy TX_NEXT CALL TM13 ; 13.75us DECFSZ DAT_CNT,F ;8bits end test GOTO TX_WAIT RETURN ; TX_WAIT NOP NOP NOP NOP NOP NOP NOP GOTO TX_LP ; ;********************************* ; Timer Routine ;********************************* TM16 ; 16.25us MOVLW D'15' MOVWF CNT1 TM16_LP DECFSZ CNT1,F GOTO TM16_LP NOP NOP RETURN ; TM13 ; 13.75us MOVLW D'13' MOVWF CNT1 TM13_LP2 DECFSZ CNT1,F GOTO TM13_LP2 RETURN TIME10MS ;約10ミリ秒 MOVLW D'50' MOVWF CNT2 TIME10ML1 MOVLW D'212' MOVWF CNT3 TIME10ML2 DECFSZ CNT3,F GOTO TIME10ML2 DECFSZ CNT2,F GOTO TIME10ML1 RETURN TIME1S ;約1秒 MOVLW D'17' MOVWF CNT1 TIME1SL1 MOVLW D'245' MOVWF CNT2 TIME1SL2 MOVLW D'255' MOVWF CNT3 TIME1SL3 DECFSZ CNT3,F GOTO TIME1SL3 DECFSZ CNT2,F GOTO TIME1SL2 DECFSZ CNT1,F GOTO TIME1SL1 RETURN ;--------------------------------------------------------------------- END