' $prog &HFF , &HE0 , &HDF 'CKDIV8 = 1 , SUT = 10 , CKSEL = 0000 ' ' ' *************************************************** ' * * ' * 精度アップ * ' * レシプロカル式 周波数カウンター 3 プログラム * ' * * ' * AVR is using ATtiny2313 * ' * Basic Compiler is BASCOM-AVR * ' * Copyright By O-Family 2011. 1.28 * ' *************************************************** ' ' Ver 3.01 初回公開バージョン。2011. 1.10 ' Ver 3.02 ヒューズの自動書き込みを修正。2011. 1.28 ' ' Const Prgver = "03.02" 'プログラム・バージョン。 ' ' $regfile = "ATtiny2313.DAT" '使用するAVRを設定。 $crystal = 12800000 'AVRクロックを設定。 ' $hwstack = 64 'ハードウェア・スタックの容量を設定。 $swstack = 10 'ソフトウェア・スタックの容量を設定。 $framesize = 28 'フレーム領域の容量を設定。 ' $baud = 9600 'ハードウェアUARTの通信速度(ボーレート)を設定。 ' ' Pfrq_100 Alias Pinb.4 '[H100]プリスケーラ周波数検知の100Hz入力ポート。 Pfrq_b0 Alias Portd.2 '[PFb0]プリスケーラの選択ビット[0]。 Pfrq_b1 Alias Portb.3 '[PFb1]プリスケーラの選択ビット[1]。 M1hz Alias Pinb.2 '[M1Hz]測定周期信号(1.24 , 5Hz)の入力ポート。 Hc74_res Alias Portb.1 '[tPB1]入力信号確認ラッチのリセットポート。 Hc74_q Alias Pinb.0 '[tPB0]入力信号確認ラッチの出力ポート。 ' ' Dim Capmode As Byte 'キャプチャー割り込みの動作モード。 Dim Capendf As Byte 'キャプチャー計測完了フラグ。 Dim Capdat1 As Word 'キャプチャー・レジスター値 バッファー1。 Dim Capovf1 As Word 'オーバーフロー・カウント値 バッファー1。 Dim Capdat2 As Word 'キャプチャー・レジスター値 バッファー2。 Dim Capovf2 As Word 'オーバーフロー・カウント値 バッファー2。 Dim Capovfc As Word 'オーバーフロー・カウンター。 ' Dim Frqdat As Long 'キャプチャー・データを差分計算したカウント値。 Dim Frqdat0 As Byte At Frqdat + 0 Overlay 'バイト型に名前を重複させる。 Dim Frqdat1 As Byte At Frqdat + 1 Overlay Dim Frqdat2 As Byte At Frqdat + 2 Overlay Dim Frqdat3 As Byte At Frqdat + 3 Overlay ' Dim Pfrqcont As Byte 'プリスケーラ周波数検知制御フラグ。 Dim Pfrqovf As Byte 'プリスケーラ周波数検知オーバーフロー数。 Dim M1hzcont As Byte '測定周期のカウントフラグ。 ' Dim Temp1 As Byte '汎用テンポラリ変数 Byte型 No.1 Dim Temp2 As Byte '汎用テンポラリ変数 Byte型 No.2 Dim Tempw1 As Word '汎用テンポラリ変数 Word型 No.1 ' ' ' ' * ポートの初期設定 * ' Config Pfrq_b0 = Output 'プリスケーラの選択ビット[0]を出力に設定する。 Config Pfrq_b1 = Output 'プリスケーラの選択ビット[1]を出力に設定する。 Config Hc74_res = Output '入力信号確認ラッチのリセットを出力に設定する。 Set Porta.1 '未使用ポートをプルアップ。 Set Portd.3 '未使用ポートをプルアップ。 Set Portb.5 '未使用ポートをプルアップ。 Set Portb.6 '未使用ポートをプルアップ。 Set Portb.7 '未使用ポートをプルアップ。 ' ' * タイマーの設定 * ' Config Timer0 = Counter , Edge = Falling 'プリスケーラの周波数検知用カウンター。 ' Config Timer1 = Counter , Edge = Falling , Capture Edge = Rising '[T1]の立ち上がりエッジでカウント。 On Capture1 Tintcap Nosave 'キャプチャー割り込みルーチンのラベルを設定。 Enable Capture1 'キャプチャー割り込みを許可。 On Timer1 Tintovf Nosave 'オーバーフロー割り込みルーチンのラベルを設定。 Enable Timer1 'オーバーフロー割り込みを許可。 ' ' * 変数の初期設定 * ' Pfrqcont = 0 Pfrqovf = 0 Capmode = 0 Capendf = 0 M1hzcont = 0 Reset Hc74_res '入力信号確認ラッチをリセットする。 Set Hc74_res Enable Interrupts 'すべての割り込みを許可。 ' ' ******************* ' * メイン ルーチン * ' ******************* ' Main: ' ' * プリスケーラ(1/100)の周波数を測定する * ' Select Case Pfrqcont Case 0 : '100Hzの[L]を検知する。 If Pfrq_100 = 0 Then 'If 100Hzパルスが[L]か? Then Pfrqcont = 1 End If Case 1 : '100Hzの[H]を検知する。 If Pfrq_100 = 1 Then 'If 100Hzパルスが[H]か? Then Pfrqcont = 2 Timer0 = 0 'Timer0を初期化する。 Pfrqovf = 0 Set Tifr.tov0 'Timer0 オーバーフローフラグをリセット。 End If Case 2 : '100Hzの[L]を検知する。 If Pfrq_100 = 0 Then 'If 100Hzパルスが[L]か? Then Pfrqcont = 3 End If Case 3: '100Hzの[H]を検知する。 If Pfrq_100 = 1 Then 'If 100Hzパルスが[H]か? Then Pfrqcont = 0 Temp1 = Timer0 'プリスケーラ(1/100)の周波数を算出する。 Tempw1 = Makeint(temp1 , Pfrqovf) ' Select Case Tempw1 '周波数によってプリスケーラの選択ビットを制御する。 Case Is < 512 : '5.12MHz未満。 Reset Pfrq_b0 Reset Pfrq_b1 Case Is < 5100 : '51MHz未満。 Set Pfrq_b0 Reset Pfrq_b1 Case Else : '51MHz以上。 Reset Pfrq_b0 Set Pfrq_b1 End Select End If End Select ' If Tifr.tov0 = 1 Then 'If Timer0がオーバーフローしたか? Then Set Tifr.tov0 'Timer0 オーバーフローフラグをリセット。 Pfrqovf = Pfrqovf + 1 'オーバーフローカウントを加算する。 End If ' ' * 無信号のチェック * ' If M1hzcont = 0 Then 'If 測定周期の立ち上がりエッジ検出か? Then If M1hz = 1 Then 'If 測定周期の立ち上がりエッジか? Then M1hzcont = 1 Temp1 = Hc74_q Reset Hc74_res '入力信号確認ラッチをリセットする。 Set Hc74_res If Temp1 = 0 Then 'If 入力信号が無いか? Then Print "0" '信号無しを送信する。 End If End If Else If M1hz = 0 Then 'If 測定周期の立ち下がりエッジか? Then M1hzcont = 0 End If End If ' ' * キャプチャー計測後、Mega88へ回数データを送信する * ' If Capendf = 0 Then Goto Main 'If キャプチャー計測が完了したか? Else ' Gosub Capsubt 'キャプチャー・バッファーの値を差分計算する。=> (Frqdat) Capendf = 0 ' Temp1 = 0 Main1: If Capendf <> 0 Then Goto Main2 'If タイムアウトが発生したか? Then Temp2 = Inkey() If Temp2 <> &H02 Then Goto Main1 'If [STX]を受信したか? else ' Select Case Temp1 '送信データを準備する。 Case 0 : Temp2 = Frqdat0 Case 1 : Temp2 = Frqdat1 Case 2 : Temp2 = Frqdat2 Case 3 : Temp2 = Frqdat3 End Select ' Printbin Temp2 'データを送信する。 Temp1 = Temp1 + 1 If Temp1 < 4 Then Goto Main1 'If データの送信が終了か? Else ' Main2: Pfrqcont = 0 Goto Main ' ' ********************************************************** ' * キャプチャー・バッファーの値を差分計算するサブルーチン * 差分カウント値 => Frqdat(ロング型) ' ********************************************************** ' Capsubt: $asm LDS R24,{Capendf} 'キャプチャー・バッファーの使用状況を調べる。 SBRC R24,0 'バッファー1が測定終了データか? Then RJMP Capsubt1 ; LDS R16,{capdat1} '32bit引き算(バッファー2)−(バッファー1)。 LDS R17,{capdat1+1} LDS R18,{capovf1} LDS R19,{capovf1+1} LDS R20,{capdat2} LDS R21,{capdat2+1} LDS R22,{capovf2} LDS R23,{capovf2+1} RJMP Capsubt2 ; Capsubt1: LDS R16,{capdat2} '32bit引き算(バッファー1)−(バッファー2)。 LDS R17,{capdat2+1} LDS R18,{capovf2} LDS R19,{capovf2+1} LDS R20,{capdat1} LDS R21,{capdat1+1} LDS R22,{capovf1} LDS R23,{capovf1+1} ; Capsubt2: Sub R20 , R16 '32bit引き算。 SBC R21,R17 SBC R22,R18 SBC R23,R19 STS {Frqdat},R20 '計算結果をロング型変数に格納。 STS {Frqdat+1},R21 STS {Frqdat+2},R22 STS {Frqdat+3},R23 $end Asm Return ' ' ******************************************** ' * Timer1 キャプチャー 割り込み処理ルーチン * ' ******************************************** ' Tintcap: $asm PUSH R1 IN R1,SREG 'ステータス・レジスタを待避。 PUSH R22 PUSH R23 'R23は、拡張I/Oレジスタへのアクセスに使用する。 PUSH R24 PUSH R25 ; LDS R22,{Capendf} 'メインルーチンの処理状態をチェック。 CPI R22,0 BREQ Tintcap1 'If メインルーチンでキャプチャー・データの処理が終了しているか? Else JMP Tintcap8 ; Tintcap1: IN R24,ICR1L 'キャプチャー・レジスターの下位バイトを取得。 IN R23,ICR1H 'キャプチャー・レジスターの上位バイトを取得。 ; LDS R22,{Capmode} 'キャプチャー割り込みのモードを調べる。 SBRC R22,0 'If データ・バッファー2 へ書き込み? Then RJMP Tintcap2 ; ; '---<データ・バッファー1 書き込み処理>--- STS {Capdat1},R24 'データ・バッファー1へ保存。 STS {Capdat1+1},R23 ; LDS R24,{Capovfc} 'オーバーフロー・カウント値を取得。 LDS R25,{Capovfc+1} CPI R23,0 BRNE Tintcap3 'If キャプチャー・データの上位バイトが00? Else ; IN R23,TIFR SBRS R23,TOV1 'オーバーフローが発生しているか? Else RJMP Tintcap3 ; ADIW R24,1 'オーバーフロー・カウント値を+1 ; Tintcap3: STS {Capovf1},R24 'データ・バッファー1へ保存。 STS {Capovf1+1},R25 ORI R22,&H01 'モードをデータ・バッファー2 書き込みに変更。 RJMP Tintcap5 ; ; Tintcap2: '---<データ・バッファー2 書き込み処理>--- STS {Capdat2},R24 'データ・バッファー2へ保存。 STS {Capdat2+1},R23 ; LDS R24,{Capovfc} 'オーバーフロー・カウント値を取得。 LDS R25,{Capovfc+1} CPI R23,0 BRNE Tintcap4 'If キャプチャー・データの上位バイトが00? Else ; IN R23,TIFR SBRS R23,TOV1 'オーバーフローが発生しているか? Else RJMP Tintcap4 ; ADIW R24,1 'オーバーフロー・カウント値を+1 ; Tintcap4: STS {Capovf2},R24 'データ・バッファー2へ保存。 STS {Capovf2+1},R25 ANDI R22,&HF0 'モードをデータ・バッファー1 書き込みに変更。 ; ; Tintcap5: CPI R22,&H10 BRCC Tintcap6 'If 1と2の両バッファーにデータの準備が完了か? Then ORI R22,&H10 'キャプチャー・モードを2つめのデータ待ちにセット。 RJMP Tintcap7 ; Tintcap6: STS {Capendf},R22 'キャプチャー計測完了フラグをセット。 Tintcap7: STS {Capmode},R22 'キャプチャー・モードを更新。 ; POP R25 POP R24 POP R23 POP R22 Out Sreg , R1 'ステータス・レジスタを復帰 POP R1 $end Asm Return ' ' $asm Tintcap8: 'メインルーチンでキャプチャー・データの処理が終わっていない。 LDI R22,0 'キャプチャー・モードを初期化する。 RJMP Tintcap7 $end Asm ' ' ********************************************** ' * Timer1 オーバーフロー 割り込み処理ルーチン * ' ********************************************** ' Tintovf: $asm PUSH R1 IN R1,SREG 'ステータス・レジスタを待避。 PUSH R24 PUSH R25 ; LDS R24,{Capovfc} 'オーバーフロー・カウント値を+1。 LDS R25,{Capovfc+1} ADIW R24,1 STS {Capovfc},R24 STS {Capovfc+1},R25 ; POP R25 POP R24 Out Sreg , R1 'ステータス・レジスタを復帰 POP R1 $end Asm Return ' ' End