AVR 109 :Frequency Counter


初めに!

周波数カウンタ  7セグメントLED2桁表示式の周波数カウンターです、簡単な表示用として作り始めました。
 CQ8月号に出ていた「AF ハイカットフイルター用の周波数カウンタです」まだLEDが表示したのを確認した程度で完成は少し先になるかも知れません(このフイルターのハードを知らないと意味が良く解らないと思いますが細かい説明は省略します。

 2桁の表示ですからあまり精度は必要ありません、「この程度でも使えれば良い!」と割切って使いたいと思います。

動作

 時間軸をタイマーで設定しその間の信号をカウントします。カウンターは9ビットで最高512までカウント出来ます。
 表示は空き時間を使って2つのLEDを交互に切替え、数字DATAをLEDのDATAに変換後LEDに転送して表示させています(前の2桁を表示として使っています)。

 2桁なので周波数精度は1/100程度取れれば問題はありません、発振は水晶では無くセラロック10MHzを使いました(実測私のは10.083MHzで0.8%の誤差になりました)、無調整で2桁の精度は十分保てそうです。

 トランジスタ(2SA1015*2)と制限抵抗値220ΩでICに接続します(手持ちを使った為)、新しいLEDなら470Ωでも十分明るく見えます。緑色とか黄色など色々売られているので好みの物を使って下さい、赤色が一番安くて発光効率は高いです。

 「300KHz程度が測定出来れば良い」と周波数はあまり高く有りません、周波数はVRで変化させる物で数字が出ると解り易い為です。
 もう少し「周波数が低いとMCUでコントロールというか作れる」のですが300KHzでは処理が間に合いません、一つだけなら何とか出ますが連続変化は無理です・・・。

 メインプログラムの流れ。
1. 初期設定をします。
2. 周波数の測定(ゲート時間は1mSで)。
3. 測定後、10進変換してLEDのDATAに変換します。
4. 0.3S(300mS)LEDを1mSごとに切替えて表示をします、1に戻る。


 誤差は有るのですが2桁表示なので、例えば[123 KHz]の場合12(100KHz/10KHz)が表示されます。D0にスイッチを付け押すと23(10KHz/1KHz)と表示させる事にしました(押している間だけ/無くても良い)。
 当然のことですが後ろの桁3は[2/3/4]が表示される可能性があります
 このセットは1%程度の誤差がありますが10MHzの水晶を使えば無調整で3桁表示の確度を保てます(念の為)、セラロックでも実測して周波数を合わせれば何とか使えると思いますがこのまま使う事にしました。

 製作する場合は[2桁 周波数カウンター]に情報を作り直しましたので実際に作る方はご覧下さい。

部品類

回路図  ICはAT90S1200を使っています、動作は回路図の様に簡単なのでコントローラーとして予定した物が出来ました。
 LEDはアノードコモンを使います、2桁続きならそのような物が廉く売られているので使うと簡単です。手持ちの物はDP(decimal point)が付いてないので1桁の物を2つ使いました。  基板も作らず何時もの小形な万能基板を使っています、見ての通り部品数も少なく簡単に出来ます。

 ただ、LEDの所は配線が込みあっています、足の配置は部品によって少し異なるので購入する時情報を得ます(LEDの端子で、回路図は省略してますがa.a等各端子間はパラに接続しています)。

 デジット・ライブは2SA1015を使いました、動作は2桁で約80mA程度流れます(220Ω時)ので5Vレギュレータは0.5A/1Aの物を使って下さい。13Vから落とすとかなの発熱するので78L05では持たないかも知れません(放熱すれば良いんですが!)。

 電源取り入れの所に直列に「47Ω程度の抵抗を入れ発熱させる」とICの加熱を分散する事が出来ます。
 この抵抗ですが(13V-7V)*0.08A=0.48Wが発熱するので1/4Wの抵抗では不安です(7VはICが必要としている電圧)、150Ω3本パラ又は220Ω4本パラで使って下さい。
 LEDはデジタル動作でノイズも多くその漏れに注意して使いたいと思います、必要ならノイズフィルターを電源回路に入れます(これは取り越し苦労で気にならなかったです)。
その後の結果 (これでは宣伝になっちゃうかなー!)

 組立ててAFフイルタに結線してみました。結果は2.5KHz以上はリグのフイルターがカットしているので音は変らず、2.2/2.0KHzと下げるとカリカリ聞えるQRMは削られ1.8KHzにするとほぼ完全に消えます。

 1.6/1.4KHz辺りがSSBでは限界の様で話の内容は聞えますが高い音が出ないので長い時間は聞きずらいです。
 1.2/1.0はこれは実際に聞いてもらった方が良いですね。
 CW用の1.0/0.8/0.7/0.6KHzは0.1KHz動かすとSSBフイルタでもばっさり切れ100Hzほど離れたQRM局を消してくれます(100Hzは少しOverかなーでも150Hz上ならバッチリ消えます)。
 QRMの局を消してその周波数と目的局が聞えなくなるまで周波数を下げると差の周波数がおよそですが100Hz単位で解ります(人によっては音だけでそんなのわかるかも知れませんが・・・!)。

 全体として周波数カウンタが付いていると今どの周波数になっているのか解るのでとても便利で安心です。これを一度使い出すと「カウンタが無い」のは考えられません。(2004/8/30)

 2004/AUG/6 - AUG/30 

;-------------------------------------------------
;Title	:LED type 2(or3)桁周波数カウンター[Max510KHz]
;	:10MHz ceramic resonator	[03FC_0822.asm]
;	:1mS Gate type	AT90S1200/2313
;	:BY JA1HWO @M.Kikuchi
;-------------------------------------------------
.include "C:\AVRTOOLS\APPNOTES\1200def.inc"

.equ	ledd1	=4		;D4 LED
.equ	ledd2	=5		;D5

.def	pre	=r2		;Timer0
.def	temp	=r16
.def	led_lc	=r17		;Loop Counter For LED
.def	cnt1	=r20		;Wait 1
.def	cnt2	=r21		;Wait 2
.def	divisor	=r22
.def	wark	=r23		;8Bit DATA
.def	warkl	=r24		;+1Bit
.def	warkh	=r25

.eseg			;EEPROM segment
.org	0		;read only
table1:
 	.db	$c0,$f9,$a4,$b0,$99,$92,$82,$f8 
	;digit	0   1   2   3   4   5   6   7
	.db	$80,$98,$ff,$ff,$ff,$ff,$ff,$ff
	;digit	8   9   a  b  c  d  e  f

.cseg			;code segment
.org	0
;-----------------------------------------------
;**** Interrupt Vector Address	****
	rjmp	begin		; Reset
	rjmp	c_up		; Ex 0(input PD-2)
	rjmp	Timer_set	; Timer 0
	reti			; Analog Comparator
begin:	ldi	temp,$ff	;B Port all output
	out	DDRB,temp	;
	ldi	temp,0b01111000	;D 0-2 input 3-7 Output
	out	DDRD,temp
	ldi	temp,0b01111011	;LED off & 0/1=pullup
	out	PortD,temp	;
	ldi	temp,0b00000010	;Ex0 interrupt Falling Edge
	out	MCUCR,temp	;
	ldi	temp,-156	;Timer0 1KHz
	mov	pre,temp
	out	TCNT0,pre	
main:				;Frequncy count
	clr	wark		;reset
	clr	warkl
	ldi	temp,3		;1/64 set & timer on
	out	TCCR0,temp	;64*156*0.1uS=998.4(0.16%)
	ldi	temp,2		;Timer interrupt on
	out	TIMSK,temp
	clt
	sei			;all interrupt on
main_f1:
	brts	main_f1		;Gate on?
	ldi	temp,0b01000000	;Bit6(0x40)
	out	GIMSK,temp	;ex0 interrupt on
main_f2:
	brtc	main_f2		;Gate off?
	cli			;stop interrupt
	clr	temp
	out	TCCR0,temp	;timer off

	rcall	bto10		;binary to BCD
	sbic	PinD,0		;PortD0=low to LED display shift
	rjmp	m2
	mov	warkh,wark
	mov	wark,warkl
m2:	clr	led_lc		;Loop counter reset
led_d1:
	cbi	PortD,ledd1	;LED1 on
	mov	temp,warkh
	out	EEAR,temp	;address set
	sbi	EECR,EERE
	in	temp,EEDR
	out	PortB,temp	;
	ldi	cnt1,255	;Wait 1mS
mw1:	ldi	cnt2,12
mw2:	dec	cnt2
	brne	mw2
	dec	cnt1
	brne	mw1
	sbi	PortD,ledd1	;LED1 off
led_d2:	cbi	PortD,ledd2	;LED2 on
	mov	temp,wark
	out	EEAR,temp	;address set
	sbi	EECR,EERE
	in	temp,EEDR
	out	PortB,temp	;
	ldi	cnt1,255	;Wait 1mS
mw3:	ldi	cnt2,12
mw4:	dec	cnt2
	brne	mw4
	dec	cnt1
	brne	mw3
	sbi	PortD,ledd2	;LED2 off
led_d3:				;Image LED3 on-off
	inc	led_lc
	cpi	led_lc,150	;150*2mS=0.3S
	brne	led_d1
	rjmp	main
;-----------------------------------------------
;wark(8bit DATA)+warkl(9bit) 
;binary 9bit(512) to BCD(10)
;warkh=100 wark=10 warkl=1 use temp/data 34=108ck
bto10:	clr	warkh
bto11:	cpi	wark,100	;100over_ck
	brlo	bto12		;lower
	subi	wark,100	;
	inc	warkh		;add 100
	rjmp	bto11		;loop ck repeat
bto12:	dec	warkl
	brne	bto13
	inc	warkh
	inc	warkh
	clr	warkl
	subi	wark,-56
	rjmp	bto11
bto13:	ldi	divisor,10	;10
	clr	warkl		;
	ldi	temp,9
d_1:	rol	wark
	dec	temp
	brne	d_2
	ret			;end
d_2:	rol	warkl
	sub	warkl,divisor
	brcc	d_3
	add	warkl,divisor
	clc
	rjmp	d_1
d_3:	sec
	rjmp	d_1
;-----------------------------------------------
Timer_set:
	out	TCNT0,pre	;1KHz
	brts	ts2
	set
	reti
ts2:	clt
	reti
;-------Ex0 Interrupt----------------------------
c_up:	inc	wark
	brne	c_2
	inc	warkl
c_2:	reti
;-----------------------------------------------
LEDのDATAを直接変換する

 この部分はEEPROMを使ってLEDのDATAに変換していた物を直接変換する様にしました。
 これによって、EEPROMが書き換わるという不安は解消されます(ICのロックビットをセットすれば書込みはされません)。

 具体的にはEEPROM読出し部分を削除して、次のプログラムを呼び出せば変換出来ます。プログラム自身もそう多くないので変更した物をVer 2としました。(2004/9/1)
 LED表示関係の所★印の3行を消してそこをrcallに変更します、led_d2:もまったく同じでこちらも変更します。

 EEPROM関係のプログラム.eseg以下から.cseg直前までのtable1:等は不要となります。
led_d1:
	cbi	PortD,ledd1	;LED1 on
	mov	temp,warkh
;★	out	EEAR,temp	;address set
;★	sbi	EECR,EERE
;★	in	temp,EEDR
	rcall	data_to		;
	out	PortB,ldata	;
	ldi	cnt1,255	;Wait 1mS
mw1:	ldi	cnt2,12

;-----------------------------------------------
;Data to LED 7DATA
data_to:
	ldi	ldata,$a3	;0
	cpi	temp,1
	brcs	dt_end
	brne	dt2
	ldi	ldata,$f9	;1
	rjmp	dt_end
dt2:	ldi	ldata,$a4	;2
	cpi	temp,3
	brcs	dt_end
	brne	dt3
	ldi	ldata,$b0	;3
	rjmp	dt_end
dt3:	ldi	ldata,$99	;4
	cpi	temp,5
	brcs	dt_end
	brne	dt4
	ldi	ldata,$92	;5
	rjmp	dt_end
dt4:	ldi	ldata,$82	;6
	cpi	temp,7
	brcs	dt_end
	brne	dt5
	ldi	ldata,$f8	;7
	rjmp	dt_end
dt5:	ldi	ldata,$80	;8
	cpi	temp,9
	brcs	dt_end
	brne	dt6
	ldi	ldata,$98	;9
	rjmp	dt_end
dt6:	ldi	ldata,$ff	;a-f
dt_end:	ret

[もどる]もどる  [MAIN MENU

inserted by FC2 system