' ' *************************************************** ' * * ' * Graphic LCD Logic Analyzer Program * ' * * ' * AVR Used is ATmega88 * ' * Basic Compiler is BASCOM-AVR * ' * Copyright By O-Family 2008. 2.27 * ' *************************************************** ' ' Ver 01.01 初回公開バージョン ' Ver 01.02 BASCOM-AVRの「Version 1.11.9.1」に対応。($lib "GlcdKS108.lbx")と(Cls Graph)命令を変更。 ' ' $regfile = "m88def.dat" $crystal = 20000000 ' Logdp Alias Pinc 'ロジック データ 入力ポート Gldtp Alias Portd 'Graphic-LCDのデータポート名 Gldip Alias Pind 'Graphic-LCDのデータポート名(キー入力用) Glcnp Alias Portb 'Graphic-LCDのコントロールポート名 Const Glce1 = 1 'Graphic-LCDの(CS1)を接続するピン番号 Const Glce2 = 0 'Graphic-LCDの(CS2)を接続するピン番号 Const Glccd = 3 'Graphic-LCDの(D/I)(RS)を接続するピン番号 Const Glcrd = 4 'Graphic-LCDの(R/W)を接続するピン番号 Const Glres = 2 'Graphic-LCDの(/RES)(RST)を接続するピン番号 Const Glena = 5 'Graphic-LCDの(E)を接続するピン番号 ' Const Smplen = 768 'サンプリング データ バッファの大きさ Const Smplenh = Smplen / 256 'サンプリング データ バッファの大きさ (上位Byte) Const Smplenl = Smplen - Smplenh * 256 'サンプリング データ バッファの大きさ (下位Byte) Const Dspmax = Smplen - 114 'G-LCD 波形表示可能領域 ' ' Dim Sampbuf(smplen) As Byte 'サンプリング データ バッファ Dim Bufsadr As Word 'サンプリング データ バッファのスタートアドレス (保管用) Dim Bufeadr As Word 'サンプリング データ バッファのエンドアドレス (保管用) Dim Smpadr As Word 'サンプリング データ バッファの書き込みポインタ Dim Remlen As Word 'サンプリング データのトリガ検知後の個数 Dim Trgpoi As Word 'トリガー発生ポイント Dim Smppoi As Integer 'サンプリング バッファの読み込み開始ポインタ (Trgpoi-128) Dim Viwpoi As Integer '現在の視点ポインタ (0〜767) Dim Dsppoi As Word '描画ポインタ (0〜767) Dim Dspsad As Word '波形描画サブルーチン用 バッファ読み込み開始アドレス Dim Smpmod As Byte 'サンプリング割り込み処理モード Dim Sdmask As Byte 'トリガー検知用マスクビット Dim Sdtrig As Byte 'トリガー検知パターン Dim Smptim As Byte 'サンプリング時間 ' Dim Gly As Byte '描画するYアドレス (1-6) Dim Dspbit As Byte 'サンプリングデータのビット位置 Dim Dspmag As Byte '表示倍率 Dim Curpos As Byte '設定カーソル表示位置 Dim Dspadd As Byte '波形表示の移動加算数 Dim Dsendp As Word '波形表示の限界点 Dim Curpoa As Byte 'Aカーソル位置 Dim Curpob As Byte 'Bカーソル位置 Dim Smpttp As Word 'カーソル値表示用 サンプリング時間 (スタート前) Dim Smpttm As Word 'カーソル値表示用 サンプリング時間 (スタート後) Dim Smpcab As Long 'カーソル値表示用 サンプリング時間 計算バッファ ' Dim Keycun As Byte 'キー入力チェック用タイマーカウンタ Dim Keyflg As Byte 'キー入力検出フラグ Dim Keydat As Byte 'キー入力データ Dim Keytmp As Byte 'キー入力用テンポラリ Dim Krpspf As Byte 'キー リピート用加速フラグ Dim Krpspd As Byte 'キー リピート用スピード カウンタ ' Dim Temp1 As Byte '汎用テンポラリ変数 Byte型 No.1 Dim Temp2 As Byte '汎用テンポラリ変数 Byte型 No.2 Dim Tempw1 As Integer '汎用テンポラリ変数 Integer型 No.1 Dim Tempstr As String * 10 '汎用テンポラリ変数 String型 Dim Tempstr2 As String * 11 '汎用テンポラリ変数 String型2 ' ' Config Portc = Input 'PORTCを入力に設定 ' $lib "GlcdKS108.lbx" 'KS0108チップ用ライブラリの使用を指示 Config Graphlcd = 128 * 64sed , Dataport = Gldtp , Controlport = Glcnp , Ce = Glce1 , Ce2 = Glce2 , Cd = Glccd , Rd = Glcrd , Reset = Glres , Enable = Glena Cls Setfont Logfont6x8 'フォント・データを定義 ' ' Config Timer0 = Timer , Prescale = 1024 , Clear Timer = 1 'Timer0を設定(キー入力用 タイマー 5mS) Ocr0a = 97 ' Config Timer1 = Timer , Prescale = 1 , Clear Timer = 1 'Timer1を設定(データ サンプリング タイマー) ' On Compare1a Tm1int Nosave 'Timer1の割り込みルーチンを設定 Enable Interrupts 'すべての割り込みを許可 ' ' Bufsadr = Varptr(sampbuf(1)) 'サンプリング データ バッファのスタートアドレス (保管用) Bufeadr = Varptr(sampbuf(smplen)) Bufeadr = Bufeadr + 1 'サンプリング データ バッファのエンドアドレス (保管用) ' Dspmag = 0 '表示倍率 Dspadd = 1 '波形表示の移動加算数 Dsendp = 654 '波形表示の限界点 Smpmod = 0 'サンプリング割り込み処理モード Curpos = 7 'モード カーソルを [S.t] 位置にセット Sdtrig = 0 'トリガー条件を設定 Viwpoi = 127 '視点位置を初期化 Dsppoi = Viwpoi '描画開始位置を初期化 Curpoa = 127 'Aカーソルの初期位置 Curpob = 128 'Bカーソルの初期位置 Smppoi = Bufsadr 'サンプリング バッファの読み込み開始を設定 Smptim = 4 'サンプリング時間の初期値を設定 ' ' ******************* ' * メイン ルーチン * ' ******************* ' Main: $asm LDI R16,1 '描画開始位置のY仕切りスケールを描画 Yscale1: LDI R20,14 'R20 = G-LCD Xアドレス MOV R21,R16 'R21 = G-LCD Yアドレス RCALL _glocate 'G-LCDライブラリのアドレスセット ルーチン LDI R24,$88 'R24 = G-LCDへ書き込むデータ RCALL _gwrite_data 'G-LCDライブラリのデータ書き込み ルーチン INC R16 CPI R16,7 BRNE Yscale1 $end Asm ' Gosub Smpmtis '動作条件のタイトルを描画 (タイトルとカーソル) Gosub Smpmods '動作条件の設定値を描画 (トリガー条件) Gosub Tmdset 'サンプリング時間を設定し表示する Smpttm = Smpttp 'カーソル値表示用 サンプリング時間を転送 ' ' Main1: If Viwpoi > Dsendp Then '表示倍率により、視点位置を確認 Dsppoi = Dsendp '波形表示の限界点を越えた場合 Else Dsppoi = Viwpoi '波形表示の限界点を越えていない場合 End If Gosub Dsmodds '表示条件を描画 (表示倍率・表示ガイド) Gosub Glwdsub 'グラフィックLCDに波形を描画 ' Tempw1 = Viwpoi - 128 '[Display Point]を表示 Tempstr = Str(tempw1) '文字列に変換 $asm RCALL Tvalcnv Loadadr Tempstr2 , Z 'マイナス符号位置を移動 ADIW R30,6 LD R16,Z+ ST Z,R16 LDI R21,8 'R21 = Yアドレス LDI R20,15 'R20 = Xアドレス LDI R17,4 '表示レングスをセット RCALL Tvalcnw1 '時間数値 描画 $end Asm ' Temp1 = Curpoa 'Aカーソルを描画 Gosub Curdsps Temp1 = Curpob 'Bカーソルを描画 Gosub Curdsps Gosub Curval 'カーソル位置の時間数値を表示 ' Main2: If Smpmod = 3 Then Goto Main3 'If サンプリング終了? Then Gosub Keyin 'キー入力をチェック If Keyflg = 0 Then Goto Main2 'If キー入力無し? Then Keyflg = 0 If Keydat = &H01 Then Goto Keyon1 'If Key(1) ON? Then If Smpmod <> 0 Then Goto Main2 'If サンプリング中? Then If Keydat = &H02 Then Goto Keyon2 'If Key(2) [Magnify] ON? Then If Keydat = &H04 Then Goto Keyon3 'If Key(3) ON? Then If Keydat = &H08 Then Goto Keyon3 'If Key(4) ON? Then If Keydat = &H10 Then Goto Keyon5 'If Key(5) [Cursor Right] ON? Then If Keydat = &H20 Then Goto Keyon6 'If Key(6) [Cursor Left] ON? Then Goto Main ' ' Main3: Smpmod = 0 'サンプリング モードを停止にセット Smppoi = Trgpoi - 128 'サンプリング バッファの読み込み開始位置を算出 (プリ・トリガ位置) If Smppoi < Bufsadr Then Smppoi = Smppoi + Smplen 'If バッファのスタートアドレスを越えた? Then Viwpoi = 127 '視点位置を初期化 Goto Main1 ' ' * Key(2) 表示倍率を変更 * ' Keyon2: '[Magnify] ON Dspmag = Dspmag + 1 Select Case Dspmag '波形表示の限界点を設定 Case 1 : Dspadd = 2 Dsendp = 540 'x1/2 Case 2 : Dspadd = 4 Dsendp = 312 'x1/4 Case 3: Dspadd = 1 Dsendp = 654 'x1 Dspmag = 0 End Select '波形表示の限界点をチェック Goto Main1 ' ' * Key(3 or 4) 設定値の増減 * ' Keyon3: 'Key(3 or 4) ON If Curpos < 7 Then Goto Keyon31 'If トリガー条件の設定? Then Temp1 = Curpos - 7 On Temp1 Goto Keyon32 , Keyon33 , Keyon34 , Keyon35 ' 設定カーソルの位置により処理を分岐 ' ' Keyon31: 'トリガー条件の設定 Temp1 = Curpos - 1 If Keydat = &H08 Then 'If Key(4)? Then Reset Sdmask.temp1 'トリガーを無効[x]に設定 Reset Sdtrig.temp1 Else 'Key(3) Set Sdmask.temp1 'トリガーを有効に設定 Toggle Sdtrig.temp1 'トリガーレベルを反転 [L]or[H] End If Gosub Smpmods '動作条件の設定値を描画 (トリガー条件) Goto Main2 ' ' Keyon32: 'サンプリング時間の設定 If Keydat = &H08 Then 'If Key(4)? Then If Smptim <> 0 Then Smptim = Smptim - 1 Else 'Key(3) If Smptim < 11 Then Smptim = Smptim + 1 End If Gosub Tmdset 'サンプリング時間の設定 Goto Main1 ' ' Keyon33: '[Display Point]の変更 If Keydat = &H08 Then 'If Key(4)? Then Viwpoi = Viwpoi - Dspadd Else 'Key(3) Viwpoi = Viwpoi + Dspadd End If If Viwpoi < 0 Then Viwpoi = 0 If Viwpoi > Dspmax Then Viwpoi = Dspmax Krpspf = 1 'キー・リピートを加速モードにセット Goto Main1 ' ' Keyon34: 'Aカーソル移動 Temp1 = Curpoa Gosub Cureras 'Aカーソルを消去 If Keydat = &H08 Then 'If Key(4)? Then If Curpoa > 15 Then Curpoa = Curpoa - 1 Else 'Key(3) Temp2 = Curpob - 1 If Curpoa < Temp2 Then Curpoa = Curpoa + 1 End If Temp1 = Curpoa Keyon36: Gosub Curdsps 'カーソルを描画 Gosub Curval 'カーソル位置の時間数値を表示 Krpspf = 1 'キー・リピートを加速モードにセット Goto Main2 ' ' Keyon35: 'Bカーソル移動 Temp1 = Curpob Gosub Cureras 'Bカーソルを消去 If Keydat = &H08 Then 'If Key(4)? Then Temp2 = Curpoa + 1 If Curpob > Temp2 Then Curpob = Curpob - 1 Else 'Key(3) If Curpob < 128 Then Curpob = Curpob + 1 End If Temp1 = Curpob Goto Keyon36 ' ' * Key(5) 設定カーソルを右へ移動 * ' Keyon5: 'Key(5) [Cursor Right] ON Curpos = Curpos + 1 If Curpos = 11 Then Curpos = 1 Keyon51: Gosub Smpmtis '動作条件のタイトルを描画 (タイトルと設定カーソル) Goto Main2 ' ' * Key(6) 設定カーソルを左へ移動 * ' Keyon6: 'Key(6) [Cursor Left] ON Curpos = Curpos - 1 If Curpos = 0 Then Curpos = 10 Goto Keyon51 ' ' * Key(1) トリガー検知のスタート・ストップ * ' Keyon1: 'Key(1) ON If Smpmod <> 0 Then Goto Keyon11 'If トリガー検出中かサンプリング中? Then $asm Loadadr Sampbuf(1) , X 'サンプリング データ バッファをクリア LDI R24,Smplenl LDI R25,Smplenh CLR R16 Memclr1: ST X+,R16 SBIW R24,1 Brne Memclr1 $end Asm Smpadr = Bufsadr 'サンプリング データ バッファの書き込みポインタを初期化 Remlen = Smplen - 129 'サンプリング データのトリガ検知後の個数をセット Smpmod = 1 'サンプリング割り込み処理モードをトリガー検知に設定 Smpttm = Smpttp 'カーソル値表示用 サンプリング時間を転送 $asm CLR R16 '[Ready]を描画 LDI R21,4 'R21 = Yアドレス LDI R20,51 'R20 = Xアドレス RCALL Glchads 'キャラクタ描画用のアドレスをセット LDI R24,$20 '[Ready]を描画 RCALL _gwrite_lcdchar 'G-LCDへキャラクタを描画するライブラリ LDI R24,$3E RCALL _gwrite_lcdchar LDI R24,$3F RCALL _gwrite_lcdchar LDI R24,$40 RCALL _gwrite_lcdchar LDI R24,$41 RCALL _gwrite_lcdchar LDI R24,$20 RCALL _gwrite_lcdchar $end Asm Enable Compare1a 'サンプリング用 Timaer1 割り込み開始 Goto Main2 ' Keyon11: 'サンプリング 手動停止 Disable Compare1a 'サンプリング用 Timaer1 割り込み停止 Smpmod = 0 'サンプリング モードを停止にセット Goto Main1 End ' ' ************************* ' * キー入力 サブルーチン * (Keyflg = 1 キー入力有り) ' ************************* (Keydat = キーデータ) ' Keyin: If Tifr0.ocf0a = 0 Then Return 'If Timer0が5mSカウント終了? Else Set Tifr0.ocf0a 'Timer0 比較A一致フラグをリセット ' If Keycun = 0 Then Goto Keyin02 'If キー入力チェック開始? Then If Keycun < 6 Then Goto Keyin01 'If チャタリング チェック期間? Then If Keycun = 6 Then Goto Keyin04 'If キー入力再確認? Then ' Gosub Keyport 'キーオフを確認 Keydat = Keydat And &H3F If Keydat <> Keytmp Then Goto Keyin05 'If キーオフ? Then If Keycun < 106 Then Goto Keyin01 'If リピート期間待ち(500mSec)? Then ' Keyflg = 1 'リピート開始 If Krpspf = 0 Then Goto Keyin06 'リピート間隔固定? Then If Krpspd > 103 Then Goto Keyin06 Krpspd = Krpspd + 1 'リピート速度を加速 Keyin06: Keycun = Krpspd Return ' Keyin01: Keycun = Keycun + 1 Return ' Keyin02: 'キー入力チェック開始 Gosub Keyport 'キー接続ポートからデータ入力 Keydat = Keydat And &H3F If Keydat <> 0 Then Goto Keyin03 'If キー入力有り? Then Keyin05: Keycun = 0 Krpspf = 0 Krpspd = 76 'キー・リピート間隔を150mSにセット Return ' Keyin03: 'キー入力有り Keytmp = Keydat Goto Keyin01 ' Keyin04: 'キー入力再確認 Gosub Keyport 'キー接続ポートからデータ入力 Keydat = Keydat And &H3F If Keydat <> Keytmp Then Goto Keyin05 'If キー入力エラー? Then Keyflg = 1 Goto Keyin01 ' ' ********************************************** ' * キー接続ポートからのデータ入力サブルーチン * (Keydat = キー入力ポートのデータ) ' ********************************************** ' Keyport: Config Gldtp = Input 'G-LCDのデータポートを入力に設定 Gldtp = &HFF 'G-LCDのデータポートをすべてプルアップ Reset Glcnp.glce1 'G-LCDの(CS1)を(L)に設定 Reset Glcnp.glce2 'G-LCDの(CS2)を(L)に設定 Waitus 10 'プルアップ抵抗の立ち上がり遅延時間 Keydat = Not Gldip 'キー・データを読み込み Set Glcnp.glce1 'G-LCDの(CS1)を(H)に設定 Config Gldtp = Output 'G-LCDのデータポートを出力に設定 Return ' ' ******************************************** ' * サンプリング時間 設定と表示 サブルーチン * ' ******************************************** ' Tmdset: Tempw1 = Loadlabel(smptab) 'データ テーブルのアドレスを変数に読み込み $asm LDS R30,{Tempw1} 'データ テーブルから設定値を取り出す LDS R31,{Tempw1+1} LDS R16,{Smptim} LDI R17,3 MUL R16,R17 ADD R30,R0 ADC R31,R1 LPM R16,Z+ 'サンプリング時間の表示値を読み込み LPM R17,Z+ 'サンプリング時間のTimer1設定値を読み込み LPM R18,Z ; LDI R19,1 'Timer1のプリスケラを設定 SBRC R16,7 'If プリスケラ値=x1? Then LDI R19,2 IN R20,Tccr1b ANDI R20,$F8 OR R20,R19 Out Tccr1b , R20 Out Ocr1ah , R18 'Timer1比較レジスタAを設定 Out Ocr1al , R17 ; MOV R20,R16 'サンプリング時間を数値化 ANDI R20,$0F MOV R21,R16 LDI R17,1 ANDI R21,$30 BREQ Tmdset1 'If 1桁? Then LDI R17,10 CPI R21,$10 BREQ Tmdset1 'If 2桁? Then LDI R17,100 '3桁 Tmdset1: MUL R20,R17 '桁数を掛ける ; ANDI R16,$40 BREQ Tmdset2 'If [uS]? Then MOVW R17:R16,R1:R0 '[mS] LDI R18,$E8 '1000倍する LDI R19,$03 RCALL Multi16 '16Bit X 16Bit 掛け算 MOVW R1:R0,R21:R20 Tmdset2: STS {Smpttp},R0 'カーソル値表示用に保管 STS {Smpttp+1},R1 $end Asm Tempstr = Str(smpttp) '文字列に変換 $asm RCALL Tvalcnv '時間数値を小数点表記に変換 Loadadr Tempstr2 , Z ADIW R30,4 CPI R22,4 BRCC Tmdset3 'If [mS]? Then ADIW R30,4 Tmdset3: LDI R21,7 'R21 = Yアドレス LDI R20,15 'R20 = Xアドレス LDI R17,3 '表示レングスをセット RCALL Tvalcnw '時間数値を描画 $end Asm Return ' ' ******************* ' * データ テーブル * ' ******************* ' Smptab: Data &H05 , 99% '5uS Data &H11 , 199% '10uS Data &H12 , 399% '20uS Data &H15 , 999% '50uS Data &H21 , 1999% '100uS Data &H22 , 3999% '200uS Data &H25 , 9999% '500uS Data &H41 , 19999% '1mS Data &H42 , 39999% '2mS Data &HC5 , 12499% '5mS Data &HD1 , 24999% '10mS Data &HD2 , 49999% '20mS ' ' **************************************** ' * ABカーソル 間隔数値 表示サブルーチン * ' **************************************** ' Curval: $asm LDS R17,{Curpoa} 'ABカーソルの差分を計算 LDS R16,{Curpob} Sub R16 , R17 RCALL Curvalsa '表示倍率により差分値を掛け算 ; RCALL Curvalsb 'サンプリング時間を掛けて文字列に変換 ; RCALL Tvalcnv '時間数値を小数点表記に変換 CPI R22,4 BRCS Curval3 'If 文字数が3以下? Then CPI R22,6 BRNE Curval2 'If 文字数が6? Else SBIW R30,1 RJMP Curval2 ; Curval3: Loadadr Tempstr2 , Z '間隔値を描画 ADIW R30,7 Curval2: LDI R21,7 'R21 = Yアドレス LDI R20,93 'R20 = Xアドレス LDI R17,4 '表示レングスをセット RCALL Tvalcnw ; ; LDS R16,{Curpoa} 'トリガー点からAカーソルまで(T-A)の値を計算 SUBI R16,15 RCALL Curvalsa '表示倍率により差分値を掛け算 ; LDS R18,{Dsppoi} '画面左端のトリガー点からの位置を計算 LDS R19,{Dsppoi+1} LDI R20,128 LDI R21,0 Sub R18 , R20 SBC R19,R21 ; LDI R24,0 ADD R16,R18 'トリガー点からAカーソルまでのポイント数を計算 ADC R17,R19 BRPL Curval6 'If 結果がプラス? Then LDI R24,1 COM R16 '絶対値に変換 COM R17 SUBI R16,$FF SBCI R17,$FF ; Curval6: PUSH R24 RCALL Curvalsb 'サンプリング時間を掛けて文字列に変換 ; RCALL Tvalcnv '時間数値を小数点表記に変換 POP R24 CPI R24,1 BREQ Curval7 'If マイナス表記? Then CPI R22,4 BRCS Curval5 'If 文字数が3以下? Then CPI R22,6 BRNE Curval4 'If 文字数が6? Else SBIW R30,2 RJMP Curval4 ; Curval5: Loadadr Tempstr2 , Z '間隔値を描画 ADIW R30,6 Curval4: LDI R21,8 'R21 = Yアドレス LDI R20,87 'R20 = Xアドレス LDI R17,5 '表示レングスをセット RCALL Tvalcnw $end Asm Return ' ' $asm Curval7: '画面左端からAカーソルまで(T-A)がマイナスの場合 LDI R16,$2D '[-]をセット ST -Z,R16 CPI R22,4 BRCS Curval5 'If 文字数が3以下? Then CPI R22,6 BRNE Curval4 'If 文字数が6? Else SBIw R30,1 RJMP Curval4 $end Asm ' ' * 表示倍率により掛け率を調整するサブルーチン * (R16 = カーソルの数値) ' (R16:R17 = 計算結果) $asm Curvalsa: LDS R18,{Dspmag} LDI R17,1 CPI R18,0 BREQ Curvals1 'If 表示倍率 X1? Then LDI R17,2 CPI R18,1 BREQ Curvals1 'If 表示倍率 X1/2? Then LDI R17,4 Curvals1: MUL R16,R17 MOVW R17:R16,R1:R0 RET ' ' * サンプリング時間を掛けて、文字列に変換するサブルーチン * (R16:R17 = カーソルのポイント数) ' Curvalsb: LDS R18,{Smpttm} 'サンプリング時間を掛ける LDS R19,{Smpttm+1} RCALL Multi16 '16Bit X 16Bit 掛け算 STS {Smpcab},R20 STS {Smpcab+1},R21 STS {Smpcab+2},R22 STS {Smpcab+3},R23 $end Asm Tempstr = Str(smpcab) '間隔値を文字列に変換 $asm RET $end Asm ' ' ******************************************* ' * 時間数値を小数点表記に変換 サブルーチン * ' ******************************************* ' $asm Tvalcnv: Loadadr Tempstr2 , Z '変換バッファを初期化 LDI R16,11 LDI R17,$20 Tvalcnv1: ST Z+,R17 DEC R16 BRNE Tvalcnv1 'If 初期化終了? Else ; Loadadr Tempstr , X 'R22 = 文字列の文字数を計算 SER R22 Tvalcnv2: INC R22 LD R16,X+ CPI R16,0 BRNE Tvalcnv2 'If 終了コード? Else SBIW R26,1 'Xを文字列の終了コード位置にセット ; MOV R16,R22 '数値をバッファへピリオドを付けながら転送 Tvalcnv4: LDI R18,3 Tvalcnv3: LD R17,-X ST -Z,R17 DEC R16 BREQ Tvalcnv5 'If 転送終了? Then DEC R18 BRNE Tvalcnv3 'If ピリオド書き込み? Else LDI R17,$2E '[.] 書き込み ST -Z,R17 RJMP Tvalcnv4 ; Tvalcnv5: RET ' ' ****************************** (R20 = Xアドレス) ' * 時間数値 描画 サブルーチン * (R21 = Yアドレス) ' ****************************** (R17 = 表示レングス) ' (R30,R31 Z = 描画データバッファ アドレス) Tvalcnw: RCALL Tvalcnw1 '数値を描画 RJMP Tvalcnw2 '単位を描画 ' ' * 数値を描画するサブルーチン * ' Tvalcnw1: CLR R16 '反転無しに設定 RCALL Glchads 'キャラクタ描画用のアドレスをセット ; Tvalcnw3: LD R24,Z+ 'Z 描画データバッファの文字をLCDへ描画 RCALL _gwrite_lcdchar 'G-LCDへキャラクタを描画するライブラリ DEC R17 BRNE Tvalcnw3 'If レングス分描画終了? Else RET ' ' * 単位を描画するサブルーチン * ' Tvalcnw2: LDI R31,$21 '[S] セット LDI R30,$26 '[u] セット CPI R22,4 BRCS Tvalcnw4 'If [uS]? Then LDI R30,$27 '[m] セット CPI R22,7 BRCS Tvalcnw4 LDI R31,$20 '[ ] セット LDI R30,$21 '[S] セット ; Tvalcnw4: MOV R24,R30 '単位を描画 RCALL _gwrite_lcdchar 'G-LCDへキャラクタを描画するライブラリ MOV R24,R31 RCALL _gwrite_lcdchar 'G-LCDへキャラクタを描画するライブラリ RET $end Asm ' ' ****************************************************** ' * 動作条件のタイトルと設定カーソルの描画サブルーチン * ' ****************************************************** ' Smpmtis: $asm LDI R17,1 'チャンネル番号を表示 LDS R30,{Curpos} LDI R31,$31 Smpmtis1: MOV R21,R17 'R21 = Yアドレス LDI R20,1 'R20 = Xアドレス RCALL Smpmtcuc '現在のカーソル位置をチェック MOV R24,R31 RCALL Glchrws1 'G-LCDへキャラクタを(1文字)描画 (反転表示対応) INC R31 CPI R17,7 BRNE Smpmtis1 'If 6チャンネル表示終了? Else ; RCALL Smpmtcuc '現在のカーソル位置をチェック LDI R21,7 'R21 = Yアドレス LDI R20,1 'R20 = Xアドレス RCALL Glchads 'キャラクタ描画用のアドレスをセット LDI R24,$21 '[S]を描画 RCALL _gwrite_lcdchar 'G-LCDへキャラクタを描画するライブラリ LDI R24,$22 '[.t]を描画 RCALL _gwrite_lcdchar 'G-LCDへキャラクタを描画するライブラリ ; RCALL Smpmtcuc '現在のカーソル位置をチェック LDI R21,8 'R21 = Yアドレス LDI R20,1 'R20 = Xアドレス RCALL Glchads 'キャラクタ描画用のアドレスをセット LDI R24,$23 '[D]を描画 RCALL _gwrite_lcdchar 'G-LCDへキャラクタを描画するライブラリ LDI R24,$24 '[.p]を描画 RCALL _gwrite_lcdchar 'G-LCDへキャラクタを描画するライブラリ ; CLR R16 LDI R21,8 'R21 = Yアドレス LDI R20,67 'R20 = Xアドレス RCALL Glchads 'キャラクタ描画用のアドレスをセット LDI R24,$2A '[T]を描画 RCALL _gwrite_lcdchar 'G-LCDへキャラクタを描画するライブラリ LDI R24,$2D '[-]を描画 RCALL _gwrite_lcdchar 'G-LCDへキャラクタを描画するライブラリ LDI R24,$28 '[A]を描画 RCALL _gwrite_lcdchar 'G-LCDへキャラクタを描画するライブラリ ; CLR R16 LDI R21,7 'R21 = Yアドレス LDI R20,79 'R20 = Xアドレス RCALL Glchads 'キャラクタ描画用のアドレスをセット LDI R24,$2D '[-]を描画 RCALL _gwrite_lcdchar 'G-LCDへキャラクタを描画するライブラリ LDI R24,$20 '[ ]を描画 RCALL _gwrite_lcdchar 'G-LCDへキャラクタを描画するライブラリ ; RCALL Smpmtcuc '現在のカーソル位置をチェック LDI R21,7 'R21 = Yアドレス LDI R20,73 'R20 = Xアドレス RCALL Glchads 'キャラクタ描画用のアドレスをセット LDI R24,$28 '[A]を描画 RCALL _gwrite_lcdchar 'G-LCDへキャラクタを描画するライブラリ ; RCALL Smpmtcuc '現在のカーソル位置をチェック LDI R21,7 'R21 = Yアドレス LDI R20,85 'R20 = Xアドレス RCALL Glchads 'キャラクタ描画用のアドレスをセット LDI R24,$29 '[B]を描画 RCALL _gwrite_lcdchar 'G-LCDへキャラクタを描画するライブラリ $end Asm Return ' ' * 現在の設定カーソル位置 チェック サブルーチン * ' $asm Smpmtcuc: LDI R16,1 CP R17,R30 BREQ Smpmtcuc1 'If 現在のカーソル位置? Then LDI R16,0 Smpmtcuc1: INC R17 RET $end Asm ' ' ************************************** ' * 動作条件の設定値の描画サブルーチン * ' ************************************** ' Smpmods: $asm LDI R17,1 'トリガー条件を表示 LDS R30,{Sdtrig} LDS R31,{Sdmask} Smpmods3: LDI R24,$2F '[L]をセット LSR R30 BRCC Smpmods1 'If トリガーレベル (L) ? LDI R24,$2C '[H]をセット Smpmods1: LSR R31 BRCS Smpmods2 'If トリガー使用? Then LDI R24,$25 '[x]をセット Smpmods2: MOV R21,R17 'R21 = Yアドレス LDI R20,7 'R20 = Xアドレス RCALL Glchrws 'G-LCDへキャラクタを(1文字)描画 INC R17 CPI R17,7 BRNE Smpmods3 'If 6チャンネル終了? Else $end Asm Return ' ' ***************************** ' * 表示条件 描画サブルーチン * ' ***************************** ' Dsmodds: $asm CLR R16 '表示倍率値を描画 LDI R21,7 'R21 = Yアドレス LDI R20,50 'R20 = Xアドレス RCALL Glchads 'キャラクタ描画用のアドレスをセット LDI R24,$25 '[x]を描画 RCALL _gwrite_lcdchar 'G-LCDへキャラクタを描画するライブラリ ; LDS R17,{Dspmag} LDI R24,$31 '[1]をセット CPI R17,0 BREQ Dsmodd1 'If 表示倍率=×1 ? Then LDI R24,$3A '[1/]をセット Dsmodd1: RCALL _gwrite_lcdchar 'G-LCDへキャラクタを描画するライブラリ ; LDI R24,$20 '[ ]を描画 CPI R17,0 BREQ Dsmodd2 'If 表示倍率=×1 ? Then LDI R24,$3B '[/2]をセット CPI R17,1 BREQ Dsmodd2 'If 表示倍率=×1/2 ? Then LDI R24,$3C '[/4]をセット Dsmodd2: RCALL _gwrite_lcdchar 'G-LCDへキャラクタを描画するライブラリ ; ; LDS R16,{Dsppoi} '表示位置ガイドを描画 LDS R17,{Dsppoi+1} LSL R16 '12分割した表示位置を計算 ROL R17 LSL R16 ROL R17 INC R17 'R17 = ガイド表示開始位置 ' LDS R16,{Dspmag} '表示倍率により描画幅を選択 LDI R18,2 CPI R16,0 BREQ Dsmodds1 'If 表示倍率=×1 ? Then LDI R18,4 CPI R16,1 BREQ Dsmodds1 'If 表示倍率=×1/2 ? Then LDI R18,8 '表示倍率=×1/4 Dsmodds1: 'R18 = ガイド表示幅 ' LDI R22,46 'R22 = G-LCD Xアドレス LDI R19,$FE '左枠を描画 RCALL Gldatwr ' LDI R16,12 Dsmodds3: 'ガイドの左側空白域を描画 DEC R17 BREQ Dsmodds2 LDI R19,$82 RCALL Gldatwr DEC R16 RJMP Dsmodds3 ' Dsmodds2: 'ガイドを描画 LDI R19,$FE RCALL Gldatwr DEC R16 DEC R18 BRNE Dsmodds2 ' INC R16 'ガイドの右側空白域を描画 Dsmodds5: DEC R16 BREQ Dsmodds4 LDI R19,$82 RCALL Gldatwr RJMP Dsmodds5 ' Dsmodds4: '右枠を描画 LDI R19,$FE RCALL Gldatwr $end Asm Return ' $asm Gldatwr: '表示位置ガイド描画用サブルーチン MOV R20,R22 LDI R21,8 'R21 = G-LCD Yアドレス RCALL _glocate 'G-LCDライブラリのアドレスセット ルーチン MOV R24,R19 RCALL _gwrite_data 'G-LCDライブラリのデータ書き込み ルーチン INC R22 RET $end Asm ' ' ************************************************ (R16 = 反転表示フラグ) ' * キャラクタ描画用 アドレスセット サブルーチン * (R20 = Xアドレス) ' ************************************************ (R21 = Yアドレス) ' $asm Glchads: STS {___LCDrev},R16 '反転表示フラグをセット STS {___lcdcol},R20 'Xアドレスをセット STS {___lcdrow},R21 'Yアドレスをセット RET ' ' ************************************** (R20 = Xアドレス) ' * キャラクタ(1文字) 描画サブルーチン * (R21 = Yアドレス) ' ************************************** (R24 = 文字データ) ' Glchrws: 'キャラクタ(1文字) 描画サブルーチン CLR R16 Glchrws1: 'R16を1にしてコールすると反転表示 RCALL Glchads RCALL _gwrite_lcdchar 'G-LCDへキャラクタを描画するライブラリ RET $end Asm ' ' ********************************** ' * A・Bカーソルの消去サブルーチン * ' ********************************** ' Cureras: $asm LDI R23,0 Cureras1: LDS R16,{Temp1} 'カーソルのアドレスを読み込み LDI R17,1 Cureras3: MOV R20,R16 'R20 = G-LCD Xアドレス MOV R21,R17 'R21 = G-LCD Yアドレス RCALL _glocate 'G-LCDライブラリのアドレスセット ルーチン RCALL _gRead_data 'G-LCDライブラリのデータ読み込み ルーチン RCALL _gRead_data 'G-LCDライブラリのデータ読み込み ルーチン CPI R23,0 BRNE Cureras4 'If カーソル描画? Then LDI R18,$3F 'カーソルを消去 AND R18,R1 LDI R19,$03 AND R19,R16 CPI R19,$02 BRNE Cureras2 ORI R18,$80 Cureras2: MOV R20,R16 'R20 = G-LCD Xアドレス MOV R21,R17 'R21 = G-LCD Yアドレス RCALL _glocate 'G-LCDライブラリのアドレスセット ルーチン MOV R24,R18 RCALL _gwrite_data 'G-LCDライブラリのデータ書き込み ルーチン INC R17 CPI R17,7 BRNE Cureras3 'If 消去終了? Else $end Asm Return ' ' ********************************** ' * A・Bカーソルの描画サブルーチン * ' ********************************** ' Curdsps: $asm LDI R23,1 RJMP Cureras1 ; Cureras4: LDI R18,$C0 OR R18,R1 RJMP Cureras2 $end Asm ' ' **************************************** ' * グラフィックLCD 波形描画サブルーチン * ' **************************************** ' Glwdsub: $asm LDS R24,{Smppoi} 'サンプリング バッファの読み込み開始ポインタ (バッファのアドレス) LDS R25,{Smppoi+1} LDS R26,{Dsppoi} '描画ポインタ (0〜767) LDS R27,{Dsppoi+1} ADD R26,R24 'サンプリング バッファの読み込み開始アドレスを算出 ADC R27,R25 LDS R24,{Bufeadr} 'サンプリング バッファの終点アドレスのチェック LDS R25,{Bufeadr+1} CP R26,R24 CPC R27,R25 BRCS Glwdsub1 'If バッファのエンドアドレスを越えた? Else LDI R24,Smplenl 'バッファのアドレスを折り返し LDI R25,Smplenh Sub R26 , R24 SBC R27,R25 Glwdsub1: STS {Dspsad},R26 STS {Dspsad+1},R27 ; LDI R16,1 '6チャンネル分の波形を描画 LDI R17,$01 Glwdsub2: STS {Gly},R16 STS {Dspbit},R17 RCALL Glxlins 'G-LCDへ1チャンネル分の波形を描画 LDS R17,{Dspbit} 'サンプリング データのビット位置を変更 LSL R17 LDS R16,{Gly} 'Yアドレスを変更 INC R16 CPI R16,7 BRNE Glwdsub2 '6チャンネル分の波形描画終了? Else $end Asm Return ' ' ********************************************* (Gly = 描画するYアドレス (1〜6)) ' * G-LCD 波形1チャンネル分 描画サブルーチン * (Dspbit = サンプリング データのビット位置) ' ********************************************* (Dapmag = 表示倍率) ' (Dspsad = サンプリング バッファの読み込み開始アドレス) $asm Glxlins: LDI R20,15 'R20 = G-LCD Xアドレス LDS R21,{Gly} 'R21 = G-LCD Yアドレス RCALL _glocate 'G-LCDライブラリのアドレスセット ルーチン ' LDS R16,{Dspmag} '表示倍率によりバッファから取り出すデータ数を決定 LDI R18,1 CPI R16,0 BREQ Glxlin02 'If 表示倍率=×1 ? Then LDI R18,2 CPI R16,1 BREQ Glxlin02 'If 表示倍率=×1/2 ? Then LDI R18,4 '表示倍率=×1/4 Glxlin02: LDS R26,{Dspsad} 'X-Reg.=サンプリング バッファの読み込み開始アドレス LDS R27,{Dspsad+1} LDS R30,{Bufeadr} 'Z-Reg.=サンプリング バッファの終点アドレス LDS R31,{Bufeadr+1} LDI R22,14 'Xアドレスの描画カウンタ (X=15から描画開始) LD R2,X '開始時の前回データを仮作成 ' Glxlin01: MOV R19,R18 '表示倍率により、サンプリングデータを検査 MOV R16,R2 '前回の最終データをセット MOV R17,R2 Glxlin03: LD R2,X+ 'サンプリング データを読み込み OR R16,R2 AND R17,R2 CP R26,R30 'サンプリング バッファのアドレスをチェック CPC R27,R31 BRNE Glxlin04 'If サンプリング バッファ アドレスが後尾? Else Loadadr Sampbuf(1) , X 'サンプリング バッファのアドレスを先頭に戻す Glxlin04: DEC R19 BRNE Glxlin03 'If サンプリング データの検査終了? Else ' LDS R19,{Dspbit} 'サンプリングデータにより、LCDへ書き込むパターンを選択 LDI R24,$20 AND R16,R19 BREQ Glxlin05 'If L(0)レベル? Then LDI R24,$02 AND R17,R19 BRNE Glxlin05 'If H(1)レベル? Then LDI R24,$3E 'L(0) -> H(1) または H(1) -> L(0) へ変化 Glxlin05: MOV R16,R22 'Xの仕切りスケールを描画 ANDI R16,$03 CPI R16,$01 BRNE Glxlin07 ORI R24,$80 Glxlin07: 'R24 = G-LCDへ書き込むデータ RCALL _gwrite_data 'G-LCDライブラリのデータ書き込み ルーチン ' CPI R22,63 BRNE Glxlin06 'If LCD チップ変更? Else LDI R20,65 'R20 = G-LCD Xアドレス LDS R21,{Gly} 'R21 = G-LCD Yアドレス RCALL _glocate 'G-LCDライブラリのアドレスセット ルーチン Glxlin06: INC R22 CPI R22,128 BRNE Glxlin01 'If 波形1チャンネル分 書き込み終了? Else RET $end Asm ' ' ************************************* ' * 16Bit X 16Bit 掛け算 サブルーチン * (R19:R18 * R17:R16 = R23:R22:R21:R20) ' ************************************* ' $asm Multi16: CLR R22 CLR R23 MUL R18,R16 MOVW R21:R20,R1:R0 MUL R18,R17 ADD R21,R0 ADC R22,R1 MUL R19,R16 ADD R21,R0 ADC R22,R1 ADC R23,R23 MUL R19,R17 ADD R22,R0 ADC R23,R1 RET $end Asm ' ' *************************************************** ' * Timer1 データ サンプリング 割り込み処理ルーチン * ' *************************************************** ' Tm1int: $asm PUSH R0 PUSH R23 'R23は拡張I/Oレジスタへのアクセスに使用する PUSH R24 PUSH R25 PUSH R26 PUSH R27 IN R0,SREG 'ステータス・レジスタを待避 ; IN R23,Logdp 'ポートからサンプリング データを取り込み LDS R26,{Smpadr} 'X = サンプリング バッファのアドレス LDS R27,{Smpadr+1} ST X,R23 'サンプリングしたデータをバッファへ書き込み ; LDS R24,{Smpmod} 'サンプリング モードをチェック CPI R24,2 BREQ Tm1int1 'If トリガー検知済み? Then ; LDS R24,{Sdmask} 'トリガーを検知 AND R23,R24 LDS R24,{Sdtrig} CP R23,R24 BRNE Tm1int2 'If トリガー検知? Else STS {Trgpoi},R26 'トリガー位置を保存 STS {Trgpoi+1},R27 LDI R24,2 'サンプリング モードをトリガー検知済みにセット STS {Smpmod},R24 RJMP Tm1int2 ; Tm1int1: 'トリガー検知済み LDS R24,{Remlen} '残りのサンプリング数を確認 LDS R25,{Remlen+1} SBIW R24,1 STS {Remlen},R24 STS {Remlen+1},R25 BRNE Tm1int2 'If サンプリング終了? Else LDI R24,3 'サンプリング モードを終了にセット STS {Smpmod},R24 CBI TIMSK1,OCIE1A 'TIMER1 比較一致割り込みを禁止 (*** この命令はR23を使用する ***) ; Tm1int2: ADIW R26,1 'サンプリング ポインタを+1 LDS R24,{Bufeadr} 'サンプリング バッファのアドレスをチェック LDS R25,{Bufeadr+1} CP R26,R24 CPC R27,R25 BRCS Tm1int3 'If サンプリング バッファ アドレスが後尾? Else Loadadr Sampbuf(1) , X 'サンプリング バッファのアドレスを先頭に戻す Tm1int3: STS {Smpadr},R26 'X = サンプリング バッファのアドレスを保存 STS {Smpadr+1},R27 ; Out Sreg , R0 'ステータス・レジスタを復帰 POP R27 POP R26 POP R25 POP R24 POP R23 POP R0 $end Asm Return ' ' ******************* ' * フォント データ * ' ******************* ' Logfont6x8: $asm .db 1 , 6 , 6 , 0 .db $00 , $00 , $00 , $00 , $00 , $00 ' .db $00 , $44 , $4a , $4a , $32 , $00 ' ! [S] .db $40 , $04 , $3e , $44 , $20 , $00 ' ”[.t] .db $00 , $7e , $42 , $42 , $3c , $40 ' # [D] .db $00 , $7c , $14 , $14 , $08 , $00 ' $ [.p] .db $00 , $44 , $28 , $10 , $28 , $44 ' % [x] .db $00 , $fc , $20 , $10 , $3c , $00 ' & [u] .db $00 , $7c , $04 , $78 , $04 , $78 ' ' [m] .db $00 , $7c , $12 , $12 , $7c , $00 '( [A] .db $00 , $7e , $4a , $4a , $34 , $00 ' )[B] .db $00 , $02 , $02 , $7e , $02 , $02 ' * [T] .db $00 , $08 , $08 , $3e , $08 , $08 ' + .db $00 , $7e , $08 , $08 , $7e , $00 ' , [H] .db $00 , $08 , $08 , $08 , $08 , $00 ' - .db $00 , $00 , $60 , $60 , $00 , $00 ' . .db $00 , $7e , $40 , $40 , $40 , $00 ' / [L] .db $00 , $3c , $52 , $4a , $3c , $00 ' 0 .db $00 , $00 , $44 , $7e , $40 , $00 ' 1 .db $00 , $64 , $52 , $52 , $4c , $00 ' 2 .db $00 , $24 , $42 , $4a , $34 , $00 ' 3 .db $00 , $18 , $14 , $7e , $10 , $00 ' 4 .db $00 , $2e , $4a , $4a , $32 , $00 ' 5 .db $00 , $3c , $4a , $4a , $30 , $00 ' 6 .db $00 , $02 , $72 , $0a , $06 , $00 ' 7 .db $00 , $34 , $4a , $4a , $34 , $00 ' 8 .db $00 , $0c , $52 , $52 , $3c , $00 ' 9 .db $00 , $04 , $7e , $00 , $60 , $18 ' : [1/] .db $06 , $00 , $64 , $52 , $52 , $4c ' ; [/2] .db $06 , $00 , $18 , $14 , $7e , $10 ' < [/4] .db $00 , $14 , $14 , $14 , $14 , $00 ' = .db $7f , $09 , $19 , $66 , $00 , $38 ' > [Ready] .db $54 , $54 , $58 , $00 , $20 , $54 ' ? .db $54 , $78 , $00 , $30 , $48 , $48 ' @ .db $7f , $00 , $4c , $50 , $30 , $1c ' A $end Asm