ホーム

2009/06/24
超簡単 超安価 PIC16F54 8桁8PIN 周波数カウンター 
秋月電子で 16F54 を @60円 で販売しています。

WEBで検索してみてもほとんど資料が出てきません。
誰もやっていないのならやってみようと挑戦しました。
PIC16F54 ハードのADC等が無いのはわかりますが、いざアセンブラーで微妙に違います。
まず CALL は 2スタックまで,3回目の CALL時点で暴走です。
仕方が無いのでサブルーチンは止めて GOTO をべたべたです。
リセットベクタ が 1FF です。まず 1FFに goto 0 を書きます。
プログラムエリヤが 512ワードですが、
MEMORY USAGE MAP ('X' = Used,  '-' = Unused)
0000 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
0040 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX
0080 : XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX ---------------- ----------------
01C0 : ---------------- ---------------- ---------------- ---------------X
Program Memory Words Used:   161
Program Memory Words Free:   351
とまだまだ余裕があります。
機能が少ないのでバンク切替不要と言うか、ありません。
TRIS のアドレスが無く読み出しなどが出来ません。
RETURN / SUBLW 命令等が無い
割り込みなし
更にタイマーのオーバーフラグがありません。(T0IF)仕方ないので自分で同等なものを作りました。

まず TMR0 の最上位が 1 になるのを待ちます。
次に TMR0 の最上位が 0 になると オーバーフロー したので フラグ を立てます。
たまたま見に行かないと間に合いません。
1秒 256回 * 8文字 * 4 * 256(プリスケーラー) * 256(8ビットタイマー) = 500M オーバーフローチェック
100MHz位までは余裕を持って確認できます。
softカウンターは32ビットです。4GHz

MPLAB SIM のバグかもしれませんが、PORTが入力設定の場合はPORTに書き込みが出来ません。?
そんな訳で久しぶりのアセンブラで疲れました。



回路図 はいつもと同じです。
図面もれています。4P(reset)は5Vに繋いで下さい。
超高輝度LEDを使った場合は各LEDに入っているTRとベース抵抗も省略可能です。
例えばRB0の6番ピンを直接7セグのコモンにつなぎます。ほとんど部品のないカウンターが出来ます。
その場合電流制限抵抗は470Ωにしてください。

最高カウント周波数UPの為 RA4 の入力抵抗をはずしたくて RA3のゲート を RA4 に直接でなく TR のベースをコントロールしてみましたが、入力側のコンデンサーの影響で高速で ON / OFF が出来ず、断念しました。
波形1つでも増幅できず取りこぼすと表示が狂います。

回路図を BSCH3V で作成
JWCAD でパターン設計
NCVC  でGコード作成
MACH  自作 CNC でプリント基板切削
秀丸エディターでプログラム作成
MPLAB でアセンブル
MPLAB SIM でバグ取(これに一番時間が掛かります。)
自作 PICKIT2 で書き込み
全部FREE SOFT (無料)です。


こんな大きさになりました。100o * 38o です。ジャンパー線は割り切りです。
幅はLEDの制限です。縦はもっと小さく出来ます。
表示明るくする為 7セグLED は アノードコモン を使いました。電流制限抵抗は100オームです。
使用したLEDは2個(4桁)で30円の特売品です。



部品はほとんどありません。実用にする方はクロックを調整可能の物に変更してください。
20MHzのクロック実測 19.999988MHz でした。12Hzの誤差 校正する設備を持っていない方はこれで十分です。
部品の表示は 20.0000MHz です。表示桁は十分な精度です。

ASM アセンブラーリスト
;8-DIGIT 8-PIN A_LED 09/6/16 JA0BAS FCOUNT 20MHzクロック
    LIST        p=16F54
    INCLUDE        "p16F5X.inc"
    __CONFIG _CP_OFF & _WDT_OFF & _HS_OSC
    ERRORLEVEL  -220    ; SUPPRESS MESSAGE 302 FROM LIST FILE

TIM0    EQU    07H    ;PSAノ値LO(TIM)。
TIM1    EQU    08H    ;TMR0ノ値
TIM2    EQU    09H    ;TOIFニヨリINCシタ値
TIM3    EQU    0AH    ;TIM(2)ノoverフローニヨリINCシタ値
S_DAT     EQU    0BH
K_POS    EQU    0CH    ;桁位置
K_BP    EQU    0DH
COUNT    EQU    0EH
OVERF    EQU    0FH
DEC0    EQU    10H    ;100MHZ    ;9桁7SEG データ
DEC1    EQU    11H    ;10MHZ
DEC2    EQU    12H     ;1MHZ
DEC3    EQU    13H     ;100KHZ
DEC4    EQU    14H     ;10KHZ
DEC5    EQU    15H     ;1KHZ
DEC6    EQU    16H     ;100HZ
DEC7    EQU    17H     ;10HZ
DEC8    EQU    18H     ;1HZ
DEC9    EQU    19H     ;0HZ
POINT    EQU    1AH
WAIT_A    EQU    1BH
WAIT_B    EQU    1CH
WAIT_C    EQU    1DH
TIM_M    EQU    1EH    ; 一時余リ格納場所(SUBルーチンデ使用)
CN    EQU    1FH

       ORG        1FFH
    GOTO    INIT_
    ORG    0H

TABLE  ;K_POS値ヲPCLニ+シデJMP,データヲ持ッテRETスル
     ANDLW    B'00001111'    ;下位4ビット有効
    ADDWF     PCL,F
    RETLW     B'00111111'     ;0    3F    C0
    RETLW     B'00000110'    ;1    06
    RETLW     B'01011011'    ;2    5A
    RETLW     B'01001111'    ;3    4F     A
    RETLW     B'01100110'    ;4    66    F B
    RETLW     B'01101101'    ;5    6D     G
    RETLW     B'01111101'    ;6    7D    E C
     RETLW     B'00000111'    ;7    07     D
    RETLW     B'01111111'    ;8    7F
    RETLW     B'01101111'    ;9    6F    90
    RETLW    B'01110111'    ;A
    RETLW    B'01111100'    ;B
    RETLW    B'00111001'    ;C
    RETLW    B'01011110'    ;D
    RETLW    B'01111001'    ;E
    RETLW    B'01110001'    ;F
INIT_       
    MOVLW    B'00100111'    ;PRESCALER 1/256 SET;立上カウント
    OPTION
    MOVLW    18H
    MOVWF    POINT
    MOVLW    B'00000001'    ;0桁目ノ位置
    MOVWF    K_BP
    CLRF    K_POS

CMAIN
    CLRF    PORTB
    CLRF    PORTA
    MOVLW    B'11111111'
    TRIS    PORTA        ;PORTA3ヲINPUT MODE=HIGH IMPEDANCE/TMR0ノ開始
    CLRWDT            ;250 ms カウントノ始点  ++++++++++++++++++++++
    CLRF    TMR0        ;カウンタTMR0ヲクリア

    MOVLW    D'165'        ;時間調整3
    MOVWF     WAIT_A        ;
C1    DECFSZ    WAIT_A,F
    GOTO    C1

    MOVLW     D'255'        ;時間調整1
    MOVWF    WAIT_B
DISPLAY   
    clrf    PORTB        ;規定値 全IN 全消灯
    MOVF    K_POS,W
    BTFSC    K_BP,7        ;8桁目?
    GOTO    K_8        ;8桁目ノミFLOAT LINEヲ使ワナイ別処理
K_ETC    NOP
    MOVf    K_POS,w        ;K_POS分ダケPOINTヲ進メル
    SUBWF    POINT,W        ;DATAノ先頭アドレス
    MOVWF    FSR        ;アドレスヲセット
    MOVF    INDF,W        ;FSR番地カラ表示DATA取得
     CALL       TABLE        ;7SEG DATA ニ変換
    MOVWF    S_DAT        ;7SEG DATA 保管
    MOVF    K_BP,W        ;FLOAT LINEノ位置
    ANDWF    S_DAT,W        ;フロービット確認
    BTFSS    STATUS,Z    ;必要ナラFLOAT LINEヲLOWニスル
    BCF    PORTB,7        ;RB7=L
    BTFSS    STATUS,Z    ;必要ナラFLOAT LINEヲLOWニスル
    BSF    S_DAT,7        ;RB7 0=OUT 発光
    MOVF    K_BP,W        ;
    IORWF    PORTB,F        ;発光桁ヲON アノード側ヲHIニ
    IORWF    S_DAT,F        ;発光桁ヲON HIニスルポートヲ出力ニ設定スル
    COMF    S_DAT,W        ;反転 消灯スルPORTヲ入力HIインピーダンスニ設定
    TRIS    PORTB        ;SEG DATA SET
    INCF    K_POS,F        ;桁+1    次の桁
    BCF    STATUS,C
    RLF    K_BP,F        ;桁位置+1
    CALL    DELAY
    GOTO    DISPLAY        ;次ノ桁
K_8   
    NOP
    NOP
    NOP
    NOP
    MOVF    11H,W        ;10H番地カラ8桁目ノ表示DATA取得
     CALL       TABLE        ;7SEG DATA ニ変換
    MOVWF    S_DAT        ;一時保管 8桁目ハFLOTING LINEヲツカワナイ
    BSF    S_DAT,7        ;RB7をOUT
    COMF    S_DAT,W        ;反転 消灯スルPORTヲHIインピーダンスニ設定
    TRIS    PORTB        ;SEG DATA SET
    MOVLW    B'10000000'    ;RB0 発光桁ヲON 8桁目ノアノードヲHIニスル 他はL
    MOVWF    PORTB
    CLRF    K_POS        ;NEXT 0桁
    MOVLW    B'00000001'    ;0桁目ノ位置
    MOVWF    K_BP
    CALL    DELAY        ;NEXT ;9桁 終了
    DECFSZ    WAIT_B,F   
    GOTO     DISPLAY   
    MOVLW    B'11110111'
    TRIS    PORTA        ;PORTA.3ヲOUT TMR0ノ停止 250MSカウントノ終点 ++++++++
    MOVF    TMR0,W   
    MOVWF    TIM1
TOGGLE    ;goto    X4
    BSF    PORTA,3        ;PORT PORTA4ノトグル    プリスケーラノ読出
    NOP
    BCF    PORTA,3
    NOP
    DECF    TIM0,F
    MOVF    TMR0,W
    SUBWF    TIM1,W        ;TIM1-TMR0=0デアレバ Z=1
    BTFSC    STATUS,Z
    GOTO    TOGGLE
X4
    BCF    STATUS,C    ;*2 250mS 計測値ヲ2倍スル
    RLF    TIM0,F
    RLF    TIM1,F
    RLF    TIM2,F
    RLF    TIM3,F
    BCF    STATUS,C    ;*2
    RLF    TIM0,F
    RLF    TIM1,F
    RLF    TIM2,F
    RLF    TIM3,F
HD_C            ;16進->10進変換
    MOVLW    H'19'    ;開始アドレス
    MOVWF    FSR    ;格納場所初期値
    movlw   D'10'   ;回数SET 10回繰返
       movwf   COUNT    
DEVIDE
    MOVLW    D'32'    ;÷10サブルーチン
    MOVWF    CN    ; 32ビットクリ返シ
    CLRF    TIM_M
DEVIDE0
    BCF    STATUS,C
    RLF    TIM0,F
    RLF    TIM1,F
    RLF    TIM2,F
    RLF    TIM3,F
    RLF    TIM_M,F
    MOVLW    B'11110110'
    ADDWF    TIM_M,0
    BTFSC    STATUS,C
    MOVWF    TIM_M
    BTFSC    STATUS,C
    INCF    TIM0,F
    DECFSZ    CN,F
    GOTO    DEVIDE0
    DECF    FSR,F
    MOVF    TIM_M,W   
    MOVWF    INDF    ; 余リ
       DECFSZ    COUNT,F     
       goto     DEVIDE

    CLRF    TIM0    ;変数クリヤ    終了処理
    CLRF    TIM1
    CLRF    TIM2
    CLRF    TIM3           
    GOTO    CMAIN    ;NEXT COUNT
DELAY            ;STEP数を揃える事
    MOVLW    D'187'    ;時間調整2
    MOVWF     WAIT_C    ;
D1    DECFSZ    WAIT_C,F
    GOTO    D1

    BTFSC    OVERF,1    ;前回の状態確認0スキップ
    GOTO    D2    ;前回1janp
    BTFSC    TMR0,7    ;TMRは1?0スキップ
    BSF    OVERF,1    ;オーバーしない
    NOP        ;step 調整
    NOP        ;step 調整
    GOTO    D3    ;オーバーJAMP
D2    BTFSC    TMR0,7    ;0になったか
    GOTO    D4    ;step 調整
    BCF    OVERF,1    ;フラグSET
    BSF    OVERF,2    ;TOIFオーバーフラグSET
    NOP        ;step 調整
D3    BCF    STATUS,C    ;キャリークリヤ
    BTFSC    OVERF,2    ;TOIFオーバーフローチェック
    INCF    TIM2,F    ;TIM1 オーバーフロー
    BTFSC    STATUS,C
    INCF    TIM3,F    ;TIM2 オーバーフロー
    BCF    OVERF,2    ;TOIFフラグクリヤ
    RETLW    0
D4    GOTO    D3     ;step 調整

        END



最高カウント周波数は写真のとおり64MHzです。輝度も十分です。電流150mA流れています。
この構成で作成すると費用は 500円 掛かりません。
2009年7月のCQ誌に PIC に 74AC00 を ゲートに使って 100MHz以上の周波数をカウントした記事が出ています。
やはりゲートを高速にして PIC をドライブすると 100MHz のカウントが可能のようです。
回路を複雑にして高速にするか?好みの問題です。
このソフトはカウント時間を0.25秒にしてカウントし4倍してHzの桁まで表示しています。したがって最小分解能は4Hzです。
1Hz単位で表示したい方は1秒間カウントしてください。ただし表示変更が1秒に1回なりますので遅くてイライラします。
最高カウント周波数を上げたい方は、プリスケーラーICを前置してください。1/10を付けると600MHzまで出来ます。


09/07/16
最高周波数UPの為プリスケーラーを入れたいとのこと
1/10の場合はそのままで良いのですが、1/64や1/128の場合はカウント時間を調整して読み取る必要があります。
いまは250mSでカウントしていますので64倍すると16秒のカウントが必要になります。
これでは実用にならないので
16秒で4Hz単位
8秒で8Hz
4秒で16Hz
2秒で32Hz
1秒で64Hz
500mSで128Hz
250mSで256Hzステップになります。
つまり10Hz以下の表示は意味がありません。 1G000M000K0 8桁 ちょうど良いか!!
カウント後に今までは4倍していましたが、更に64倍 4*64=256倍 すれば良いことになります。
256 つまりちょうど8ビット 
何もしないで 10進数に 変換の 時に下8桁 0000 0000  にして実行すれば良いようです。
MB506、MB501 は1/64 ですのでこの計算で使用できます。
BG3013Fの場合は1/128 ですので500mS計測するか、下9桁に0 0000 0000を追加して10数変換を実施することになります。

基本の状態で60Mまでカウントできますので 1/10(600MHz)か 1/16(960MHz)のプリスケーラーが使いやすいですが、入手できません。


手持ちのOSCユニットの発信周波数を調べてみました。選別して使用すればカウンターにもそのまま使えるものがあります。
4          4.000002     2    
4          3.999951   49  
4          3.999991     9  
4          3999918    82
6.144    6.144043   43
6.144    6.144082   82
10        9.999939   61   
10        9.999993     7  
10        9.999918   82
12       11.999807  93
12.8     12.799821 179  
12.8     12.799999     1
20       20.000126  126
20       19.999914    86
32       32.000450  450