ホーム

08/09/21
例えば5Hz等の低い周波数の測定をするときには1秒間測定しても5と測定されて有効桁数1桁になってしまいます。
その為低い周波数の測定には周期測定を行います。
測定波形でゲートをON/OFFしてonの時に自分のクロックを数えて時間を測定し逆算して周波数を表示します。
netで周期測定プログラムを探して見ましたが、見つかりません。
そこで考えて見ました。
回路図は超簡単。 pic16F716 (秋月で110円)です。


クロックはEPSONの4MクリスタルモジュールSG-11 8501B を使いました 有効桁数5桁 足は左から G ,OUT, 5V
ジャンク箱の中にあった手持ち部品


セ ラロックでも有効桁数4桁位ありますので良いと思いますが!


7セグLEDは4桁 アノードコモン ダイナミック点灯用 SL-1063-50  ジャンク 1個32円か53円


JWCADで基板パターン作成 大きさ 31*33o 超小型です。

でもこんな事が簡単に出来る CNC はすばらしい。皆でCNCを作りましょう!!


基板は上記と違いますが、写真撮り忘れてしまいました。

完成した基板上部


基板パターン部


表示はレンジ自動切換えです。常に4桁表示します。DPは表示しません。7セグに無いので
クロックの1/4をカウントします。したがって今回は1MHzになります。
割込みを使って見ました。


PICのCCPモジュール キャプチャーモード を使用して計測します。
ポートB3はCCP1のシュミット入力ポートです。
入力信号をトリガにしてタイマ1の内容を保持します。
TMR1H,TMR1Lの内容がトリガ信号によりCCPR1H.CCPR1Lにコピーし同時に割込みが発生します。

;周期カウンター アノードコモン JA0BAS 08/07/24
        LIST            P=PIC16F716
        INCLUDE         "P16F716.INC"
    __CONFIG _PWRTE_ON & _WDT_OFF & _CP_OFF & _HS_OSC & _BOREN_OFF
    errorlevel  -302        ; suppress message 302 from list file
;  Define Constant or Work
#define        K1    PORTA,0    ;1Hz
#define        K2    PORTA,1    ;10Hz
#define        K3    PORTA,2    ;100Hz
#define        K4    PORTA,3    ;1000Hz

x0        equ    20h
x1        equ    21h
x2        equ    22h
x3        equ    23h
vfo0        equ    28h    ;Lo(VFO)。
vfo1        equ    29h
vfo2        equ    2ah
cfo3        equ    2bh
y0        equ    2ch
y1        equ    2dh
y2        equ    2eh
y3        equ    2fh
dec0        equ    30h    ; 10進格納場所(10バイト)
dec1        equ    31h
dec2        equ    32h
dec3        equ    33h
dec4        equ    34h
dec5        equ    35h
dec6        equ    36h
dec7        equ    37h
dec8        equ    38h
dec9        equ    39h    ;dec_top
val0        equ    3ah    ; 変換したい値(32ビット)
val1        equ    3bh
val2        equ    3ch
val3        equ    3dh
val_m        equ    3eh    ; 一時余り格納場所(サブルーチンで使用)
overf        equ    44h
dsp0        equ    45h    ;LED表示データ 5桁
dsp1        equ    46h
dsp2        equ    47h
dsp3        equ    48h
dsp4        equ    49h
tempa        EQU    4bh
wait_cn        equ    4ch
wait_cn2    equ    4dh
cn        equ    4eh
cs        equ    4fh    ;sub-counter
COUNTF        EQU    60H
W_TEMP        EQU    61H
W_TEM        EQU    62H
ST_TEMP        EQU    63H
INT_C        EQU    64H
MOVFF   MACRO     SRC,DST    ;←MOVFF というマクロを登録、引数は SRC DST
    MOVF    SRC,W    ;命令を書く
    MOVWF   DST
    ENDM              ;マクロ終了
CPLFN   MACRO   L,FILE,PTR     ;IF(L <> FILE) GOTO PTR F<>Lの場合PTRへとぶ
        MOVF    FILE,W         ;WREG破壊 例:CPLFN   H'10',FILE,PTR
        XORLW   L        ;IF FILE = L THEN Z = 1
        BTFSS   STATUS,Z    ;Z = 1 なら1行とばす
        GOTO    PTR    
      ENDM

    org 0
    goto start
    org 4
    goto INTR
tabl    ANDLW    B'00001111'    ;下位4ビット有効
    addwf    pcl,F          ;cycle3
;               ADBE-FGC      7segment のA〜F      
    retlw    b'11110101'    ;letter 0    RB0(6)-C
    retlw    b'00100001'    ;letter 1    RB1(7)-G
    retlw    b'11110010'    ;letter 2    RB2(8)-F
    retlw    b'11100011'    ;letter 3    RB3(9)-
    retlw    b'00100111'    ;letter 4    RB4(10)-E
    retlw    b'11000111'    ;letter 5    RB5(11)-B
    retlw    b'11010111'    ;letter 6    RB6(12)-D
    retlw    b'10100001'    ;letter 7    RB7(13)-A
    retlw    b'11110111'    ;letter 8
    retlw    b'11100111'    ;letter 9      A   
    retlw    b'01110101'    ;letter U     ____
    retlw    b'01010100'    ;letter L     F    |    | B
    retlw    b'11010100'    ;letter C    |_G__|
    retlw    b'10110111'    ;letter A     E    |    | C
    retlw    b'10010110'    ;letter F    |____|   
    retlw    b'00000010'    ;letter -      D   
;--------------------------------------------------------------------------
start
INI
    bsf    STATUS,RP0    ;BANK1
    MOVLW    b'11111111'    ;初期設定 アナログOFF
    MOVWF    ADCON1        ;16F716 独自
    MOVLW    b'00001000'    ;初期設定 RB3 CCP入力
    MOVWF    TRISB
    MOVLW    B'11010111'    ;OPTION set
    MOVWF    OPTION_REG    ;for TMR0
    BCF    PIE1,TMR1IE     ;TMR1 OVERフロー割込禁止
    BCF    PIE1,CCP1IE     ;チャプチャー割込禁止
    BCF    PIE1,TMR2IE     ;TMR2 OVERフロー割込禁止
    MOVLW    b'11110000'    ;初期設定入力 RA0-3 桁出力 RA4 TOCKI
    MOVWF    TRISA   
    BCF    STATUS,RP0    ;BANK0
    MOVLW    b'11111111'
    MOVWF    T2CON        ;1:16,1:16 SET=256   
    CLRF    TMR2
    MOVLW    b'11111111'    ;LED OFF
    MOVWF    PORTA        ;MOVWF    PORTA
    MOVLW    b'00000101'    ;初期設定入力
    MOVWF    CCP1CON        ;チャプチャー立上エッジごと
        MOVLW    b'00000000'    ;初期設定入力
    MOVWF    T1CON         ;T1CONレジスタ プリスケーラ1:1
    BCF    T1CON,T1OSCEN    ;OSC停止
    BCF    T1CON,T1SYNC    ;同期
    BCF    T1CON,TMR1CS    ;int osc
    BSF    T1CON,TMR1ON     ;TMRのTMR ONビットをセット カウント開始
    CLRF    COUNTF
    CLRF    PIR1
    BSF    INTCON,PEIE     ;周辺割込の許可
    BSF    INTCON,GIE     ;全体割込の許可
    CLRF    TMR1H
    CLRF    TMR1L
    CLRF    DSP0
    CLRF    DSP1
    CLRF    DSP2
    CLRF    DSP3
    CLRF    INT_C
MAIN
display    ;RETURN                   
    BTFSS    INT_C,2        ;4回まで待つ
    GOTO    DIS1
    bsf    STATUS,RP0    ;BANK1
    BTFSC    PIE1,CCP1IE     ;チャプチャー割込中?
    GOTO    DIS2
    BCF    STATUS,RP0    ;BANK0
    CLRF    TMR1L
    CLRF    TMR1H
    CLRF    A2
    BCF    PIR1,CCP1IF    ;CCP FLG CLR
    bsf    STATUS,RP0    ;BANK1
    BSF    PIE1,CCP1IE     ;チャプチャー割込許可
    BCF    STATUS,RP0    ;BANK0
    GOTO    DIS1
DIS2
    BCF    STATUS,RP0    ;BANK0
    BTFSS    INT_C,3        ;8回過ぎたらErr
    GOTO    DIS1
    CLRF    DSP0
        CLRF    DSP1
        CLRF    DSP2
        CLRF    DSP3
        CLRF    DSP4
    CALL    DEND
DIS1    movf    dsp3,w         ;100KHz桁   
    call    TABL
    MOVWF    W_TEM
    COMF    W_TEM,W        ;反転
    movwf    portb           
    BCF    K4           
    call    TIME       
    bSf    K4   
    movf    dsp2,W         ;10KHz桁
    call    TABL
    MOVWF    W_TEM
    COMF    W_TEM,W        ;反転
    movwf    portb
    BCF    K3
    call    TIME       
    bSf    K3   
    movf    dsp1,W         ;1KHz桁
    call    TABL
    MOVWF    W_TEM
    COMF    W_TEM,W        ;反転
    movwf    portb
    BCF    K2
    call    TIME       
    bSf    K2   
    movf    dsp0,W         ;0.1KHz桁
    call    TABL
    MOVWF    W_TEM
    COMF    W_TEM,W        ;反転
    movwf    portb
    BCF    K1
    call    TIME       
    bSf    K1   
    GOTO    MAIN   
TIME    DECFSZ    wait_cn,f
    GOTO    $-1
    DECFSZ    wait_cn,f
    GOTO    $-1
    btfsS    PIR1,TMR1IF    ;1M/64k=15 100Ms以内にCHKする
    GOTO    CHK             ;TMR1 OVER FRO
    BCF    PIR1,TMR1IF    ;クリヤー
    INCF    A2,F        ;
CHK    BTFSS    PIR1,TMR2IF    ;TMR2 OVER FRO CHK
    RETURN
    BCF    PIR1,TMR2IF
    INCF    INT_C,F
    RETURN
;
INTR     ;割込処理
PUSH    BCF    INTCON,GIE     ;全体割込の禁止
    MOVWF    W_TEMP        ;Wレジスタ待避
    SWAPF    STATUS,W    ;STATUS取出
    MOVWF    ST_TEMP        ;STATUS待避
    CALL    INTMAIN

pop    SWAPF    ST_TEMP,W    ;STATUSを戻す
    MOVWF    STATUS   
    SWAPF    W_TEMP,F    ;Wレジスタを戻す
    SWAPF    W_TEMP,W
    BSF    INTCON,GIE     ;全体割込の許可
    RETFIE            ;割込を許可してリターン

INTMAIN    BCF    PIR1,CCP1IF    ;CCP FLG CLR
    CPLFN    01H,COUNTF,NEXT
    MOVFF    CCPR1L,A4    ;NEW->A
    MOVFF    CCPR1H,A3
    CALL    SUB32        ;NEW-OLD(A-B)=A
    MOVFF    A4,B4
    MOVFF    A3,B3
    MOVFF    A2,B2
    MOVLW    B'00000000'    ;A=D'4000M'を2進数でSET
    MOVWF    A4
    MOVLW    B'00101000'    ;1Hzで1000表示
    MOVWF    A3
    MOVLW    B'01101011'    ;誤差を無くすためなるべく大きな数
    MOVWF    A2
    MOVLW    B'11101110'
    MOVWF    A1
    CALL    DIV32        ;4 000 000 000/xx(A/B)=A
    BCF    STATUS,C    ;/2
    RRF    A1,F
    RRF    A2,F
    RRF    A3,F
    RRF    A4,F
    BCF    STATUS,C    ;/2
    RRF    A1,F
    RRF    A2,F
    RRF    A3,F
    RRF    A4,F
    MOVFF    A4,VAL0        ;A->VAL
    MOVFF    A3,VAL1
    MOVFF    A2,VAL2
    MOVFF    A1,VAL3
    CALL    DCMAIN        ;B->D 変換 答えはDEC0-9
    MOVLW    2Fh        ; DEC0-9 10進格納場所(10バイト)開示番地
    MOVWF    FSR
A    INCF    FSR,F
    MOVF    INDF,W
    BTFSS    STATUS,Z    ;値が0(Z=1)でスキップ
    GOTO    CEND
    MOVF    FSR,W
    SUBLW    36h        ;36Hまでで終了
    BTFSS    STATUS,Z    ;36hの場合(Z=1)でSKIP
    GOTO    A        ;次を確認
CEND    MOVFF    INDF,DSP3    ;DEC->DSP へ複写 4桁
    INCF    FSR,F
    MOVFF    INDF,DSP2
    INCF    FSR,F
    MOVFF    INDF,DSP1
    INCF    FSR,F
    MOVFF    INDF,DSP0
DEND    CLRF    COUNTF        ;以後CCPR終了処理
    CLRF    TMR1L
    CLRF    TMR1H
    CLRF    A2        ;TMR1 OVER CLR
    CLRF    A1
    bsf    STATUS,RP0    ;BANK1
    BCF    PIE1,CCP1IE     ;チャプチャー割込禁止
    BCF    STATUS,RP0    ;BANK0
    CLRF    INT_C
    RETURN

NEXT    MOVFF    CCPR1L,B4    ;OLD->B
    MOVFF    CCPR1H,B3
    MOVFF    A2,B2
    CLRF    B1
    INCF    COUNTF,F
    RETURN
;---------------------------------------------------------------------
;32ビットバイナリ→10進変換
;valに32ビットデータを置く。(val3:val2:val1:val0)
;dcmainをコールする。    decに答えが格納される。
;    (dec0:dec1:...:dec8:dec9)
;dec0が最上位桁でdec[9]が最下位桁です。    変換後valは破壊される。
dcmain
    movLW    39H        ; 格納場所初期値 DEC9
    MOVWF    FSR
    call    devide        ; 最下位変換
    call    devide        ;10回繰り返し
    call    devide
    call    devide
    call    devide
    call    devide
    call    devide
    call    devide
    call    devide
    call    devide        ; 最上位変換
    RETURN
;    ÷10サブルーチン    10で除算します
devide        MOVLW    D'32'
        MOVWF    cn        ; 32ビットくり返し
        clrf    val_m
devide0        BCF    STATUS,C
        RLF    val0,F
        RLF    val1,F
        RLF    val2,F
        RLF    val3,F
        RLF    val_m,F
        movlw    b'11110110'    ;F6H
        addwf    val_m,0
        btfsc    STATUS,c
        movWF    val_m
        btfsc    STATUS,c
        incF    val0,F
        DECFSZ    CN,F
        GOTO    devide0
        decF    fsr,F
        MOVFF    val_m,INDF    ; 余り
        RETURN
   
;*********************************************************************
;    32bit四則演算ルーチン    PM=216/DM=15
;*********************************************************************
;    32bit除算ルーチン    A÷B=A・・・B    (call    DIV32)
;    0エラーのときは、A,B ともに 0 クリア
;    A1〜A4    割られる数    /    答え
;    B1〜B4    割る数    /    余り    137〜3609命令
;---------------------------------------------------------------------
;    32bit乗算ルーチン    AXB=AB    (call    MUL32)
;    A1〜A4,B1〜B4 答えは 64bit    1639命令
;---------------------------------------------------------------------
;    32bit加算ルーチン    A+B=A;    (call    ADD32)
;    STATUS,C は正確/B は壊れない    38命令
;---------------------------------------------------------------------
;    32bit減算ルーチン    A−B=A;    (call    SUB32)
;    STATUS,C は正確/B は壊れない    77命令
A1    equ    50h        ;割られる数上位
A2    equ    51h        ;    ↓
A3    equ    52h        ;    ↓
A4    equ    53h        ;割られる数下位
B1    equ    54h        ;割る数上位
B2    equ    55h        ;    ↓
B3    equ    56h        ;    ↓
B4    equ    57h        ;割る数下位
W1    equ    58h        ;ワーク1
W2    equ    59h        ;ワーク2
W3    equ    5Ah        ;ワーク3
W4    equ    5Bh        ;ワーク4
Na    equ    5Ch        ;Aのシフト値
Nba    equ    5Dh        ;BとAのシフト値の差
Ctemp    equ    5Eh
;---------------------------------------------------------------------
SET32:
        movlw        0ffh    ;割られる数上位    (ffffffffh=4294967295)
        movwf        A1    ;    〜
        movlw        0ffh    ;    〜
        movwf        A2                ;    〜
        movlw        0ffh            ;    〜
        movwf        A3                ;    〜
        movlw        0ffh            ;    〜
        movwf        A4                ;割られる数下位
        movlw        0ffh    ;割る数上位       (989680h=10000000)
        movwf        B1                ;    〜
        movlw        0ffh            ;    〜
        movwf        B2                ;    〜
        movlw        0ffh             ;    〜
        movwf        B3                 ;    〜
        movlw        0ffh                ;    〜
        movwf        B4                ;割る数下位
        return
DIV32:
        clrf        Na        ;初期値をセット
        clrf        Nba
        clrf        W1
        clrf        W2
        clrf        W3
        clrf        W4
LOOPA:
        btfsc        A1,7        ;最上位bitまでループ
        goto        LOOPB        ;最上位まできたら、次へ
        bcf        STATUS,C
        rlf        A4,f        ;左シフトする
        rlf        A3,f
        rlf        A2,f
        rlf        A1,f
        incf        Na,f        ;カウント加算
        btfss        Na,5        ;カウントが 32 か?
        goto        LOOPA        ;ループ
        goto        ANSERR        ;カウント値が 32 ならばエラー処理
LOOPB:
        btfsc        B1,7        ;最上位bitまでループ
        goto        NCHK        ;最上位まできたら、次へ
        bcf        STATUS,C
        rlf        B4,f        ;左シフトする
        rlf        B3,f
        rlf        B2,f
        rlf        B1,f
        incf        Nba,f        ;カウント加算
        btfss        Nba,5        ;カウントが 32 か?
        goto        LOOPB        ;ループ
        goto        ANSERR        ;カウント値が 32 ならばエラー処理
NCHK:
        movf        Na,w        ;Nbaを計算
        subwf        Nba,f
        incf        Nba,f
        btfss        STATUS,C    ;Nbaが負なら
        goto        ANS1        ;ANSZへジャンプ
        movf        Nba,w
        addwf        Na,f
HOS32:
        call        SUB32
        btfss        STATUS,C
        goto        ADDH
LOOPH:
        rlf        W4,1    ;左シフトする(結果もシフトされる)
        rlf        W3,1
        rlf        W2,1
        rlf        W1,1
        rlf        A4,1            ;左シフトする
        rlf        A3,1
        rlf        A2,1
        rlf        A1,1
        decf        Nba,f
        btfsc        STATUS,Z
        goto        ANS1
        btfsc        A1,7            ;最上位までループ
        goto        HOS32            ;最上位まできたらHOS32へ
        goto        LOOPH
ADDH:
        call        ADD32
        bcf            STATUS,C
ADDHLOOP:
        rlf        W4,1    ;左シフトする(結果もシフトされる)
        rlf        W3,1
        rlf        W2,1
        rlf        W1,1
        rlf        A4,1            ;左シフトする
        rlf        A3,1
        rlf        A2,1
        rlf        A1,1
        decf        Nba,f
        btfsc        STATUS,Z
        goto        ANS1
        call        SUB32
        bsf            STATUS,C
        btfsc        A1,7
        goto        ADDHLOOP
        goto        LOOPH
ANS1:
        bcf        STATUS,C
        rrf        A1,f            ;右シフトする
        rrf        A2,f
        rrf        A3,f
        rrf        A4,f
        decfsz        Na,f
        goto        ANS1
ANSS:                            ;解答をセットし終了
        movf        A1,w
        movwf        B1            ;余りをBにコピー
        movf        A2,w
        movwf        B2
        movf        A3,w
        movwf        B3
        movf        A4,w
        movwf        B4
        movf        W1,w
        movwf        A1            ;答えをAにコピー
        movf        W2,w
        movwf        A2
        movf        W3,w
        movwf        A3
        movf        W4,w
        movwf        A4
        return
ANSERR:                            ;エラー処理
        clrf        A1            ;数値クリア
        clrf        A2
        clrf        A3
        clrf        A4
        goto        ANSS
SUB32:
        call        COM32        ;補数計算後、加算することにより減算する
        call        ADD32
        call        COM32
        bcf            STATUS,C
        btfsc        Ctemp,0
        bsf            STATUS,C
        retlw        0
ADD32:                            ;32bit加算
        bcf            Ctemp,0
        movf        B4,w
        addwf        A4,f
        movlw        1
        btfsc        STATUS,C
        addwf        A3,f
        btfsc        STATUS,C
        addwf        A2,f
        btfsc        STATUS,C
        addwf        A1,f
        btfsc        STATUS,C
        bsf            Ctemp,0
        movf        B3,w
        addwf        A3,f
        movlw        1
        btfsc        STATUS,C
        addwf        A2,f
        btfsc        STATUS,C
        addwf        A1,f
        btfsc        STATUS,C
        bsf            Ctemp,0
        movf        B2,w
        addwf        A2,f
        movlw        1
        btfsc        STATUS,C
        addwf        A1,f
        btfsc        STATUS,C
        bsf            Ctemp,0
        movf        B1,w
        addwf        A1,f
        btfsc        STATUS,C
        bsf            Ctemp,0
        btfsc        Ctemp,0
        bsf            STATUS,C
        retlw        0
COM32:
        comf        B4,f
          comf        B3,f
        comf        B2,f
        comf        B1,f
        movlw        1
        addwf        B4,f
        btfsc        STATUS,C
        addwf        B3,f
        btfsc        STATUS,C
        addwf        B2,f
        btfsc        STATUS,C
        addwf        B1,f
        retlw        0
MUL32:
        movlw        21h
        movwf        Na
        movf        A1,w            ;Aをワークへ
        movwf        W1
        clrf        A1
        movf        A2,w
        movwf        W2
        clrf        A2
        movf        A3,w
        movwf        W3
        clrf        A3
        movf        A4,w
        movwf        W4
        clrf        A4
        bcf            STATUS,C
LOOPM:
        rrf        A1,f            ;右シフトする
        rrf        A2,f
        rrf        A3,f
        rrf        A4,f
        rrf        W1,f
        rrf        W2,f
        rrf        W3,f
        rrf        W4,f
        btfsc        STATUS,C
        call        ADD32
        decfsz        Na,f
        goto        LOOPM
        movf        W1,w            ;ワークからBへ
        movwf        B1
        movf        W2,w
        movwf        B2
        movf        W3,w
        movwf        B3
        movf        W4,w
        movwf        B4
        return

    END
プログラムです。バグがあったら訂正しますので連絡してください。
反省
クロックは20MHZを使用して精度を上げる。
1サイクルでカウントしているが、4サイクル位カウントして精度を上げたほうが良い。
他のプログラムを参考にして作成したので無駄な部分や意味の無い部分がたくさんあります。
普通のカウンターも組込み入力周波数により自動的に切り替えて表示する。
何方か改良してください。

5.347Hzを計測中です。