新たな気持ちで再度 周波数カウンタ AVRでAT90S2313はタイマ/カウンタ(T/C)が2つ付いて(AT90S1200の一つ)片方で時間を決め、残りはカウントアップ用に使うと効率良く作動します。 この様な考えで以前トライしたのですが誤差が解決出来ず箱入りになっていました、最近また思い出して試して見る事にしました。 AVR 52でAT90S1200のカウンタで実験しましたが、これをベースにICを交換して試して見ました回路はほとんど同じ、SOFTもかなり流用しています。 結果は予想よりFBになり完璧では有りませんが概ね満足しています。 全体の動作 1]T/C0は周波数のカウントアップ用とする。 2]T/C1はゲート時間設定用です。 3]外部プリスケラは1/4としゲート時間を25Hzで動作させる事にしました、従って表示は100Hzとなります。 4]入力はT0(PD4)とし内蔵の8ビットプリスケラー(TCNT0)をそのまま使う事にしました。 5]ゲートを開けて割込み解除(T/C0でカウント開始)し、カウントアップを(16bitの合計24bit)させます(ゲートコントロールは今回もTフラッグを利用した)。 6]順次カウントアップを続け、ゲート終了後に割込みを禁止して結果を24bitのDATAにします。 7]数字DATAはBCD変換してLCDで表示します。 8]初期設定して5に戻りループとなる。 メインクロックの45%まで動作した 動作させた結果メインクロック10.24MHzで動かすと18.6000MHzまで動作しました、1/4のプリスケラー(74LS393のB出力使用、Cを使えば36MHz)が入っているので裸だと「4.6MHz」となります、これは約45%でAVRの実力としてはこんな物です。 12.8MHzの水晶(安価で正確なものが売られている)を使えばこの1.25倍で5.6MHzとなりミズホ通信のVFO-5が外部プリスケラー無しで周波数表示が出来る事になります。 (手元の12.8MHzは消費電流5mA流れる、水晶を使って内臓発振器で動作させればこれは節約出来ますから特に必要が無ければICで発振させた方がFBみたい。) AT90S1200の場合、T/Cが一つしかないのでゲート用に使い、後は直接入力とするので正確にカウント動作をしてくれる最高動作周波数が「0.56MHz」でした。 一方AT90S2313はタイマーとカウンタと2つ使いますが「4.6MHzまで行ける」のが今回の実験で判りました、PIC16F84には負けますがまあまあの線だと思います。 当初表示が少し狂っていたのですがT/C0の設定がまずかった様です、ここを修正し動き出しました(ホッとしています)。 表示誤差は最終桁が異なる程度(100Hz)です、ゲート時間を更に伸ばせば10Hzも問題なさそうです。後は少し使って細かい点を煮詰め完成度を上げたいと思います。 10Hzも試したのですが誤差が目立つので少しゲート時間を伸ばすべくWAITを入れて調整し18.00000まで表示させてみました。 もしかして AVR29で周波数カウンタを7MHzのリグに付けて表示させました、「同じAT90S2313なら今回の方が効率が良いので交換しょう」と思ったのです、所が動作周波数を見ると11.756MHzのフィルターでVFOは4.756-4.656MHzになっています、残念ながらわずかな所で周波数がオーバーしています。 このまま(裸で)動くのは前記の通りMax 4.6MHzですから、動作周波数を越えており取換えは出来ず少しがっかりしました。 当時はまだAVR知識もレベルが低かった、それでもそれなりにまとめた物で基本動作は同じです、私としては思いでもあり7MHzのリグは暫くそのまま使う事にしました。 AT90S2313はAT90S1200に比べると大幅に能力UPとなり(4.6/0.56=8.2倍)使い道が更に広がります、ICの値段も下がり気味ですからますます使いやすいデバイスになって来ました。 .include "fc10blw.inc" ;○BinBCD :binary to BCD/24bit ; BinLow,BinMid,BinHi-BCDr0,BCDr1,BCDr2,BCDr3/Btemp ;○lcd_dsp :dt=data :LCD program ; stemp1,stemp2(lcd_commd) ;○lcd_commd :dt=command ;○wait_5m :10MHz Wait w_cnt2/w_cnt1 以上は毎度おなじみのプログラムの為省略します。 2003/OCT/27 | ;Title :Freqencu counter for TR with 100Hz display ; New Fcounter [FC30] ;date :2003/10/21 10/24 BY JA1HWO ;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 ; PD4=T0 input ;----------------------------------------------- .def itpL = r3 ;for TCNT1 .def itpH = r4 ; .def r_0 = r5 ;0 .def r_1 = r6 ;1 .def Btemp = r7 .def int_on = r8 .def int_off = r9 .def t0_set = r10 .def Bbit24 = r11 ;temp .def temp = r16 ; .def stemp1 = r17 ;for LCD .def stemp2 = r18 .def dt = r19 ;for LCD .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 BinLow = r27 ; .def BinMid = r28 .def BinHi = r29 .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 out PortD,temp ldi temp,1 mov r_1,temp ;for count up clr r_0 out TCCR1A,r_0 ldi temp,3 ;T1 1/64 out TCCR1B,temp ldi temp,$e7 ;$e700=6400 mov itpH,temp out TCNT1H,itpH clr itpL out TCNT1L,itpL ldi temp,0 ;T0 off out TCCR0,temp ; 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 ;----------------------------------------------- rcall lcd_initalize ;LCD set & Test ldi dt,'J' rcall lcd_dsp ldi dt,'A' rcall lcd_dsp ldi dt,'1' rcall lcd_dsp ldi dt,'H' rcall lcd_dsp ldi dt,'W' rcall lcd_dsp ldi dt,'O' rcall lcd_dsp ldi temp,100 ;WAIT 0.5S be2: rcall wait_5m dec temp brne be2 sei ;all interrupt on ;----------------------------------------------- main: clr FC1 ;clear Frequncy data clr FC2 ; out TCNT0,FC1 ; m_2: brtc m_2 ;Gate ON? ldi temp,6 ;T0 input down check out TCCR0,temp ;T/C on out TIMSK,int_on ;timer Interrupt on m_3: brts m_3 ;Gate off? nop nop out TIMSK,int_off ;counter stop ldi temp,0 ; out TCCR0,temp ;T/C0 off 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/(64*6400)=40mS(25Hz) gate25: out TCNT1H,itpH out TCNT1L,itpL ;set brtc gate3 clt reti gate3: set reti ;*********************************************** ; 24bit binary to LCD display 6deg **,***.* ; PORTD 0=h then normal frequency counter. lcddata: in temp,TCNT0 ;read from frequency data mov BinLow,temp mov BinMid,FC1 mov BinHi,FC2 sbic PinD,0 ;SW check rjmp lcdda2 ;add or subtract hints ;*2- type:HF reciver (VFO-IF ) ldi temp,$0b ;VFO-9.0123=$1600B sub BinLow,temp ;if add ldi temp,$60 sbc BinMid,temp ;adc ldi temp,1 sbc BinHi,temp ;adc ;----------------------------------------------- lcdda2: rcall BinBCD ;binary to BCD ldi dt,$80 ;LCD address claer rcall lcd_commd ; mov dt,BCDr2 ; swap dt ; andi dt,$0f ;100.000/ brne lcdda3 ldi dt,$20 rjmp lcdda4 lcdda3: ori dt,$30 lcdda4: rcall lcd_dsp mov dt,BCDr2 ; andi dt,$0f ;10.000/ ori dt,$30 rcall lcd_dsp ;to LCD ldi dt,',' ;',' rcall lcd_dsp mov dt,BCDr1 ; swap dt ; andi dt,$0f ;1.000/ ori dt,$30 rcall lcd_dsp mov dt,BCDr1 ; andi dt,$0f ;100/ ori dt,$30 rcall lcd_dsp lcdmbk: mov dt,BCDr0 ; swap dt ;10/ andi dt,$0f ; ori dt,$30 rcall lcd_dsp sbic PinD,1 ;PortD 1=L then 1KHz rjmp lcdda5 ldi dt,' ' rcall lcd_dsp rcall lcd_dsp ret lcdda5: ;100Hz ldi dt,'.' ;'.' rcall lcd_dsp mov dt,BCDr0 ; andi dt,$0f ;1/ ori dt,$30 rcall lcd_dsp ret ;------------------------------------------- .include "fc10blw.inc" ;○BinBCD :binary to BCD/24bit ; BinLow,BinMid,BinHi-BCDr0,BCDr1,BCDr2,BCDr3/Btemp ;○lcd_dsp :dt=data :LCD program ; stemp1,stemp2(lcd_commd) ;○lcd_commd :dt=command ;○wait_5m :10MHz Wait w_cnt2/w_cnt1 |
もどる [MAIN MENU]