AVR 115 :周波数カウンタX


周波数カウンタX (少し改良)

 以前の[周波数カウンタW(avr91)]の表示は10Hz単位だったが、ソフトを見直しゲート時間を10倍にして最低周波数を1Hz単位としてみた(切替え使用出来る)。
 これ自体あまりメリットは無いが(精度が取れない為)念の為数字を出せる様にした。
 表示は24Bit処理で16.7**.***と8桁まで出せるが基準周波数を10Hzまで合わせ込む事はアマチュアにはかなり難しい、更にその1桁下の1Hzまで出しても意味が無いかも!

節電対策
 消費電流はノーマル状態で約22mA流れていたので節電する為、周波数を測らない時はスリープ状態にすることを考え、乾電池(006P等)の動作を考えてみた。
 方法は色々考えられるがメモリースイッチを付け、これが押されたら現在の状態を表示して「スリープ状態にさせる」事にした。トランジスタも4mAほど食うのでこれもOFFさせる回路が必要になる。
 これぐらいなら直接ICに流し込めるので直接コントロールする事にした、これで部品も減って一石二鳥という所でしょうか。

 結局、スリープ状態にさせる(ボタンを押す)と消費電流は[ 0.82mA ]となった。これは3端子レギュレータとLCDユニット(古い物)が生きている為です。
 測定時だけ電気を食うので(19-26mA)乾電池でも問題なく作動する、普通「測定した結果を見て、考えている」事が多い。(16MHzを加えると結構消費する)

問題点
 今回の実験では「周波数カウンタとしては最大16.7MHzまでしか作動しません」が日常の実験は発振などの実験に使いたいと思います(内部は18MHzまで動作するのですが24Bit処理の為それ以上はリセットされてしまいます)。
 1/10のプリスケラを入れて160MHzまで使える様にすると使い易いかも知れませんが、その手の物は外に持っているのであまり興味はありません。
 適当なケースに入れて、使ってみたいと思っています。
 ハードは次の所を変更
○プリスケラーとして74LS393を1/4として使っていたのを74HC43に変更、これで10mA程度減って現在の状態になった。
○入力回路のTRからの流れ出しをICに直接接続してコントロールする。(PD5)

 再スタートはボタンを付けず電源を一度切ってから再起動する方式とした、これによって再起動のボタンは不要。
 ただ、再起動には数秒の待ち時間が無いと誤動作する事もある(リセットICが付いてないので仕方ない!)。

 ソフトの変更
○ゲート時間に0.4Sの外、スイッチによって4Sモードを追加(この程度までは我慢出来る?)。
○スイッチは以前「IFの補正」用に使っていたが関連を削除した(カウンタ専用とした)。
○桁数が多くなったので表示位置を変更した。0.4Sの時はDATAを10倍して桁位置を同じにした。

 節電として
○パワーダウンモードの設定、TRのON設定及び[MCUCRに$30]を設定する。
○TRをOFFする為I/O(PortD5)をHに設定、LCDにホールドの印し[*]を描き、SLEEPコマンドを挿入して表示以外は停止させる。
 この時LCDが少し消費していたので端子を(PortB)入力に設定したら画面が黒くなってしまった。どうもENBをHレベルにした為だった様でここだけLにして一件落着、これを入れないと1.4mA流れていた。現在0.82mAですから0.6mAよけいに流れていた。

 include File(fc30bl.inc)は使用レジスタをgr1.gr2.gr3に変更した物、外は同じ24bit、LCD関係がここに集めてある、これは毎回おなじ様なプログラム。

 2005/JAN/22 

プログラムプログラム(続き)

---------------------------------------------------------------
;Title	:Freqencu counter	[FC32]
;date	:2005/1/20	BY JA1HWO
;	:with 1/4Pre Counter	:Gate 0.4S/4S
;MCU	:AT90S2313+10.24MHz
;-----------------------------------------------
.include "C:\AVRTOOLS\APPNOTES\2313def.inc"
.cseg				;code segment
.org	0

.equ	lcd_enb	= 2	;PB2
.equ	lcd_rs	= 3	;PB3
;-----------------------------------------------
.def	gb1	= r2		;gr1-3 backup
.def	gb2	= r3
.def	gb3	= r4
.def	r_0	= r5		;0
.def	r_1	= r6		;1
.def	Btemp	= r7
.def	int_on	= r8
.def	int_off	= r9

.def	temp	= r16		;
.def	gr1	= r17		;for LCD
.def	gr2	= r18
.def	gr3	= r19		;
.def	w_cnt1	= r20		;for wait
.def	w_cnt2	= r21
.def	BCDr0	= r23		;digit0,1
.def	BCDr1	= r24		;digit2,3
.def	BCDr2	= r25		;digit4,5
.def	BCDr3	= r26		;digit6,7
.def	itpL	= r27		;for TCNT1
.def	itpH	= r28		;
.def	FC1	= r30		;F DATA
.def	FC2	= r31
;**** Vector Address ****
	rjmp	begin		;Reset handle
	reti			;ex Interrupt 0
	reti			;ex Interrupt 1
	reti			;Input Capture1 Interrupt
	reti			;Output Compare1 Interrupt
	rjmp	gate25		;Overflow1
	rjmp	fc_up		;Overflow0
	reti			;UART Receive Complete
	reti			;UART Data Register Empty
	reti			;UART Transmit Complete
	reti			;Analog Comparator
begin:	ldi	temp,LOW(RAMEND)
	out	SPL,temp	;RAM
	ldi	temp,$ff	;B Port all output
	out	DDRB,temp	;
	ldi	temp,0b01100000	;1=output / 0=input
	out	DDRD,temp	;
	ldi	temp,0b00001111	;pull up & PD5=L
	out	PortD,temp
	ldi	temp,1
	mov	r_1,temp	;for count up
	clr	r_0
	out	TCCR1A,r_0
	ldi	temp,5		;T1 1/1024
	out	TCCR1B,temp
	ldi	temp,0		;T0 off
	out	TCCR0,temp
	ldi	temp,$30	;Sleep set
	out	MCUCR,temp
	sbi	ACSR,ACD	;AComparator OFF
;-----------------------------------------------
	rcall	lcd_initalize	;LCD set & Test
	ldi	gr3,'J'
	rcall	lcd_dsp
	ldi	gr3,'A'
	rcall	lcd_dsp
	ldi	gr3,'1'
	rcall	lcd_dsp
	ldi	gr3,'H'
	rcall	lcd_dsp
	ldi	gr3,'W'
	rcall	lcd_dsp
	ldi	gr3,'O'
	rcall	lcd_dsp
	ldi	temp,100	;WAIT 0.5S
be2:	rcall	wait_5m
	dec	temp
	brne	be2
	ldi	temp,$82	;bit 7(T1)+2(T0)
	mov	int_on,temp
	ldi	temp,$80	;t0=count UP
	mov	int_off,temp
	out	TIMSK,int_off	;16bit timer on/fcount off
	sei			;all interrupt on
;-----------------------------------------------
main:	sbic	PinD,1		;SW check
	rjmp	main_0
	sbi	PortD,5		;TR OFF
	ldi	gr3,'*'
	rcall	lcd_dsp
	ldi	temp,0b00000100	;enable PB2
	out	DDRB,temp	;PortB=input
	ldi	temp,0
	out	PortB,temp	;Tri-state (Hi-Z)
	sleep
main_0:	clr	FC1		;clear Frequncy data
	clr	FC2
	out	TCNT0,FC1
	ldi	temp,$ff	;set
	out	TCNT1H,temp
	out	TCNT1L,temp
	ldi	itpH,high(-4000)	;10.24/(1024*4000)=0.4S(dsp=10Hz)
	ldi	itpL,low(-4000)	
	sbic	PinD,0		;SW check
	rjmp	m_2
	ldi	itpH,high(-40000)
	ldi	itpL,low(-40000)	;10.24/(1024*40000)=4S(dsp=1Hz)
m_2:	brtc	m_2		;Gate ON?
	ldi	temp,6		;T0 input down check
	out	TCCR0,temp	;T/C0 on
	out	TIMSK,int_on	;timer Interrupt on
m_3:	brts	m_3		;Gate off?
	ldi	temp,0		;
	out	TCCR0,temp	;T/C0 off
	out	TIMSK,int_off	;counter stop
	rcall	lcddata		;DATA to LCD display
	rjmp	main
;-----------------------------------------------
; Timer-0 Interrupt:count UP	
fc_up:	adiw	FC1,1
	reti
;-----------------------------------------------
; Timer-1 Interrupt:GATE
; 	10.24/(1024*4000/40000)=0.4or4S
gate25:	out	TCNT1H,itpH
	out	TCNT1L,itpL	;set
	brtc	gate3
	clt
	reti
gate3:	set
	reti
;-----------------------------------------------
;	10MHz 0.05mS	5mS
wait_50u:			;40uS over
	ldi	w_cnt2,1
	rjmp	wait_51
wait_5m:ldi	w_cnt2,100	;0.05mS*100=5mS
wait_51:ldi	w_cnt1,125	;4*125*0.1uS=50uS(0.05mS)
wait_52:nop
	dec	w_cnt1
	brne	wait_52
	dec	w_cnt2
	brne	wait_51
	ret

;********************************************************
; 24bit  binary to LCD display 8deg **,***.***
; PORTD 0=H then 10Hz counter display. 0=L then 1Hz counter.
; Max 16,777.215 Hz
lcddata:
	in	temp,TCNT0	;read from frequency data
	mov	gr1,temp
	mov	gr2,FC1
	mov	gr3,FC2
	sbis	PinD,0		;SW check
	rjmp	lcd2
	lsl	gr1		;*2
	rol	gr2
	rol	gr3
	mov	gb1,gr1		;keeps data
	mov	gb2,gr2
	mov	gb3,gr3
	lsl	gr1		;*4
	rol	gr2
	rol	gr3
	lsl	gr1		;*8
	rol	gr2
	rol	gr3
	add	gr1,gb1		;8+2
	adc	gr2,gb2
	adc	gr3,gb3
;-----------------------------------------------
lcd2:	rcall	BinBCD		;binary to BCD
	ldi	gr3,$80		;LCD address claer
	rcall	lcd_commd	;
;
	mov	gr3,BCDr3	;10MHz
	swap	gr3
	andi	gr3,$0f
	brne	lcd3
	ldi	gr3,$20
	rjmp	lcd4
lcd3:	ori	gr3,$30
lcd4:	rcall	lcd_dsp
	mov	gr3,BCDr3	;1MHz
	andi	gr3,$0f
	ori	gr3,$30
	rcall	lcd_dsp
	ldi	gr3,','		;','
	rcall	lcd_dsp
	mov	gr3,BCDr2	;100kHz
	swap	gr3
	andi	gr3,$0f
	ori	gr3,$30
	rcall	lcd_dsp
	mov	gr3,BCDr2	;10kHz
	andi	gr3,$0f
	ori	gr3,$30
	rcall	lcd_dsp
	mov	gr3,BCDr1	;1kHz
	swap	gr3
	andi	gr3,$0f
	ori	gr3,$30
	rcall	lcd_dsp
	ldi	gr3,'.'		;'.'
	rcall	lcd_dsp
	mov	gr3,BCDr1	;100Hz
	andi	gr3,$0f
	ori	gr3,$30
	rcall	lcd_dsp
;
	ldi	gr3,$c0		;LCD address set
	rcall	lcd_commd	;
	mov	gr3,BCDr0	;10Hz
	swap	gr3
	andi	gr3,$0f
	ori	gr3,$30
	rcall	lcd_dsp
	sbic	PinD,0		;SW check
	rjmp	lcde
	mov	gr3,BCDr0	;1Hz
	andi	gr3,$0f
	ori	gr3,$30
	rcall	lcd_dsp
lcde:	ldi	gr3,' '		;' Hz '
	rcall	lcd_dsp
	ldi	gr3,'H'		;
	rcall	lcd_dsp
	ldi	gr3,'z'		;
	rcall	lcd_dsp
	ldi	gr3,' '		;
	rcall	lcd_dsp
	ret
;-------------------------------------------
.include "fc30bl.inc"
; BinBCD	:binary to BCD/24bit
;	gr1,gr2,gr3 to BCDr0,BCDr1,BCDr2,BCDr3/Btemp
; lcd_dsp	:gr3=data	:LCD program
;		 gr1,gr2(lcd_commd)
; lcd_commd	:gr3=command
;-------------------------------------------

;以下 "fc30bl.inc"分
;-------------------------------------------
; BinBCD	:binary to BCD
; lcd_dsp	:gr3=data	:LCD program
; lcd_commd	:gr3=command
;	2002/11/11	 BY M.kikuchi
;*****  binary to BCD ****************************
; use temp Btemp:	Max 16777215
; gr1,gr2,gr3 to BCDr0,BCDr1,BCDr2,BCDr3
BinBCD:
	ldi	temp,24	;24 bit
	clr	BCDr0	;1,10digit
	clr	BCDr1	;100,1000
	clr	BCDr2	;10000,100000
	clr	BCDr3	;1000000,10000000
BinBCD2:
	lsl	gr1
	rol	gr2
	rol	gr3
	rol	BCDr0
	rol	BCDr1
	rol	BCDr2
	rol	BCDr3
	dec	temp
	brne	BinBCD3
	ret
BinBCD3:
	mov	Btemp,BCDr3
	subi	BCDr3,-3	;add	$03
	sbrs	BCDr3,3
	mov	BCDr3,Btemp
	mov	Btemp,BCDr3
	subi	BCDr3,-$30	;add	$30
	sbrs	BCDr3,7
	mov	BCDr3,Btemp

	mov	Btemp,BCDr2
	subi	BCDr2,-3	;add	$03
	sbrs	BCDr2,3
	mov	BCDr2,Btemp
	mov	Btemp,BCDr2
	subi	BCDr2,-$30	;add	$30
	sbrs	BCDr2,7
	mov	BCDr2,Btemp

	mov	Btemp,BCDr1
	subi	BCDr1,-3	;add	$03
	sbrs	BCDr1,3
	mov	BCDr1,Btemp
	mov	Btemp,BCDr1
	subi	BCDr1,-$30	;add	$30
	sbrs	BCDr1,7
	mov	BCDr1,Btemp

	mov	Btemp,BCDr0
	subi	BCDr0,-3	;add	$03
	sbrs	BCDr0,3
	mov	BCDr0,Btemp
	mov	Btemp,BCDr0
	subi	BCDr0,-$30	;add	$30
	sbrs	BCDr0,7
	mov	BCDr0,Btemp
	rjmp	BinBCD2
;-----------------------------------------------
;* LCD program
;register	gr1,gr2,gr3
;wait_50u	:50uS	Wait
;wait_5m	:5mS	Wait
;lcd_dsp	:gr3=data
;lcd_commd	:gr3=command
;	lcd_enb	= 2	;PB2
;	lcd_rs	= 3	:PB3
;	lcd db0~3	:Free
;	lcd db4~7	:PB4~7
lcd_dsp:
	sbi	PORTB,lcd_rs	; lcd rs set
lcd_commd:
	in	gr1,PORTB	; lcd db4~7 clear
	andi	gr1,$0f
	mov	gr2,gr3	; lcd data bit4~7 set
	andi	gr2,$f0
	or	gr1,gr2
	out	PORTB,gr1	; lcd data bit4~7 out
	sbi	PORTB,lcd_enb	; lcd enb set
	nop			; over 450ns
	swap	gr3
	mov	gr2,gr3	; lcd data bit0~3 set
	andi	gr2,$f0
	swap	gr3
	cbi	PORTB,lcd_enb	; lcd enb reset
	in	gr1,PORTB	; lcd db4~7 clear
	andi	gr1,$0f
	or	gr1,gr2	; lcd data bit0~3 out
	rcall	lcd_in2
	in	gr1,PORTB	; lcd db4~7 rs enb clear
	andi	gr1,$03
	out	PORTB,gr1
	rjmp	wait_50u
lcd_initalize:
	rcall	wait_5m		; 15mS
	rcall	wait_5m
	rcall	wait_5m
	ldi	gr1,$30	; 8bit
	rcall	lcd_in2
	rcall	wait_5m
	ldi	gr1,$20	; 4bit
	rcall	lcd_in2
	ldi	gr3,$28		; LCD 2line
	rcall	lcd_commd
	ldi	gr3,$01		; LCD all clear
	rcall	lcd_commd
	rcall	wait_5m
	ldi	gr3,$0c		; c
	rcall	lcd_commd
	ldi	gr3,$06		; c
	rjmp	lcd_commd	;
lcd_in2:
	out	PORTB,gr1	; 140ns
	nop
	nop
	sbi	PORTB,lcd_enb	;enable H=active/on
	nop			;450ns over
	nop
	nop
	nop
	nop
	cbi	PORTB,lcd_enb	;off
	ret
;-----------------------------------------------

[もどる]もどる  [MAIN MENU

inserted by FC2 system