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にてアセンブルしてください。

HEXファイル   ASMファイル  LISTファイル

 

;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ファイル   実物で試験してありません。動かない場合はご連絡をお願いします。