' $prog &HFF , &HE2 , &HDF , &HF9 'ヒューズ・ビット設定 CKDIV8 = 1 ' ' ********************************************** ' * Serial to LED (12-LED) 制御ボード * ' * * ' * AVR is using ATmega88P * ' * Basic Compiler is BASCOM-AVR * ' * Copyright By O-Family 2011. 1.28 * ' ********************************************** ' ' Ver 1.01 初回公開バージョン ' ' $regfile = "m88pdef.dat" '使用するAVRを設定。 $crystal = 8000000 'AVRクロックを設定。 ' $hwstack = 64 'ハードウェア・スタックの容量を設定。 $swstack = 10 'ソフトウェア・スタックの容量を設定。 $framesize = 24 'フレーム領域の容量を設定。 ' ' Const Assembly = 0 '組立の選択。(0:制御基板と同方向, 1:制御基板とハンダ面合わせ) Const Bright = 58 '輝度の初期値。(2〜58)暗〜明 ' $baud = 9600 'ハードウェアUSARTの通信速度(ボーレート)を設定。 ' ' * ポート名の定義 * ' Led_c1 Alias Portb.7 'LEDのコモン[1]端子接続ポート。 Led_c2 Alias Portb.2 'LEDのコモン[2]端子接続ポート。 Led_c3 Alias Portb.1 'LEDのコモン[3]端子接続ポート。 Led_c4 Alias Portc.0 'LEDのコモン[4]端子接続ポート。 Led_c5 Alias Portb.4 'LEDのコモン[5]端子接続ポート。 Led_c6 Alias Portb.5 'LEDのコモン[6]端子接続ポート。 Led_c7 Alias Portb.0 'LEDのコモン[7]端子接続ポート。 Led_c8 Alias Portc.1 'LEDのコモン[8]端子接続ポート。 Led_c9 Alias Portc.3 'LEDのコモン[9]端子接続ポート。 Led_c10 Alias Portc.4 'LEDのコモン[10]端子接続ポート。 Led_c11 Alias Portc.5 'LEDのコモン[11]端子接続ポート。 Led_c12 Alias Portc.2 'LEDのコモン[12]端子接続ポート。 ' Led_segment Alias Portd 'LEDのセグメント端子接続ポート。 Led_segmentd Alias Portb.6 'LEDの[d]セグメント端子接続ポート。 Led_common1 Alias Portb 'LEDのコモン端子接続ポート[1]。 Led_common2 Alias Portc 'LEDのコモン端子接続ポート[2]。 ' Sw_1 Alias Pinb.3 'スイッチ[1]の接続ポート。 Sw_o1 Alias Portb.3 ' ' * 変数の宣言 * ' Dim Led_counter As Byte 'ダイナミック点灯の桁カウンター。 Dim Led_buff(12) As Byte 'ダイナミック点灯のセグメントデータ。 Dim Led_temp1 As Byte 'LED用 汎用テンポラリ変数 Byte型 No.1 ' Dim Rxbuff(32) As Byte '受信データ保管用。 Dim Rxcount As Byte '受信データ数カウンター。 Dim Dsbuff(32) As Byte '表示データ保管用。 Dim Commaflg As Byte 'カンマ[,]の表示制御フラグ。(0:無視, 1:[D.P.]で表示, 2:前文字の[D.P.]で表示) Dim Periodflg As Byte 'ピリオド[.]の表示制御フラグ。(0:無視, 1:[D.P.]で表示, 2:前文字の[D.P.]で表示) Dim Sysmode As Byte 'ユニットの動作モード。(0:通常, 1:周波数カウンター[3]動作) Dim Swtemp As Byte 'スイッチの状態保存用。 ' Dim Temp1 As Byte '汎用テンポラリ変数 Byte型 No.1 Dim Temp2 As Byte '汎用テンポラリ変数 Byte型 No.2 Dim Temp3 As Byte '汎用テンポラリ変数 Byte型 No.3 Dim Temp4 As Byte '汎用テンポラリ変数 Byte型 No.4 ' ' * ポートの初期設定 * ' Reset Ucr.txen0 'USART送信許可を取り消す(禁止)。 Config Serialin = Buffered , Size = 254 'シリアルデータ受信を、バッファを使用した割り込み処理にする。 ' Config Portb = &B1111_0111 '各ポートの方向を設定。 Config Portc = &B0011_1111 Config Portd = &B1111_1110 Set Sw_o1 'スイッチ[1]入力を内部プルアップする。 ' Config Aci = Off 'アナログ比較器の電源を切る。 ' On Pcint2 Sinint Nosave 'PD0のピン変化割り込みルーチンを設定。 Set Pcmsk2.pcint16 'PD0のピン変化割り込みを許可する。 ' ' * タイマーの設定 * ' Config Timer0 = Timer , Prescale = 64 , Clear Timer = 1 '8,000,000Hz / 64 = 125,000Hz (ダイナミック点灯用) Ocr0a = 62 - 1 '125,000Hz / 2,000Hz = 約62カウント Ocr0b = Bright '輝度の初期値を設定する。(2〜58) On Oc0a Ledcomset 'DMA割り込み[a]ルーチンを設定。 Enable Oc0a 'TIMER0比較一致A割り込みを許可する。 On Oc0b Ledcomoff 'DMA割り込み[b]ルーチンを設定。 Enable Oc0b 'TIMER0比較一致B割り込みを許可する。 ' Config Timer2 = Timer , Prescale = 1024 , Clear Timer = 1 '8,000,000Hz / 1,024 = 7,812.5Hz (スイッチチェック用) Ocr2a = 78 - 1 '7,812.5Hz / 100Hz(10mS) = 約78カウント ' ' * プログラムの初期設定 * ' Commaflg = 1 'カンマ[,]の初期動作。(0:無視, 1:[D.P.]で表示, 2:前文字の[D.P.]で表示) Periodflg = 2 'ピリオド[.]の初期動作。(0:無視, 1:[D.P.]で表示, 2:前文字の[D.P.]で表示) Sysmode = 0 'ユニットの動作モード。(0:通常, 1:周波数カウンター[3]動作) ' Led_counter = 0 '桁カウンターを初期化。 Rxcount = 0 '受信データ数カウンターを初期化。 Enable Interrupts 'すべての割り込みを許可する。 ' For Temp1 = 1 To 32 '表示データバッファーをスペースで埋める。 Dsbuff(temp1) = &H20 Next Temp1 ' ' ******************* ' * メイン ルーチン * ' ******************* ' Main: Gosub Rxdata 'シリアル通信ポートからデータを受信する。 Gosub Swcheck 'スイッチの状態を調べて表示を変更する。 Goto Main ' ' ******************************************************* ' * シリアル通信ポートからデータを受信する サブルーチン * ' ******************************************************* ' Rxdata: Temp1 = Inkey() 'シリアル受信バッファーから1バイト取り出す。 If Temp1 = 0 Then Return 'If 受信データが無いか? Then ' If Temp1 < &H20 Then Goto Rxdata1 'If 制御コードか? Then If Temp1 >= &H7F Then Goto Rxdata1 'If 制御コードか? Then ' Rxdata2: If Rxcount >= 32 Then Return 'If 受信データが32個を越えたか? Then Rxcount = Rxcount + 1 Rxbuff(rxcount) = Temp1 '受信データをバッファーへ保存する。 Return ' ' Rxdata1: '制御コードの処理。 If Temp1 = &H0D Then Goto Rxdata3 'If [CR(復帰)]か? Then If Temp1 = &H08 Then Goto Rxdata4 'If [BS(後退)]か? Then If Temp1 = &H7F Then Goto Rxdata4 'If [DEL(削除)]か? Then If Temp1 = &H12 Then Goto Rxdata2 'If [DC2(装置制御2)]か? Then Return ' ' Rxdata3: '[CR(復帰)]の処理。 If Rxbuff(1) = &H12 Then Goto Rxdata5 'If ユニット制御[DC2(装置制御2)]か? Then ' For Temp1 = 1 To 32 '受信バッファーから表示バッファーへ転送する。 If Rxcount >= Temp1 Then Dsbuff(temp1) = Rxbuff(temp1) '表示バッファーへ転送する。 Else Dsbuff(temp1) = &H20 '表示バッファーの残りエリアをスペースで埋める。 End If Next Temp1 ' Gosub Segconv 'ASCIIコードをセグメントデータに変換する。 Rxcount = 0 Return ' ' Rxdata5: 'ユニット制御[DC2(装置制御2)]の処理。 If Rxcount = 2 Then 'If 2バイトの制御コードか? Then Temp1 = Rxbuff(2) Select Case Temp1 Case Is < &H30 : '[00-2F] Case Is < &H32 : '[30,31] Sysmode = Temp1 - &H30 'ユニットの動作モードを設定。(0:通常, 1:周波数カウンター[3]動作) ' Case Is < &H35 : '[32,33,34] Commaflg = Temp1 - &H32 'カンマ[,]の表示制御フラグを設定。(0:無視, 1:[D.P.]で表示, 2:前文字の[D.P.]で表示) ' Case Is < &H38 : '[35,36,37] Periodflg = Temp1 - &H35 'ピリオド[.]の表示制御フラグ。(0:無視, 1:[D.P.]で表示, 2:前文字の[D.P.]で表示) ' Case Is < &H40 : '[38-3F] Case &H40 : '[40] 「パワーダウン・モード」へ移行する。 Waitms 30 '[LF]を読み飛ばす。 Temp1 = Inkey() Reset Ucr.rxen0 'USART受信を禁止する。 Disable Oc0a 'TIMER0比較一致A割り込みを禁止する。 Disable Oc0b 'TIMER0比較一致B割り込みを禁止する。 Led_common1 = &B0000_1000 'すべてのLEDを消灯する。 Led_common2 = 0 Led_segment = 0 Set Mcucr.pud '内部プルアップをすべて禁止する。 ' Set Pcifr.pcif2 'ピン変化割り込み2をリセットする。 Enable Pcint2 'ピン変化割り込み2を許可する。 Power Powerdown 'AVRをパワーダウン・モードに移行する。 ' Disable Pcint2 'ピン変化割り込み2を禁止する。 Reset Mcucr.pud '内部プルアップを許可する。 Enable Oc0a 'TIMER0比較一致A割り込みを許可する。 Enable Oc0b 'TIMER0比較一致B割り込みを許可する。 Set Ucr.rxen0 'USART受信を許可する。 ' Waitms 30 '起動時のUSARTの受信終了を待つ。 Clear Serialin 'シリアル入力バッファを初期化する。 ' Case Is < &H60 : '[41-5F] Temp2 = Temp1 - &H40 '輝度制御。 Temp2 = Temp2 + Temp2 If Temp2 > 58 Then 'If 最高輝度か? Then Temp2 = 58 End If Ocr0b = Temp2 '輝度値をタイマーに設定する。 ' End Select End If Rxcount = 0 Return ' ' Rxdata4: '[BS(後退)],[DEL(削除)]の処理。 If Rxcount <> 0 Then Rxbuff(rxcount) = &H20 Rxcount = Rxcount - 1 End If Return ' ' ******************************************************* ' * ASCIIコードをセグメントデータに変換するサブルーチン * ' ******************************************************* ' Segconv: If Sysmode <> 0 Then Goto Segconv20 'If 周波数カウンター[3]モードか? Then ' If Swtemp = 0 Then 'If 桁スイッチがOFFか?Then Temp2 = 1 '受信バッファーの位置。 Else Temp2 = 17 '受信バッファーの位置。 End If ' Temp1 = 1 'LEDのDMAバッファー位置。 Segconv1: Temp3 = Dsbuff(temp2) - &H20 If Temp3 = &H0C Then Goto Segconv2 'If カンマ[,]か? Then If Temp3 = &H0E Then Goto Segconv3 'If ピリオド[.]か? Then Segconv5: Temp3 = Lookup(temp3 , Led_segdata) 'セグメント変換テーブルを参照する。 Led_buff(temp1) = Temp3 'LEDのDMAバッファーに書き込む。 Temp1 = Temp1 + 1 Segconv4: Temp2 = Temp2 + 1 If Temp1 < 13 Then Goto Segconv1 'If 12文字終了か? Else Return ' ' Segconv2: 'カンマ[,]の処理。 If Commaflg = 0 Then Goto Segconv4 'If カンマ[,]を無視か? Then If Commaflg = 1 Then Goto Segconv5 'If カンマ[,]を[D.P]で表示か? Then Gosub Segdps 'カンマ[,]を前文字の[D.P]で表示する。 Goto Segconv4 ' Segconv3: 'ピリオド[.]の処理。 If Periodflg = 0 Then Goto Segconv4 'If ピリオド[.]を無視か? Then If Periodflg = 1 Then Goto Segconv5 'If ピリオド[.]を[D.P]で表示か? Then Gosub Segdps 'ピリオド[.]を前文字の[D.P]で表示する。 Goto Segconv4 ' ' * カンマ[,]を前文字の[D.P]で表示するサブルーチン * ' Segdps: If Temp1 <> 1 Then 'If 1文字目以降か? Then Temp3 = Temp1 - 1 '左側文字の小数点を点灯させる。 Temp4 = Led_buff(temp3) #if Assembly = 0 '組立の選択。(0:制御基板と同方向, 1:制御基板とハンダ面合わせ) Set Temp4.6 #else Set Temp4.3 #endif Led_buff(temp3) = Temp4 End If Return ' ' ***************************** ' * 周波数カウンター[3]モード * ' ***************************** ' Segconv20: If Swtemp = 1 Then Goto Segconv30 'If 桁スイッチがONか?Then ' Temp1 = 1 'LEDのDMAバッファー位置。 Temp2 = 1 '受信バッファーの位置。 ' If Dsbuff(1) = &H20 Then 'If 1文字目がスペースか? Then If Dsbuff(6) <> &H2C Then 'If カンマ[,]が無いか? Then Temp2 = Temp2 + 1 End If If Dsbuff(10) <> &H2E Then 'If ピリオド[.]が無いか? Then Temp2 = Temp2 + 1 End If Else '1文字目が数値の場合。 If Dsbuff(2) = &H2C Then 'If [1MHz]台か? Then If Dsbuff(6) = &H2C Then Led_buff(1) = Lookup(&H00 , Led_segdata) '左端にスペースを表示する。 Temp1 = 2 'LEDのDMAバッファー位置。 End If End If End If ' Segconv21: Temp3 = Dsbuff(temp2) - &H20 If Temp3 <> &H0C Then 'If カンマ[,]以外か? Then If Temp3 = &H0E Then 'If ピリオド[.]か? Then Gosub Segdps 'ピリオド[.]を前文字の[D.P]で表示する。 Else Temp3 = Lookup(temp3 , Led_segdata) 'セグメント変換テーブルを参照する。 Led_buff(temp1) = Temp3 'LEDのDMAバッファーに書き込む。 Temp1 = Temp1 + 1 End If End If Temp2 = Temp2 + 1 If Temp1 < 12 Then Goto Segconv21 'If 11文字終了か? Else ' Led_buff(12) = Lookup(&H28 , Led_segdata) '右端に[H]を表示する。 Return ' ' Segconv30: Temp3 = Dsbuff(18) - &H20 '1文字目に測定周期を表示する。 Led_buff(1) = Lookup(temp3 , Led_segdata) Temp3 = Dsbuff(19) - &H20 '2文字目にプリスケール値を表示する。 Led_buff(2) = Lookup(temp3 , Led_segdata) Led_buff(3) = Lookup(&H00 , Led_segdata) '3文字目にスペースを表示する。 ' Temp1 = 4 'LEDのDMAバッファー位置。 If Dsbuff(26) = &H20 Then 'If [nS]台か? Then Temp2 = 22 '受信バッファーの位置。 Else Temp2 = 21 '受信バッファーの位置。 End If ' Segconv31: Temp3 = Dsbuff(temp2) - &H20 If Temp3 = &H0E Then 'If ピリオド[.]か? Then Gosub Segdps 'ピリオド[.]を前文字の[D.P]で表示する。 Else Temp3 = Lookup(temp3 , Led_segdata) 'セグメント変換テーブルを参照する。 Led_buff(temp1) = Temp3 'LEDのDMAバッファーに書き込む。 Temp1 = Temp1 + 1 End If Temp2 = Temp2 + 1 If Temp1 < 12 Then Goto Segconv31 'If 11文字終了か? Else ' Temp3 = Dsbuff(31) - &H20 Led_buff(12) = Lookup(temp3 , Led_segdata) '右端に単位を表示する。 Return ' ' ************************************************ ' * スイッチの状態を調べて表示を変更するルーチン * ' ************************************************ ' Swcheck: If Tifr2.ocf2a = 1 Then 'If 10mS経過したか? Then Set Tifr2.ocf2a 'Timer2 比較A一致フラグをリセット。 ' If Swtemp = 0 Then 'If 行表示が前半か? Then If Sw_1 = 0 Then 'スイッチが[ON]か? Then Swtemp = 1 Gosub Segconv 'ASCIIコードをセグメントデータに変換する。 End If Else If Sw_1 = 1 Then 'スイッチが[OFF]か? Then Swtemp = 0 Gosub Segconv 'ASCIIコードをセグメントデータに変換する。 End If End If End If Return ' ' ******************************************************* ' * ダイナミック点灯 コモン表示制御ルーチン(割り込み) * ' ******************************************************* ' #if Assembly = 0 '組立の選択。(0:制御基板と同方向, 1:制御基板とハンダ面合わせ) Ledcomset: Led_temp1 = Led_buff(led_counter + 1) 'セグメントデータを読み出す。 Led_segment = Led_temp1 'セグメント[d]以外を出力する。 If Led_temp1.0 = 0 Then 'If セグメント[d]は[0]か? Then Reset Led_segmentd Else Set Led_segmentd End If ' On Led_counter Goto Ledcom1 , Ledcom2 , Ledcom3 , Ledcom4 , Ledcom5 , Ledcom6 , Ledcom7 , Ledcom8 , Ledcom9 , Ledcom10 , Ledcom11 , Ledcom12 ' Ledcom1: Set Led_c1 Goto Ledcomend ' Ledcom2: Set Led_c2 Goto Ledcomend ' Ledcom3: Set Led_c3 Goto Ledcomend ' Ledcom4: Set Led_c4 Goto Ledcomend ' Ledcom5: Set Led_c5 Goto Ledcomend ' Ledcom6: Set Led_c6 Goto Ledcomend ' Ledcom7: Set Led_c7 Goto Ledcomend ' Ledcom8: Set Led_c8 Goto Ledcomend ' Ledcom9: Set Led_c9 Goto Ledcomend ' Ledcom10: Set Led_c10 Goto Ledcomend ' Ledcom11: Set Led_c11 Goto Ledcomend ' Ledcom12: Set Led_c12 ' Ledcomend: Led_counter = Led_counter + 1 'コモンカウンターを更新する。 If Led_counter > 11 Then 'If コモンカウンターが上限か? Then Led_counter = 0 End If Return ' ' #else Ledcomset: Led_temp1 = Led_buff(led_counter + 1) 'セグメントデータを読み出す。 Led_segment = Led_temp1 'セグメント[d]以外を出力する。 If Led_temp1.0 = 0 Then 'If セグメント[d]は[0]か? Then Reset Led_segmentd Else Set Led_segmentd End If ' On Led_counter Goto Ledcom1 , Ledcom2 , Ledcom3 , Ledcom4 , Ledcom5 , Ledcom6 , Ledcom7 , Ledcom8 , Ledcom9 , Ledcom10 , Ledcom11 , Ledcom12 ' Ledcom1: Set Led_c9 Goto Ledcomend ' Ledcom2: Set Led_c4 Goto Ledcomend ' Ledcom3: Set Led_c8 Goto Ledcomend ' Ledcom4: Set Led_c2 Goto Ledcomend ' Ledcom5: Set Led_c12 Goto Ledcomend ' Ledcom6: Set Led_c11 Goto Ledcomend ' Ledcom7: Set Led_c10 Goto Ledcomend ' Ledcom8: Set Led_c3 Goto Ledcomend ' Ledcom9: Set Led_c1 Goto Ledcomend ' Ledcom10: Set Led_c7 Goto Ledcomend ' Ledcom11: Set Led_c6 Goto Ledcomend ' Ledcom12: Set Led_c5 ' Ledcomend: Led_counter = Led_counter + 1 'コモンカウンターを更新する。 If Led_counter > 11 Then 'If コモンカウンターが上限か? Then Led_counter = 0 End If Return #endif ' ' ******************************************************* ' * ダイナミック点灯 コモン消灯制御ルーチン(割り込み) * ' ******************************************************* ' Ledcomoff: Led_common1 = &B0000_1000 Led_common2 = 0 ' Led_segment = 0 Return ' ' ************************************************ ' * シリアルポートのピン変化割り込み処理ルーチン * ' ************************************************ ' Sinint: Return '何も処理しない。 ' ' End ' ' ****************************************************** ' * ASCII文字コード → セグメント・データ 変換テーブル * ' ****************************************************** ' #if Assembly = 0 '組立の選択。(0:制御基板と同方向, 1:制御基板とハンダ面合わせ) Led_segdata: Data &H00 , &H02 , &H08 , &H84 , &H12 , &H20 , &H04 , &H03 ' !”#$%&’ Data &H27 , &H8B , &H0C , &HA0 , &H40 , &H10 , &H40 , &H38 '()*+,-./ Data &HAF , &H88 , &H3B , &H9B , &H9C , &H97 , &HB7 , &H8A '01234567 Data &HBF , &H9F , &H0A , &H21 , &H06 , &H11 , &H81 , &H94 '89:;<=>? Data &HBB , &HBE , &HB5 , &H31 , &HB9 , &H37 , &H36 , &HA7 '@ABCDEFG Data &HB4 , &H80 , &HA9 , &HB6 , &H25 , &HAE , &HB0 , &HB1 'HUJKLMNO Data &H3E , &H9E , &H30 , &H95 , &H35 , &HA1 , &HAD , &H0D 'PQRSTUVW Data &HBC , &H9D , &H2B , &H14 , &H1C , &H18 , &H0E , &H01 'XYZ[\]^_ Data &HAC , &HBE , &HB5 , &H31 , &HB9 , &H37 , &H36 , &HA7 '`abcdefg Data &HB4 , &H80 , &HA9 , &HB6 , &H25 , &HAE , &HB0 , &HB1 'hijklmno Data &H3E , &H9E , &H30 , &H95 , &H35 , &HA1 , &HAD , &H0D 'pqrstuvw Data &HBC , &H9D , &H2B , &H1E , &H28 , &H90 , &H98 , &H34 'xyz{|} ' ' #else Led_segdata: Data &H00 , &H20 , &H40 , &H11 , &HA0 , &H02 , &H01 , &H24 ' !”#$%&’ Data &H27 , &H74 , &H41 , &H12 , &H08 , &H80 , &H08 , &HC2 '()*+,-./ Data &H77 , &H50 , &HE6 , &HF4 , &HD1 , &HB5 , &HB7 , &H70 '01234567 Data &HF7 , &HF5 , &H60 , &H06 , &H21 , &H84 , &H14 , &H91 '89:;<=>? Data &HF6 , &HF3 , &H97 , &H86 , &HD6 , &HA7 , &HA3 , &H37 '@ABCDEFG Data &H93 , &H10 , &H56 , &HB3 , &H07 , &H73 , &H92 , &H96 'HUJKLMNO Data &HE3 , &HF1 , &H82 , &H95 , &H87 , &H16 , &H57 , &H45 'PQRSTUVW Data &HD3 , &HD5 , &H66 , &H81 , &HC1 , &HC0 , &H61 , &H04 'XYZ[\]^_ Data &H53 , &HF3 , &H97 , &H86 , &HD6 , &HA7 , &HA3 , &H37 '`abcdefg Data &H93 , &H10 , &H56 , &HB3 , &H07 , &H73 , &H92 , &H96 'hijklmno Data &HE3 , &HF1 , &H82 , &H95 , &H87 , &H16 , &H57 , &H45 'pqrstuvw Data &HD3 , &HD5 , &H66 , &HE1 , &H42 , &H90 , &HD0 , &H83 'xyz{|} #endif