楽天市場
[無料でホームページを作成] [通報・削除依頼]

PIC10F322 AN592準拠 周波数カウンタ

PIC10F322を用いた周波数カウンターです。

microchipのAN592に記載のソースの改変で、AN592に準拠しています。

信号入力はRA2(T0CKI)直結、結果はRA0(TX)にてシリアル出力されます。
有効数値5桁(1~65535)、測定範囲は50Hzから50MHzです。
測定精度を上げるためPIC10F322は16MHzの外部クロックで作動させます。

ブートローダー下ではなく、スタンドアローンで作動します。

<回路図>
img_20130128-234015.jpg





<計測結果、計測誤差>

img_20130128-201633.jpg192.00k クリスタルオシレーターの周波数計測


img_20130128-200706.jpg




左側の値はPIC10F322を内部クロック8MHzで作動させたときのもので、
右側の値は16MHzのクロックオシレーターで作動させたときのものです。
手持ちのクロックオシレーターを使用した計測結果です。
クロックオシレーターで作動させることで精度は1桁、測定値のばらつきは劇的に改善しますが、
内部クロックの場合でも数%程度の誤差が許容できれば用途があります。



<ソースプログラム>

LIST P=PIC10F322
#INCLUDE <P10F322.inc>

__CONFIG _FOSC_EC & _BOREN_OFF & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _LVP_OFF & _LPBOR_OFF & _BORV_HI & _WRT_OFF

#DEFINE TX 0 ;RS-232C データ出力用ビット
#DEFINE RX 3 ;RS-232C データ入力用ビット
#DEFINE Direct ;RS-232C 直結方式、コメントアウトで反転方式

;****************************************************************************************
;* *
;* 注意(重要) *
;* *
;* 本デモプログラムはパソコンで周波数を表示します。   *  
;* *
;* 通信にTX=RA0,RX=RA3を使用します。信号入力はRA2(T0CKI)です。 *
;* *
;* RA1にはクリスタルオシレーター16MHzの出力を接続します。 *
;* *
;* ご使用にはTREATERMやハイパーターミナルなどのターミナルソフトが必要です。 *
;* 通信条件: ボーレート19200、8ビット、1ストップビット、ノーパリティ *
;* *
;* *
;* このデモプログラムはマイクロチップ社のアプリケーションノートAN592に示された *
;* ソースプログラムを改変したもので、アルゴリズム、性能などはAN592に準拠 *
;* しています。 *
;* *
;****************************************************************************************
;
;This program implements the concepts for the frequency counter
;using a PIC16C54. In this program, RA0 is connected directly
;to the tmr0 input. Tmr0 input is connected thro a 470 ohm
;resistor to the freq source. Please note that the
;the input freq. is required to be a 50% duty cycle, square
;wave. Though none of the internal calculations are based
;on this requirement, wave forms which deviates drastically
;for the one specified were not tested using these routines.
;The routines written in this program, automatically measure
;waveforms from 50MHz to 50hz in a period of approx. 300 mS.
;After a period of approx 300 mS, the 16 bit "measured" value of
;the freq. is read and saved in the location "flo" and "fhi".
;A "range" flag is set to indicate if the measurement belongs to
;the five ranges measured namely:
; RANGE: Flag name
; 50MHz to 10MHz --> Mhz50to10
; 10MHz to 1MHz --> Mhz10to1
; 1MHz to 100kHz --> Khz1Kto100
; 100kHz to 10kHz --> Khz100to10
; 10kHz to 50Hz --> Hz10Kto50
;The freq. check is repeated to give approx 3 samples/sec.
;The "measured" value now has to go through a calculation to
;get the actual value. Please use the math routines mentioned
;elsewhere in the Embedded Control Handbook to determine
;the actual value of the freq.
;******************************************************************
;Calculations required to determine actual freq. values
;******************************************************************
;First determine which range flag is set, then calculate as follows:
;
; MHz50to10: freq. = (fhi|flo) X 1000
; MHz10to1: freq. = (fhi|flo) X 200
; kHz1kto100: freq. = (fhi|flo) X 20
; kHz100to10: freq. = (fhi|flo) X 5
; Hz10kto50: freq. = (fhi|flo) X 1
;
;
; Program: FREQ.ASM
; Revision Date:
; 1-16-97 Compatibility with MPASMWIN 1.40
;
;******************************************************************
;
;
; ********************************************************************
; Define General Purpose Registers (64 bytes maximum; 40h-7fh)
; Bank 0 Only
; ********************************************************************
;
fhi equ 0x40 ;high 8 bit value for freq.
flo equ 0x41 ;low 8 bit value for freq.
tempa equ 0x42
tempb equ 0x43
limithi equ 0x43
limitlo equ 0x42
count equ 0x43
;trisabuf equ 0x44
;InputCounthi equ 0x45
;InputCountlo equ 0x46
RangeFlag equ 0x44

binH equ fhi
binL equ flo
bcdH equ 0x45
bcdM equ 0x46
bcdL equ 0x47
counter equ 0x48
temp equ 0x49
IRF equ 0x4A
cn equ 0x4B
rs equ 0x4C
rxd equ 0x4D

#define Mhz50to10 RangeFlag,0
#define Mhz10to1 RangeFlag,1
#define Khz1Kto100 RangeFlag,2
#define Khz100to10 RangeFlag,3
#define Hz10Kto50 RangeFlag,4
#define RangeError RangeFlag,5
;
tenMhz equ .10000000/.1000
oneMhz equ .1000000/.200
hndredK equ .100000/.20
tenKhz equ .10000/.5
fiftyhz equ .50
;
btime equ 42h ;19200bps 16MHz時のウエイトタイム
;
;/////////////////////////////////////////////////////////////////
;
; マクロ定義
;
;/////////////////////////////////////////////////////////////////

enabletmr0 macro
BSF OPTION_REG,T0CS ;TMR0=Counter MODE
CLRF TMR2 ;TMR2=0
BCF INTCON,TMR0IF ;TMR0割り込みフラグクリア
BSF INTCON,TMR0IE ;TMR0割り込み許可
clrf TMR0
endm
;
disabletmr0 macro
BCF OPTION_REG,T0CS ;TMR0=Timer MODE
MOVF TMR0,W ;W=TMR0
BSF T2CON,TMR2ON ;TMR2=ON
endm
;
;/////////////////////////////////////////////////////////////////
;
; プログラムコード
;
;/////////////////////////////////////////////////////////////////

ORG 0x0000

goto INIT ;

ORG 0x0004 ;割り込みベクター

BCF T2CON,TMR2ON ;TMR2=OFF
BCF INTCON,TMR0IF ;TMR0割り込みフラグクリア
BSF IRF,0 ;割り込み完了フラグセット
RETFIE

; ********************************************************************
; データ領域
; ********************************************************************

MESMhz50to10 ; kHz
DW ' '*0x80+'k' ;
DW 'H'*0x80+'z' ;
MESCRLF
DW 0x0D*0x80+0x0A ;
DW 0 ;

MESMhz10to1 ;x200 Hz
DW 'x'*0x80+'2' ;
DW '0'*0x80+'0' ;
DW ' '*0x80+'H' ;
DW 'z'*0x80+0x0D ;
DW 0x0A*0x80+0 ;

MESKhz1Kto100 ;x20 Hz
DW 'x'*0x80+'2' ;
DW '0'*0x80+' ' ;
DW 'H'*0x80+'z' ;
DW 0x0D*0x80+0x0A ;
DW 0 ;

MESKhz100to10 ;x5 Hz
DW 'x'*0x80+'5' ;
DW ' '*0x80+'H' ;
DW 'z'*0x80+0x0D ;
DW 0x0A*0x80+0 ;

MESHz10Kto50 ; Hz
DW ' '*0x80+'H' ;
DW 'z'*0x80+0x0D ;
DW 0x0A*0x80+0 ;

MESRangeError ;RangeError
DW 'R'*0x80+'a' ;
DW 'n'*0x80+'g' ;
DW 'e'*0x80+'E' ;
DW 'r'*0x80+'r' ;
DW 'o'*0x80+'r' ;
DW 0x0D*0x80+0x0A ;
DW 0 ;

; ********************************************************************
; メインルーチン
; ********************************************************************

INIT
CLRF PORTA ;
CLRF LATA ;
CLRF ANSELA ;
MOVLW B'11111110' ;RA0のみ出力に設定
MOVWF TRISA ;RA0:TX RA1:CLKIN RA2:T0CKI PA3:RX

MOVLW B'00110111' ;TMR0=T0CKI,Prescale=265,H->Lでインクリメント
MOVWF OPTION_REG ;

MOVLW B'0000000' ;TMR2=OFF,Prescale=1,Postscale=1
MOVWF T2CON ;
MOVLW 0xFF ;PR2=0xFF
MOVWF PR2 ;

BSF INTCON,GIE ;グローバル割り込みを許可

repeat
enabletmr0 ;enable tmr0
call delay1mS ;wait for 1mS
disabletmr0 ;disable tmr0
call getfreq ;get freq in fhi and flo
call check10M ;check if <= 10 Mhz
btfss STATUS,Z ;yes then do lower freq.
goto Freq50Mto10M ;found 50Mhz to 10Mhz freq.
enabletmr0 ;enable tmr0
call delay5mS ;wait for 5mS
disabletmr0 ;disable tmr0
call getfreq ;get freq in fhi and flo
call check1M ;check if <= 1 Mhz
btfss STATUS,Z ;yes then do lower freq.
goto Freq10Mto1M ;else wait for 300 mS
enabletmr0 ;enable tmr0
call delay50mS ;wait for 50mS
disabletmr0 ;disable tmr0
call getfreq ;get freq in fhi and flo
call check100K ;check if <= 100 Khz
btfss STATUS,Z ;yes then do lower freq.
goto Freq1Mto100K ;else wait for 250 mS
enabletmr0 ;enable tmr0
call delay200mS ;wait for 200 mS
disabletmr0 ;disable tmr0
call getfreq ;get freq in fhi and flo
call check10K ;check if <= 10Khz
btfss STATUS,Z ;yes then do lower freq.
goto Freq100Kto10K ;else wait 50mS
enabletmr0 ;enable tmr0
call delay1S ;wait for 1S
disabletmr0 ;disable tmr0
call getfreq ;get freq in fhi and flo
call check50 ;check if <= 50hz
btfss STATUS,Z ;yes then do lower freq.
goto Freq10Kto50 ;else wait 50mS
OutofRange
clrf RangeFlag ;set error flag
bsf RangeError
goto wait50mS
;
;Check10M, check if the freq < 10 Mhz if yes then the z bit
;is set else it is cleared. This routine uses a generic routine
;checklimit, which check the value in fhi and flo to the ones
;in limithi and limitlo
check10M
movlw high tenMhz ;get hi value of 10Mhz
movwf limithi ;save in limithi
movlw low tenMhz ;get lo value of 10Mhz
movwf limitlo ;save in limitlo
;checklimit, checks if the freq in flo and fhi is lower
;than the values set in limitlo and limithi. It is a
;common routine used to check all set limits. If the value
;is <= the z bit = 0 else z = 1 .
checklimit
movf fhi,W ;get high freq value
subwf limithi,F ;and check with high value
btfsc STATUS,Z ;if not equal then skip
goto chk10Mlo ;else check low value
btfss STATUS,C ;skip if value is < limit
retlw 0 ;value > limit so z = 0.
clrw ;z = 1
retlw 0 ;return with z flag set
chk10Mlo
movf flo,W ;get low value
subwf limitlo,F ;and check with low value
btfsc STATUS,Z ;not equal then skip
retlw 0 ;else return with z = 1
btfss STATUS,C ;skip if value is < limit
retlw 0 ;value > limit so z = 0
clrw ;z = 1
retlw 0 ;return with z flag set
;
;Check1M checks if freq is below 1 MHz
;
check1M
movlw high oneMhz ;get hi value of 1MHz
movwf limithi ;save in limithi
movlw low oneMhz ;get lo value of 1MHz
movwf limitlo ;save in limitlo
goto checklimit
;
check100K
movlw high hndredK ;get hi value of 100KHz
movwf limithi ;save in limithi
movlw low hndredK ;get lo value of 100KHz
movwf limitlo ;save in limitlo
goto checklimit
;
check10K
movlw high tenKhz ;get hi value of 10KHz
movwf limithi ;save in limithi
movlw low tenKhz ;get lo value of 10KHz
movwf limitlo ;save in limitlo
goto checklimit
;
check50
movlw high fiftyhz ;get hi value of 50Hz
movwf limithi ;save in limithi
movlw low fiftyhz ;get lo value of 50Hz
movwf limitlo ;save in limitlo
goto checklimit
;
Freq50Mto10M
clrf RangeFlag
bsf Mhz50to10
goto wait300mS
Freq10Mto1M
clrf RangeFlag
bsf Mhz10to1
goto wait300mS
Freq1Mto100K
clrf RangeFlag
bsf Khz1Kto100
goto wait250mS
Freq100Kto10K
clrf RangeFlag
bsf Khz100to10
goto wait50mS
Freq10Kto50
clrf RangeFlag
bsf Hz10Kto50
goto wait50mS
;
wait300mS
call delay50mS
wait250mS
call delay50mS
call delay50mS
call delay50mS
call delay50mS
wait50mS
call delay50mS

BTFSS RangeError
GOTO DISP

MOVLW MESRangeError
CALL PUT2
goto repeat

DISP
CALL _bin2bcd ;BCD変換

MOVF bcdH,W ;
CALL H2B ;
SWAPF bcdM,W ;
CALL H2B ;
MOVF bcdM,W ;
CALL H2B ;
SWAPF bcdL,W ;
CALL H2B ;
MOVF bcdL,W ;
CALL H2B ;

BTFSC Mhz50to10
MOVLW MESMhz50to10
BTFSC Mhz10to1
MOVLW MESMhz10to1
BTFSC Khz1Kto100
MOVLW MESKhz1Kto100
BTFSC Khz100to10
MOVLW MESKhz100to10
BTFSC Hz10Kto50
MOVLW MESHz10Kto50
CALL PUT2
goto repeat

; ********************************************************************
; サブルーチン
; ********************************************************************

delay1S
call delay200mS ;+200000 us
call delay200mS ;+200000 us
call delay200mS ;+200000 us
call delay200mS ;+200000 us
delay200mS
call delay50mS ;+50000 us
call delay50mS ;+50000 us
call delay50mS ;+50000 us
delay50mS
call d10ms ;+10000 us
call d10ms ;+10000 us
call d10ms ;+10000 us
call d10ms ;+10000 us
d10ms
call delay5mS ;+5000 us
delay5mS
call delay1mS ;+1000 us
call delay1mS ;+1000 us
call delay1mS ;+1000 us
call delay1mS ;+1000 us
delay1mS
call d200us ;+200 us
call d200us ;+200 us
call d200us ;+200 us
call d200us ;+200 us
d200us
call d50us ;+50 us
call d50us ;+50 us
call d50us ;+50 us
d50us ;
movlw d'65' ;0.25 us
movwf tempb ;0.25 us
decfsz tempb,f ;0.25 us
goto $-1 ;0.5 us
return ;0.5 us total:0.25+0.25+(0.25+0.5)*65-0.25+0.5=24.5 us
;
getfreq ;TMR0とプリスケーラー値の取得
MOVWF fhi ;fhi=TMR0
CLRF IRF ;割り込み待ち
BTFSS IRF,0 ;
GOTO $-1 ;
BCF INTCON,TMR0IE ;TMR0割り込み禁止
COMF TMR2,W ;flo=/TMR2
MOVWF flo ;

MOVLW 0x04 ;補正値
ADDWF flo,F ;
BTFSC STATUS,C ;
INCF fhi,F ;
RETURN ;
;
H2B ;BCDデータをASCIIコードに変換して印字
ANDLW 0x0F ;
IORLW 0x30 ;
GOTO rs1tx ;
;
CRLF ;改行
MOVLW MESCRLF
PUT2 ;フラッシュデータメモリーから2文字出力
MOVWF PMADRL
CLRF PMADRH
LOOP_P
CALL rd
RLF PMDATL,W
RLF PMDATH,W
ANDLW B'01111111'
skpnz
RETURN
CALL rs1tx
MOVF PMDATL,W
ANDLW B'01111111'
skpnz
RETURN
CALL rs1tx
INCF PMADRL,F
GOTO LOOP_P
;
; 16-bit binary to BCD conversion ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; file register variables
; binH
; binL
; bcdH
; bcdM
; bcdL
; counter
; temp
; need to be defined elsewhere.
;
; binH, binL contain the binary value to
; convert. Conversion process destroys contents
; Result is in bcdH, bcdM, bcdL on return.
; Call _bin2bcd to perform conversion.
;
; Executes in 454 instructions
;
_bin2bcd
movlw d'16'
movwf counter
clrf bcdL
clrf bcdM
clrf bcdH
_repeat
rlf binL,F
rlf binH,F
rlf bcdL,F
rlf bcdM,F
rlf bcdH,F
decfsz counter,F
goto _adjust
return

_adjust
movlw d'14'
subwf counter,W
skpnc
goto _repeat
movf bcdL,W
addlw 0x33
movwf temp
movf bcdL,W
btfsc temp,3
addlw 0x03
btfsc temp,7
addlw 0x30
movwf bcdL
movf bcdM,W
addlw 0x33
movwf temp
movf bcdM,W
btfsc temp,3
addlw 0x03
btfsc temp,7
addlw 0x30
movwf bcdM
goto _repeat
;
; ********************************************************************
;
; RS-232C 1文字送信
;
; 送信文字を w にセットして呼ぶ
;
; ********************************************************************
rs1tx
movwf rxd ;rxd=W

#ifdef Direct
bsf PORTA,TX
#else
bcf PORTA,TX
#endif
call bwait ;スタートビット 1ビット分待つ
movlw 8 ;送信ビット数
movwf cn
r1tx11
rrf rxd,f

#ifdef Direct
btfsc STATUS,C
#else
btfss STATUS,C
#endif

bcf PORTA,TX ;

#ifdef Direct
btfss STATUS,C
#else
btfsc STATUS,C
#endif

bsf PORTA,TX
call bwait ;1ビットのウエイト
decfsz cn,f ;8ビット送信したか?
goto r1tx11 ;
call ret00 ;6サイクルウエイト (call+goto+return)

#ifdef Direct
BCF PORTA,TX
#else
BSF PORTA,TX
#endif

bwait ;1ビットのウエイトを作る
call bwait2 ; 1 us total:0.5+24.5+24.5=49.5us

bwait2 ;1/2ビットのウエイトを作る
movlw btime/2-2 ;0.25 us
movwf rs ;0.25 us
decfsz rs,f ;0.25 us
goto $-1 ;0.5 us
ret00
goto $+1 ;0.5 us
return ;0.5 us total:0.25+0.25+(0.25+0.5)*(33-2)-0.25+0.5+0.5=24.5us
;
; ********************************************************************
;
; フラッシュデータメモリー操作サブルーチン
;
; rd :PMADRで指定したアドレスのデータを読み出す。
; 結果はPMDATに保存される。
;
; wr_e :PMADRで指定したアドレスを含む16ワード境界のデータブロック
; (16ワード)を消去する。
; 例.PMADRH:PMADRL=0x0137のとき、0x0130~0x013Fを消去
;
; wr_w :PMADRで指定したアドレスのデータを書き込む。
; 書き込むデータはPMDATに予めセットしておく。
;
; ********************************************************************
rd
movlw b'00000001' ;CFGS=0 LWLO=0 FREE=0 WREN=0 RD=1
movwf PMCON1
nop
nop
return
wr_e
movlw b'00010100' ;CFGS=0 LWLO=0 FREE=1 WREN=1
goto $+2
wr_w
movlw b'00000100' ;CFGS=0 LWLO=0 FREE=0 WREN=1
movwf PMCON1
movlw 0x55
movwf PMCON2
movlw 0xaa
movwf PMCON2
bsf PMCON1,WR ;WR=1
nop
nop
clrf PMCON1 ;CFGS=0 LWLO=0 FREE=0 WREN=0
return

;*************************************************************
end













<HEXファイル>

:020000040000FA
:020000002428B2
:0800080013110B114A14090049
:100010006B107A248A060000323C301848100D3DDF
:100020000005323C20187A248A060000353C48102E
:100030000D3D000548100D3D000561296737C532AB
:100040007239F2378A060000850187018801FE3087
:10005000860037308E0000309300FF3092008B17FF
:100060008E1691010B118B168101DD208E12010875
:100070001315E9207420031D9C288E1691010B1185
:100080008B168101D9208E1201081315E9208820D2
:10009000031D9F288E1691010B118B168101D42010
:1000A0008E1201081315E9208D20031DA2288E163B
:1000B00091010B118B168101D1208E1201081315AD
:1000C000E9209220031DA5288E1691010B118B1695
:1000D0008101CD208E1201081315E9209720031D00
:1000E000A828C401C416B0282730C3001030C200AD
:1000F0004008C30203198028031C003403010034A4
:100100004108C20203190034031C00340301003407
:100110001330C3008830C20078281330C300883001
:10012000C20078280730C300D030C20078280030E1
:10013000C3003230C2007828C4014414AB28C40183
:10014000C414AB28C4014415AC28C401C415B0289C
:10015000C4014416B028D420D420D420D420D420E4
:10016000D420C41EB6281D30F920302809214508A6
:10017000F520460EF5204608F520470EF5204708E5
:10018000F52044180830C4180C3044191130C41933
:100190001630441A1A30F9203028D120D120D1202D
:1001A000D120D420D420D420D820D820D820D820A2
:1001B000D920DD20DD20DD20DD20E120E120E1204F
:1001C000E120E420E420E4204130C300C30BE62812
:1001D0000800C000CA014A1CEB288B121109C1009B
:1001E0000430C1070318C00A08000F3930382D2920
:1001F0000A30A000A1014321220D230D7F390319EC
:1002000008002D2122087F39031908002D21A00A9A
:10021000FB281030C800C701C601C501C10DC00DC3
:10022000C70DC60DC50DC80B162908000E304802B3
:1002300003180E294708333EC9004708C919033E71
:10024000C91B303EC7004608333EC9004608C919DD
:10025000033EC91B303EC6000E29CD0005143C21CB
:100260000830CB00CD0C03180510031C05143C21ED
:10027000CB0B3229412105103D211F30CC00CC0B86
:100280003F29422908000130A400000000000800B6
:1002900014304B290430A4005530A500AA30A50025
:0A02A000A41400000000A4010800EF
:02400E008138F7
:00000001FF






































.