home CNCの構想 CNCの製作 CNCのSOFT CNCの作品 ゲストブック
10/7/21
要望の多かったPIC16F84AでPIC周波数カウンター60MHZ_MAXを作ってみました。
PIC16F84A
を使いました。
クロックは超高精度クリスタルモジュール(12.8MHz±1ppm)
◆フラッシュ:1Kワード
◆RAM:68バイト
◆EEPROM:64バイト
◆クロック:DC〜20MHz
◆電源電圧:4.5V(MAX20MHz)〜5.5V(MAX20MHz)
7SEG LED はカソードコモンです。アノードコモンの方がおすすめですが、ソフト、回路変更必要です。
コレクター抵抗は100オーム VRは20Kを使ってコレクター電圧2.4V位に調整しています。
セグメント電流調整抵抗は100Ω、ベースの抵抗は4.7KΩを使ってください。
RA3に繋がっている抵抗は100Ω
250mS測定し4倍して周波数にしています。毎秒4回計測します。
2倍、4倍 と言った計算はシフトするだけで計算終わりですのでソフトが簡単高速になります。
8ビットの1/256内蔵プリスケーラーを前置して8ビットのタイマー0を使い測定しています。
このプリスケーラーの性能で最高測定周波数が決まります。
PORTA4がこのプリスケーラーの入力端子です。
PORTA3で250mSのゲートを行っています。
100MHzの桁まで表示していますが、この PIC ではプリスケーラーを外付けしないと測定できません。
表示最小桁は10Hzです。
周波数調整可能なクロックを使わないと10Hzの桁は無効(無意味)です。
18P の PIC で8桁余裕を持って表示しています。
プログラムの工夫で使用ピン数が激減し回路も簡単になりました。
写真のとおり表面に部品がほとんどありません。
下記をコピーして*.ASMとして保存
MPLABにてアセンブルしてください。
;8-DIGIT 8-PIN Kカソードコモン LED FCOUNT 10/7/21 JA0BAS 12.8MHz ;RA3の抵抗は200Ω使用、測定MAXは60MHz LIST P=PIC16F84A ; INCLUDE "P16F84A.INC" __CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC ERRORLEVEL -302 ; SUPPRESS MESSAGE 302 FROM LIST FILE ;------- ADRESS 20&H DEC0 EQU 20H ;100MHZ 10進格納場所(10バイト) DEC1 EQU 21H ;10MHZ DEC0が最上位桁でDEC[9]が最下位桁です。 DEC2 EQU 22H ;1MHZ DEC3 EQU 23H ;100KHZ DEC4 EQU 24H ;10KHZ DEC5 EQU 25H ;1KHZ DEC6 EQU 26H ;100HZ DEC7 EQU 27H ;10HZ DEC8 EQU 28H ;1HZ DEC9 EQU 29H ; OVERF EQU 2AH VFO_M EQU 2EH ; 一時余り格納場所(サブルーチンで使用) WT EQU 2FH VFO0 EQU 31H ;PSAの値LO(VFO)。 VFO1 EQU 32H ;TMR0の値 VFO2 EQU 33H ;TOIFによりインクリメントした値 VFO3 EQU 34H ;VFO(2)のオーバフローによりINCした値 WAIT_CN EQU 36H CN EQU 37H S_DAT EQU 38H K_POS EQU 39H ;桁位置 K_BP EQU 3AH O_DAT EQU 3BH TC EQU 3CH TW EQU 3DH W_TEMP EQU 3EH ST_TEMP EQU 3FH MOVFF MACRO DST,SRC ;←MOVFF というマクロを登録、引数は SRC DST MOVF DST,W MOVWF SRC ENDM ORG 0 GOTO INIT ORG 4 GOTO INIT ;---------------------------------------------------------------------------- INIT BSF STATUS,RP0 ;BANK1 MOVLW B'00000000' MOVWF TRISB ; PORTBをOUTに MOVLW B'01100111' ;PRESCALER 1/256 SET ;PORTB_PU;立上カウント MOVWF OPTION_REG BCF STATUS,RP0 ;BANK0 MOVLW B'00000001' ;0桁目の位置 MOVWF K_BP CLRF K_POS CLRWDT ;PRESCALERをクリア CLRF TMR0 ;TMR0をクリア MAIN CALL C_MAIN ;COUNTER MEIN CALL X4 ;4倍する CALL DCMAIN ;16進->10進変換 CLRF VFO0 ;変数クリヤ CLRF VFO1 CLRF VFO2 CLRF VFO3 GOTO MAIN ; ------------------------------------------------------------------- C_MAIN CLRF PORTB CLRF PORTA BSF STATUS,RP0 ;BANK1 MOVLW B'00011000' MOVWF TRISA ; PORTA.3をINPUT MODE=HIGH IMPEDANCE/TMR0の開始 BCF STATUS,RP0 ;BANK0 CLRWDT ;;TEMP 250 MSEC カウントの始点 CLRF TMR0 ;カウンタTMR0をクリア MOVLW D'176' ;時間調整 MOVWF WAIT_CN ; DECFSZ WAIT_CN,F GOTO $-1 MOVLW D'122' ;時間調整 MOVWF CN CMAIN0 CALL DISPLAY DECFSZ CN,F GOTO CMAIN0 CMAIN1 BSF STATUS,RP0 ;BANK1 MOVLW B'00010000' MOVWF TRISA ;PORTA.3をOUT,TMR0の停止 250MSECカウントの終点 BCF STATUS,RP0 ;BANK0 BCF PORTA,3 MOVFF TMR0,VFO1 ;TMR0のDATAをVFO1に TOGGLE BSF PORTA,3 ;PORT PORTA4のトグル BCF PORTA,3 DECF VFO0,F MOVF TMR0,W SUBWF VFO1,W ;VFO1-TMR0=0であれば Z=1 BTFSC STATUS,Z GOTO TOGGLE RETURN ;VFO0への PRESCALER値の取込完 ;---------------------------------- DELAY250 ;TMR0のオーバフロー(TMR0IF)のCHK MOVLW D'254' ; MOVWF WAIT_CN ; DECFSZ WAIT_CN,F GOTO $-1 MOVFF INTCON,OVERF ;チェックした瞬間を保存 BCF STATUS,C BTFSC OVERF,2 ; INCF VFO2,F ; BTFSC STATUS,C ; INCF VFO3,F ; BTFSC OVERF,2 ; BCF INTCON,T0IF ; フラグクリヤ NOP RETURN ; ;------------------------------------------------------------- TABLE ;K_POS値をPCLに+しでJMP,データを持ってRETする ANDLW B'00001111' ;下位4ビット ADDWF PCL,F RETLW B'00111111' ;0 C0 RETLW B'00000110' ;1 RETLW B'01011011' ;2 RETLW B'01001111' ;3 A RETLW B'01100110' ;4 ____ RETLW B'01101101' ;5 F | | B RETLW B'01111101' ;6 |_G__| RETLW B'00000111' ;7 E | | C RETLW B'01111111' ;8 |____| RETLW B'01101111' ;9 D RETLW B'01110111' ;A RETLW B'01111100' ;B RETLW B'01011000' ;C RETLW B'01011110' ;D RETLW B'01111001' ;E RETLW B'01110001' ;F X4 BCF STATUS,C ;*2 250MS 計測値を4倍する RLF VFO0,F RLF VFO1,F RLF VFO2,F RLF VFO3,F BCF STATUS,C ;*2 RLF VFO0,F RLF VFO1,F RLF VFO2,F RLF VFO3,F RETURN ;--------------------------------------------------------- ;32BITバイナリ→10進変換 変換後VFOは破壊 ;VFOに32BITデータを置く。(VFO3:VFO2:VFO1:VFO0) ;DECに答えが格納(DEC0:DEC1:...:DEC8:DEC[9]) DCMAIN MOVLW H'29' MOVWF FSR ; 格納場所初期値 CALL DEVIDE ; 最下位変換 CALL DEVIDE ;10回繰り返し CALL DEVIDE CALL DEVIDE CALL DEVIDE CALL DEVIDE CALL DEVIDE CALL DEVIDE CALL DEVIDE CALL DEVIDE ; 最上位変換 RETURN DEVIDE MOVLW D'32' ;÷10サブルーチン MOVWF CN ; 32ビットくり返し CLRF VFO_M DEVIDE0 BCF STATUS,C RLF VFO0,F RLF VFO1,F RLF VFO2,F RLF VFO3,F RLF VFO_M,F MOVLW B'11110110' ADDWF VFO_M,0 BTFSC STATUS,C MOVWF VFO_M BTFSC STATUS,C INCF VFO0,F DECFSZ CN,F GOTO DEVIDE0 DECF FSR,F MOVFF VFO_M,INDF ; 余り RETURN DISPLAY LEDOFF ;規定値 全IN 全消灯 BSF STATUS,RP0 ;BANK1 MOVLW B'11111111' ;1=INMODE LEDOFF MOVWF TRISB BCF STATUS,RP0 ;BANK0 CLRF PORTB CLRF O_DAT MOVF K_POS,W SUBLW D'7' ;7桁目か BTFSC STATUS,Z GOTO K_7 ;7桁目のみFLOAT LINEを使わない別処理 K_ETC MOVF K_POS,W ;K_POS分だけポインタを進める SUBLW 27H ;DATAの先頭アドレス MOVWF FSR ;アドレスをセット MOVF INDF,W ;FSR番地から表示DATA取得 CALL TABLE ;7SEG DATA に変換 MOVWF S_DAT ;7SEG DATA 保管 MOVF K_BP,W ;FLOAT LINEの位置 IORWF O_DAT,F ;発光桁を強制的に1にするON K側をLに COMF O_DAT,F ANDWF S_DAT,W ;1の部分素通りマスク BTFSS STATUS,Z ;必要ならFLOAT LINEをHにする BSF S_DAT,7 ;RB7 0=OUT 発光 MOVF K_BP,W ;FLOAT LINEの位置 IORWF S_DAT,F COMF S_DAT,F ;反転させ MOVF O_DAT,W MOVWF PORTB MOVF S_DAT,W BSF STATUS,RP0 ;BANK1 MOVWF TRISB ;SEG DATA SET BCF STATUS,RP0 ;BANK0 INCF K_POS,F ;桁+1 BCF STATUS,C RLF K_BP,F ;桁位置+1 CALL DELAY250 GOTO LEDOFF K_7 MOVF 20H,W ;20H番地から7桁目の表示DATA取得 CALL TABLE ;7SEG DATA に変換 MOVWF S_DAT ;7SEG DATA 保管 BSF O_DAT,7 ;発光桁を強制的に1にするON K側をLに COMF O_DAT,F BSF S_DAT,7 ;RB7 0=OUT 発光 COMF S_DAT,F ;反転させ MOVF O_DAT,W MOVWF PORTB MOVF S_DAT,W BSF STATUS,RP0 ;BANK1 MOVWF TRISB ;SET BCF STATUS,RP0 ;BANK0 CLRF K_POS ;NEXT 0桁 MOVLW B'00000001' ;0桁目の位置 MOVWF K_BP CALL DELAY250 NOP NOP NOP RETURN END
プログラムのバグありましたら訂正しますのでご連絡ください。
プリスケーラーを使って最高カウント周波数をUP希望とのこと。プリスケラーに秋月で販売していた「μPB1505GR」を使用したいと
思います 1/64・1/128・1/256
が出力出来ます。正常に周波数を表示するためには2つの方法があります。ゲート時間を分収数だけ長くする方法、カウントした値を分収倍する方法があります。今回は後者で考えてみたいと思います。あまり分収を多くするとカウントに時間がかかって好ましくありません。1/64で設計します。最高で3GHz/64=47MHzですからPICで十分計測できます。ただこのICは低い周波数では感度が低くなるようです。
上記プログラムのX4サブルーチンを改良します。
X4 BCF STATUS,C ;*2 250MS 計測値を4倍する
RLF VFO0,F
RLF VFO1,F
RLF VFO2,F
RLF VFO3,F
BCF STATUS,C ;*2
RLF VFO0,F
RLF VFO1,F
RLF VFO2,F
RLF VFO3,F
RETURN
この後にX64を追加すればOKです。
X4 BCF STATUS,C ;*2 250MS 計測値を4倍する
RLF VFO0,F
RLF VFO1,F
RLF VFO2,F
RLF VFO3,F
BCF STATUS,C ;*2
RLF VFO0,F
RLF VFO1,F
RLF VFO2,F
RLF VFO3,F
X64 BCF STATUS,C ;プリスケーラーのため64倍する
RLF VFO0,F
RLF VFO1,F
RLF VFO2,F
RLF VFO3,F
BCF STATUS,C ;*2
RLF VFO0,F
RLF VFO1,F
RLF VFO2,F
RLF VFO3,F
BCF STATUS,C ;*2
RLF VFO0,F
RLF VFO1,F
RLF VFO2,F
RLF VFO3,F
BCF STATUS,C ;*2
RLF VFO0,F
RLF VFO1,F
RLF VFO2,F
RLF VFO3,F
BCF STATUS,C ;*2
RLF VFO0,F
RLF VFO1,F
RLF VFO2,F
RLF VFO3,F
BCF STATUS,C ;*2
RLF VFO0,F
RLF VFO1,F
RLF VFO2,F
RLF VFO3,F
RETURN
アセンブラーファイル HEXファイル 実物で試験してありません。動かない場合はご連絡をお願いします。