;******************************************************************** ; 汎用8桁周波数カウンタ カウンタ部 ;  ・ゲートタイム:1秒/0.1秒切替可能 ;  ・低周波(2.3MHz)/高周波(18MHz)切替可能 ;  ・0.1/1 sec gate time ;  ・クロックは12.8MHzの高精度発振器 ;******************************************************************** LIST P=PIC16F84A INCLUDE "P16F84A.INC" ;**************************************************** ; 変数定義とレジスタ割付 ;**************************************************** BYTE0 EQU 0CH ;周波数カウンタ0 BYTE1 EQU 0DH ;周波数カウンタ1 BYTE2 EQU 0EH ;周波数カウンタ2 BAND EQU 0FH ;Max周波数切替 CNT1 EQU 10H ;タイマ用カウンタ CNT2 EQU 11H DAT_CNT EQU 12H TEMP EQU 13H LPCNT1 EQU 14H ;Loop Counter LPCNT2 EQU 15H ;Loop Counter SHIFT EQU 16H ;Shift counter GATE EQU 17H ;ゲートタイムフラグ OVRFLW EQU 18H ;Over Flow Flag ORG 0 ;******************************** ; メインプログラム ;******************************** ;**** 初期化 **** MAIN BSF STATUS,RP0 ;Page1へ CLRF TRISA ;PortA すべて出力 MOVLW 0FFH MOVWF TRISB ;Port B すべて入力 BCF OPTION_REG,NOT_RBPU ;PORTB Pull up ON BCF STATUS,RP0 ;Page0に戻る BSF PORTA,0 ;RESET ;**** メインループ ***** MAINLP CALL SENSE ;スイッチ読み込み CALL MESURE ;計測実行 CALL CONVRT ;計測値調整  CALL TM100 ;DELAY CALL TXDATA ;データを表示部へ転送 CALL TM100 ;DELAY CALL TM100 ;DELAY GOTO MAINLP ;*********** サブルーチン群 ****************************** ;***************************************** ; スイッチチェックとフラグセット ; 広帯域(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 STATUS,RP0 ;バンク1に切替え MOVLW 062H ;プリスケーラ8倍にセット MOVWF OPTION_REG ; BCF STATUS,RP0 ;バンク0に戻る GOTO SKIP1 LOWBAND BCF BAND,0 ;1/1モード(BAND=0) BSF STATUS,RP0 ;バンク1に切替え MOVLW 068H ;プリスケーラ無しにセット MOVWF OPTION_REG ; BCF STATUS,RP0 ;バンク0に戻る SKIP1 BCF GATE,0 ;set 1sec BTFSS PORTB,5 ;ゲートタイムチェック BSF GATE,0 ;set 0.1sec 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 RETURN ;**** 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 RETURN ;*************************************** ;* Subroutine for Send to LED controler ;*************************************** TXDATA BCF PORTA,3 ;Yellow ON ;**** START BIT BCF PORTA,0 ;Start Bit Send CALL TM100 ;100usec ;***** DATA 8*3 BIT MOVF BYTE2,W CALL TX_BYTE MOVF BYTE1,W CALL TX_BYTE MOVF BYTE0,W CALL TX_BYTE ;***** STOP BIT BSF PORTA,0 CALL TM100 BSF PORTA,3 ;Yellow OFF RETURN ;******* 1バイト転送サブルーチン ****** TX_BYTE MOVWF TEMP ;save temporaly MOVLW 8H ;8bit counter MOVWF DAT_CNT TX_LP RLF TEMP,F ;Bit shift BTFSS STATUS,C ;0,1 check GOTO TX_0 GOTO TX_1 TX_0 BCF PORTA,0 ;0 send GOTO TX_NEXT TX_1 BSF PORTA,0 ;1 send NOP ;dumy TX_NEXT CALL TM100 ;(322+10)*312.5nsec=103.6usec DECFSZ DAT_CNT,F ;8bits end test GOTO TX_LP ;Not end loop RETURN ;between byte +5cycle ;********************************* ; Timer Routine ; TIME10 :10usec ; TM100 :100usec ; at  12.8MHz ;********************************* TM100 MOVLW 9H ;9回ループ MOVWF CNT1 TIM_LP1 CALL TIME10 ;2+(32+3)x9-1=316 DECFSZ CNT1,F GOTO TIM_LP1 RETURN ;316+4=320 TIME10 MOVLW 8H ;8回ループ MOVWF CNT2 TIM_LP2 DECFSZ CNT2,F ;2+3x8-1=25 GOTO TIM_LP2 NOP RETURN ;25+5=30 END