' ' **************************************** ' * * ' * 富くじ夢想猫 プログラム * ' * * ' * AVR is using ATtiny861A * ' * Basic Compiler is BASCOM-AVR * ' * 2012. 2.24 * ' **************************************** ' ' Ver 01.01 初回公開バージョン。 2012. 2.24 ' $regfile = "ATtiny861.DAT" '使用するAVRを設定。 $crystal = 8000000 'AVRクロックを設定。 ' $hwstack = 64 'ハードウェア・スタックの容量を設定。 $swstack = 10 'ソフトウェア・スタックの容量を設定。 $framesize = 24 'フレーム領域の容量を設定。 ' ' * ポート名の定義 * ' Sw_1 Alias Pinb.4 'スイッチ[1]の接続ポート。 Sw_1pu Alias Portb.4 'スイッチ[1]の接続ポート(プルアップ用)。 Led_f1 Alias Portb.0 'LED[C1]のコモン接続ポート。 Led_if1 Alias 0 Led_f2 Alias Portb.1 'LED[C2]のコモン接続ポート。 Led_if2 Alias 1 Led_f3 Alias Portb.2 'LED[C3]のコモン接続ポート。 Led_if3 Alias 2 Led_f4 Alias Portb.3 'LED[C4]のコモン接続ポート。 Led_if4 Alias 3 Led_ifp Alias Portb 'LEDのコモン接続ポート。 Led_maskbit Alias &B1111_0000 'LEDのコモン・マスクビット。 Led_seg Alias Porta 'LEDのセグメント接続ポート。 Sp_in Alias Pinb.5 'スピーカー入力の接続ポート。 Sp_out Alias Portb.5 'スピーカー出力の接続ポート。 Ad_sp Alias 8 'スピーカー入力用 A/Dコンバータのチャネル番号。 ' ' * 変数の宣言 * ' Dim Ledcounter As Byte 'ダイナミック点灯の桁カウンター。 Dim Ledbuff(4) As Byte 'ダイナミック点灯のセグメントデータ。 Dim Bright(4) As Byte 'LEDの輝度調整値(Timer値)。 Dim Int1msf As Byte '1mS経過フラグ。 Dim Int1mscun As Word '1mSカウンター。 Dim Intwaitf As Byte 'ダイナミック点灯中フラグ。 Dim Swintf As Byte 'スイッチ割り込みフラグ。 Dim Numselect As Byte 'くじの種類。(3〜6) Dim Miclevel As Word 'マイク入力の最小レベル。(ノイズレベル) Dim Tim1carry As Byte '乱数タイマー(Timer1)のキャリーカウント数。 Dim Clapcount As Byte '拍手の回数。 Dim Resultnum4 As Word '4桁の予想結果。 Dim Result6(6) As Byte '2桁の予想結果。 Dim ___rseed As Word '乱数用の種。 ' 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 Dim Temp5 As Byte '汎用テンポラリ変数 Byte型 No.5 Dim Temp6 As Byte '汎用テンポラリ変数 Byte型 No.6 Dim Temp7 As Byte '汎用テンポラリ変数 Byte型 No.7 Dim Tempw1 As Word '汎用テンポラリ変数 Word型 No.1 Dim Tempw2 As Word '汎用テンポラリ変数 Word型 No.2 Dim Tempw3 As Word '汎用テンポラリ変数 Word型 No.3 Dim Tempseg1 As Byte 'セグメントデータ保管用 (1桁) Dim Tempseg2 As Byte 'セグメントデータ保管用 (10桁) Dim Tempseg3 As Byte 'セグメントデータ保管用 (100桁) Dim Tempseg4 As Byte 'セグメントデータ保管用 (1000桁) ' Dim Dummy As Eram Long 'EEPROM 4バイトのダミーエリア。 Dim Eepclapoffset As Eram Byte 'EEPROM 拍手のしきい値オフセット。(10:高感度〜90:低感度) Config Clockdiv = 1 'AVRの動作クロックを8MHzに変更する。 ' ' * ポートの初期設定 * ' Set Didr1.adc8d 'デジタル入力禁止レジスタの設定。(PB5) Set Prr.prusi '電力削減 USI回路の停止。 Config Led_seg = Output 'LEDのセグメント接続ポートを出力に設定する。 Config Led_f1 = Output 'LED[C1]のコモン接続ポートを出力に設定する。 Config Led_f2 = Output 'LED[C2]のコモン接続ポートを出力に設定する。 Config Led_f3 = Output 'LED[C3]のコモン接続ポートを出力に設定する。 Config Led_f4 = Output 'LED[C4]のコモン接続ポートを出力に設定する。 Config Sp_out = Output 'スピーカー出力の接続ポートを出力に設定する。 Set Sw_1pu 'スイッチ[1]の接続ポートをプルアップ。 Set Portb.6 '未使用ポートをプルアップする。 ' ' * A/Dコンバーターの設定 * ' Config Adc = Single , Prescaler = 16 , Reference = Internal_1.1 'A/Dコンバータの設定。 ' Config Aci = Off 'アナログ比較器の電源を切る。(BASCOMのバグ有り) Set Acsra.acd 'アナログ比較器の電源を切る。 ' ' * Timerの設定 * ' Config Timer0 = Timer , Prescale = 64 , Clear Timer = 1 'LEDダイナミック点灯 1mSタイマー 8,000,000Hz / 64 = 125,000Hz Tccr0a = &B0000_0001 '[CTC0]ビットを[1]にする。(8ビットCTC動作) Compare0a = 125 - 1 'スキャン周波数。(125,000Hz ÷ 125カウント = 1,000Hz) Compare0b = 120 'パルス幅 (暗0〜明123) 1カウントは8μS。 On Compare0a Tint0a Nosave 'TIMER0比較一致A割り込みルーチンのラベルを設定。 Enable Compare0a 'TIMER0比較一致A割り込みを許可。 On Compare0b Tint0b Nosave 'TIMER0比較一致B割り込みルーチンのラベルを設定。 Enable Compare0b 'TIMER0比較一致B割り込みを許可。 ' Tccr1d = &B0000_0000 'Config Timer1 = Timer (標準動作) Tccr1b = &B0000_0001 'Prescale = 1 (8,000,000Hz / 1 = 125nS) Tccr1a = &B0000_0000 Tccr1c = &B0000_0000 Tc1h = &H03 '[999]カウントを比較器C に書き込む。 Ocr1c = &HE7 ' ' * スイッチ割り込みの設定 * ' Pcmsk0 = &B0000_0000 Pcmsk1 = &B0001_0000 'PB4[PCINT12]を許可する。 On Pcint Swint Nosave 'スイッチ割り込みルーチンのラベルを設定。 ' ' * 変数の初期値を設定 * ' Bright(1) = 120 'LEDの輝度。(暗0〜明123) Bright(2) = 120 Bright(3) = 120 Bright(4) = 120 Numselect = 3 'くじの初期値。 Enable Interrupts 'すべての割り込みを許可。 ' ' * マイク感度の設定確認 * ' If Eepclapoffset > 90 Then 'If EEPROMが初期値か? Then Eepclapoffset = 20 '初期値をセットする。 End If ' If Sw_1 = 0 Then Goto Micgain 'If マイク感度設定モードか? Then ' ' ******************* ' * メイン ルーチン * ' ******************* ' Main: Ledbuff(1) = 0 '表示を消す。 Ledbuff(2) = 0 Ledbuff(3) = 0 Ledbuff(4) = 0 Config Sp_out = Output 'スピーカー出力の接続ポートを出力に設定する。 Reset Sp_out Stop Adc 'A/Dコンバータの電源を切る。 Stop Timer0 'LEDのダイナミック点灯を停止する。 Led_seg = 0 'LEDのセグメントをすべてOFFにする。 Reset Led_f1 'LED[C1]のコモンをOFFにする。 Reset Led_f2 'LED[C2]のコモンをOFFにする。 Reset Led_f3 'LED[C3]のコモンをOFFにする。 Reset Led_f4 'LED[C4]のコモンをOFFにする。 Set Gifr.pcif 'ピン変化割り込みフラグをリセットする。 Set Gimsk.pcie1 'Enable Pcint1 ピン変化割込を許可する。 ' Power Powerdown 'スリープモードへ移行する。(スイッチ割り込みで再起動する) ' Start Timer0 'LEDダイナミック点灯を開始する。 Start Adc 'A/Dコンバータに電源を供給。 ' ' * 鈴音の発生 * ' Main1: Config Sp_out = Output 'スピーカー出力の接続ポートを出力に設定する。 Temp1 = 139 '発音周波数 = 3,600Hz[-] Temp2 = 0 For Tempw1 = 1 To 500 Waitus Temp1 Toggle Sp_out Temp2 = Temp2 + 1 If Temp2 > 100 Then 'If 周波数を下げる時間か? Then Temp2 = 0 Temp1 = Temp1 + 1 End If Next Tempw1 ' Waitms 100 '休止時間。 ' Temp1 = 128 '発音周波数 = 3,900Hz[+] Temp2 = 0 For Tempw1 = 1 To 1000 Waitus Temp1 Toggle Sp_out Temp2 = Temp2 + 1 If Temp2 > 150 Then 'If 周波数を上げる時間か? Then Temp2 = 0 Temp1 = Temp1 - 1 End If Next Tempw1 Reset Sp_out ' Bitwait Sw_1 , Set '[SW1]が離されるまで待つ。 Swintf = 0 ' ' * 目鼻をフェードイン表示する * ' Temp1 = Lookup(numselect , Segtab) 'くじの種類を表示する。 Ledbuff(1) = Temp1 Or &B1000_0000 '[D.P]を表示する。 Ledbuff(2) = &B0100_0000 '目(閉じる)鼻を表示する。 Ledbuff(3) = &B0101_0100 Ledbuff(4) = &B0100_0000 Temp2 = 0 For Temp1 = 0 To 120 Bright(1) = Temp1 '種類の輝度。(暗0〜明123) Temp2 = Temp1 / 3 Bright(2) = Temp2 '目鼻の輝度。(暗0〜明123) Bright(3) = Temp2 Bright(4) = Temp2 Waitms 5 Next Temp1 ' Config Sp_out = Input 'スピーカーをマイクに変更。 ' ' * 雑音レベルをチェックする * ' Miclevel = 0 For Temp1 = 0 To 250 Dmawait1: If Intwaitf <> &HFF Then Goto Dmawait1 'If ダイナミック点灯中か? Then Disable Interrupts 'すべての割り込みを禁止。 Tempw1 = Getadc(ad_sp) 'マイク入力をA/D変換する。 Enable Interrupts 'すべての割り込みを許可。 If Tempw1 > Miclevel Then '雑音レベルが上がったか? Then Miclevel = Tempw1 End If Waitus 100 Next Temp1 ' If Miclevel > 50 Then 'If ノイズが多すぎるか? Then Miclevel = 30 End If ' Temp1 = Eepclapoffset 'ノイズレベルにオフセットを加算し「しきい値」を決める。 Miclevel = Miclevel + Temp1 Int1mscun = 0 'タイムアウトのカウント値をクリアする。 Clapcount = 0 '拍手の回数をクリアする。 ' ' * 拍手を検出する * ' Main2: If Intwaitf <> &HFF Then Goto Main2 'If ダイナミック点灯中か? Then Disable Interrupts 'すべての割り込みを禁止。 Tempw1 = Getadc(ad_sp) 'マイク入力をA/D変換する。 Enable Interrupts 'すべての割り込みを許可。 ' If Sw_1 = 0 Then Goto Sw1in 'If [SW1]が押されたか? Then If Tempw1 > Miclevel Then Goto Claphand 'If 手を叩いたか? Then ' If Tifr.tov1 = 1 Then 'If 乱数用タイマーのキャリーオーバーか? Then Tifr = &B0000_0100 'Timer1 オーバーフローフラグ[TOV1]をリセットする。 Tim1carry = Tim1carry + 1 If Tim1carry > 9 Then 'If [9999]を越えたか? Then Tim1carry = 0 End If End If ' If Int1msf <> &HFF Then 'If 1mS経過したか? Then Int1msf = &HFF Int1mscun = Int1mscun + 1 '1mSタイマーをカウントする。 End If ' If Int1mscun >= 20000 Then Goto Main 'If 20秒経過したか? Then Goto Main2 ' ' * [SW1]が押された場合 * ' Sw1in: Numselect = Numselect + 1 If Numselect > 6 Then 'If 上限か? Then Numselect = 3 End If Ledbuff(1) = 0 '表示を消す。 Ledbuff(2) = 0 Ledbuff(3) = 0 Ledbuff(4) = 0 Goto Main1 ' ' * 拍手を検出した場合 * ' Claphand: For Temp1 = 1 To 50 '拍手の波形値を乱数の拡散に使用する。 Tempw2 = Getadc(ad_sp) 'マイク入力をA/D変換する。 Tempw1 = Tempw1 + Tempw2 Next Temp1 Temp1 = Tcnt1 Temp2 = Tc1h Tempw2 = Makeint(temp1 , Temp2) '3桁の予想結果。 Tempw1 = Tempw1 + Tempw2 Tc1h = High(tempw1) 'タイマー値を拡散する。 Tcnt1 = Low(tempw1) ' Clapcount = Clapcount + 1 '拍手の回数を加算する。 If Clapcount = 2 Then Goto Expect '予想開始か? Then ' Bright(4) = 0 '右目を開ける。 Ledbuff(4) = &B0110_0011 For Temp1 = 0 To 30 Bright(4) = Temp1 '右目の輝度。(暗0〜明123) Waitms 15 Next Temp1 Goto Main2 ' ' * 予想の開始 * ' Expect: Temp1 = Tcnt1 Temp2 = Tc1h If Tifr.tov1 = 1 Then 'If 乱数用タイマーのキャリーオーバーか? Then Tifr = &B0000_0100 'Timer1 オーバーフローフラグ[TOV1]をリセットする。 Tim1carry = Tim1carry + 1 If Tim1carry > 9 Then 'If [9999]を越えたか? Then Tim1carry = 0 End If End If Tempw2 = Makeint(temp1 , Temp2) '[3桁]の予想結果。 Tempw1 = Tim1carry Tempw1 = Tempw1 * 1000 Resultnum4 = Tempw1 + Tempw2 '[4桁]の予想結果。 ' ___rseed = ___rseed + Resultnum4 '乱数の種を拡散する。 For Temp1 = 1 To 6 '結果のバッファーをすべてクリアする。 Result6(temp1) = 0 Next Temp1 ' Select Case Numselect '[5]数字と[6]数字の発生。 Case 5 : '[5]数字の場合。 For Temp1 = 1 To 5 Expect1: Tempw1 = Rnd(&Hffff) 'RND関数に問題が有るための暫定処理。 Rotate Tempw1 , Right , 9 Temp4 = Tempw1 Mod 31 '0-30の乱数を発生させる。 Temp4 = Temp4 + 1 '1〜31に変更する。 Temp3 = 0 For Temp2 = 1 To 5 '同数を確認する。 If Result6(temp2) = Temp4 Then 'If 同数か? Then Temp3 = 1 End If Next Temp2 If Temp3 <> 0 Then Goto Expect1 'If 同数が有ったか? Then Result6(temp1) = Temp4 Next Temp1 ' Case 6 : '[6]数字の場合。 For Temp1 = 1 To 6 Expect2: Tempw1 = Rnd(&Hffff) 'RND関数に問題が有るための暫定処理。 Rotate Tempw1 , Right , 9 Temp4 = Tempw1 Mod 43 '0-42の乱数を発生させる。 Temp4 = Temp4 + 1 '1〜43に変更する。 Temp3 = 0 For Temp2 = 1 To 6 '同数を確認する。 If Result6(temp2) = Temp4 Then 'If 同数か? Then Temp3 = 1 End If Next Temp2 If Temp3 <> 0 Then Goto Expect2 'If 同数が有ったか? Then Result6(temp1) = Temp4 Next Temp1 End Select ' Bright(2) = 0 '左目を開ける。 Ledbuff(2) = &B0110_0011 For Temp1 = 0 To 30 Bright(2) = Temp1 '左目の輝度。(暗0〜明123) Waitms 15 Next Temp1 ' Config Sp_out = Output 'スピーカー出力の接続ポートを出力に設定する。 Tempw1 = 385 '発音周波数 = 1,300Hz[-] Temp2 = 0 For Tempw2 = 1 To 1000 Waitus Tempw1 Toggle Sp_out Temp2 = Temp2 + 1 If Temp2 > 15 Then 'If 周波数を下げる時間か? Then Temp2 = 0 Tempw1 = Tempw1 + 1 End If Next Tempw2 ' ' * 思案中の表示 * ' Temp2 = 120 '種類の輝度を下げて目鼻の輝度を上げる。 For Temp1 = 30 To 120 Bright(2) = Temp1 '目鼻の輝度。(暗0〜明123) Bright(3) = Temp1 Bright(4) = Temp1 Bright(1) = Temp2 '種類の輝度。(暗0〜明123) Temp2 = Temp2 - 1 Waitms 5 Next Temp1 ' For Temp5 = 120 To 0 Step -1 '目の輝度を下げる。 Bright(2) = Temp5 '目の輝度。(暗0〜明123) Bright(4) = Temp5 Waitms 5 Next Temp5 ' Tempw1 = Rnd(&Hffff) 'RND関数に問題が有るための暫定処理。 Rotate Tempw1 , Right , 9 Temp3 = Tempw1 Mod 8 '0-7の乱数を発生させる。 ' Temp6 = 0 For Temp1 = 1 To 2 Select Case Temp3 '思案中の顔データを選択する。 Case 0 : Restore Facedata1 Case 1 : Restore Facedata2 Case 2 : Restore Facedata3 Case 3 : Restore Facedata4 Case 4 : Restore Facedata5 Case 5 : Restore Facedata6 Case 6 : Restore Facedata7 Case Else : Restore Facedata8 End Select ' Bright(2) = 0 '目の輝度。(暗0〜明123) Bright(4) = 0 For Temp2 = 1 To 4 '思案中の顔を変化させる。 Read Temp4 Ledbuff(2) = Temp4 Read Temp4 Ledbuff(4) = Temp4 ' For Temp5 = 0 To 120 '目の輝度を上げる。 Bright(2) = Temp5 '目の輝度。(暗0〜明123) Bright(4) = Temp5 Waitus 2500 Next Temp5 ' Temp6 = 0 Temp7 = 3 For Temp5 = 120 To 0 Step -1 '目の輝度を下げる。 Bright(2) = Temp5 '目の輝度。(暗0〜明123) Bright(4) = Temp5 Temp6 = Temp6 + 1 'ゴロゴロ音の発音。 If Temp6 > Temp7 Then Toggle Sp_out Temp6 = 0 Temp7 = Temp7 + 1 End If Waitus 2500 Next Temp5 Next Temp2 Next Temp1 ' Wait 1 Ledbuff(2) = &H3F '目を見開く。 Ledbuff(4) = &H3F Bright(2) = 120 '目の輝度。(暗0〜明123) Bright(4) = 120 ' Temp1 = 116 '発音周波数 = 4,000Hz[-] Temp2 = 0 For Tempw1 = 1 To 4000 Waitus Temp1 Toggle Sp_out Temp2 = Temp2 + 1 If Temp2 > 150 Then 'If 周波数を下げる時間か? Then Temp2 = 0 Temp1 = Temp1 + 1 End If Next Tempw1 Reset Sp_out ' For Temp1 = 120 To 0 Step -1 '全ての輝度を下げる。 Bright(2) = Temp1 '目の輝度。(暗0〜明123) Bright(3) = Temp1 Bright(4) = Temp1 Temp2 = Temp1 / 4 Bright(1) = Temp2 '種類の輝度。(暗0〜明123) Waitms 10 Next Temp1 ' ' * 予想結果の表示 * ' Waitms 500 Temp6 = 1 'くじの種類が[5〜6]の場合のカウント数。 If Numselect > 4 Then Goto Resdisp51 'If くじの種類が[5〜6]か? Then ' Tempw1 = Resultnum4 'くじの種類が[3〜4]の場合。 Gosub Wordseg 'Word値を4桁のセグメント値に変換する。 If Numselect = 3 Then 'If くじの種類が[3]か? Then Ledbuff(1) = 0 Else 'くじの種類が[4]の場合。 Ledbuff(1) = Tempseg4 End If Ledbuff(2) = Tempseg3 Ledbuff(3) = Tempseg2 Ledbuff(4) = Tempseg1 ' Resdisp1: For Temp1 = 0 To 120 '予想値を表示し輝度を上げる。 Bright(1) = Temp1 Bright(2) = Temp1 Bright(3) = Temp1 Bright(4) = Temp1 Waitms 20 Next Temp1 ' ' * 次の入力を待つ * ' Config Sp_out = Input 'スピーカーをマイクに変更。 Int1mscun = 0 'タイムアウトのカウント値をクリアする。 Resdisp31: If Intwaitf <> &HFF Then Goto Resdisp31 'If ダイナミック点灯中か? Then Disable Interrupts 'すべての割り込みを禁止。 Tempw1 = Getadc(ad_sp) 'マイク入力をA/D変換する。 Enable Interrupts 'すべての割り込みを許可。 ' If Sw_1 = 0 Then Goto Sw1in 'If [SW1]が押されたか? Then If Tempw1 > Miclevel Then Goto Resdisp2 'If 手を叩いたか? Then ' If Tifr.tov1 = 1 Then 'If 乱数用タイマーのキャリーオーバーか? Then Tifr = &B0000_0100 'Timer1 オーバーフローフラグ[TOV1]をリセットする。 Tim1carry = Tim1carry + 1 If Tim1carry > 9 Then 'If [9999]を越えたか? Then Tim1carry = 0 End If End If ' If Int1msf <> &HFF Then 'If 1mS経過したか? Then Int1msf = &HFF Int1mscun = Int1mscun + 1 '1mSタイマーをカウントする。 End If ' If Int1mscun >= 20000 Then Goto Main 'If 20秒経過したか? Then Goto Resdisp31 ' ' * 手を叩いた場合 * ' Resdisp2: If Numselect < 5 Then Goto Main1 'If くじの種類が[3〜4]か? Then ' Temp6 = Temp6 + 1 If Numselect = 5 Then 'If くじの種類が[5]か? Then If Temp6 > 5 Then Goto Main1 'If 表示が最終か? Then Else If Temp6 > 6 Then Goto Main1 'If 表示が最終か? Then End If ' Config Sp_out = Output 'スピーカー出力の接続ポートを出力に設定する。 Tempw1 = 625 '発音周波数 = 400Hz[-] For Tempw2 = 1 To 200 Waitus Tempw1 Toggle Sp_out Tempw1 = Tempw1 + 1 Next Tempw2 ' For Temp1 = 120 To 0 Step -1 '全ての輝度を下げる。 Bright(1) = Temp1 Bright(2) = Temp1 Bright(3) = Temp1 Bright(4) = Temp1 Waitms 10 Next Temp1 ' ' * くじの種類が[5〜6]の場合 * ' Resdisp51: Temp1 = Result6(temp6) Gosub Binseg 'バイナリ値を2桁のセグメントコードに変換する。 If Temp1 < 10 Then 'If 10以下か? Then Ledbuff(3) = 0 Else Ledbuff(3) = Tempseg2 End If Ledbuff(4) = Tempseg1 Ledbuff(1) = Lookup(temp6 , Segtab) '数値をセグメントコードへ変換する。 Ledbuff(2) = &H40 'ハイフンを表示する。 Goto Resdisp1 ' ' --------------------------------------------------- ' * Word値を4桁のセグメント値に変換するサブルーチン * (Tempw1 -> Tempseg4 , Tempseg3 , Tempseg2 , Tempseg1) ' --------------------------------------------------- ' Wordseg: Tempw2 = Tempw1 / 100 '100の位を抽出する。 Tempw3 = Tempw2 * 100 '10と1の位を抽出する。 Tempw3 = Tempw1 - Tempw3 ' Temp1 = Tempw2 '100の位を変換する。 Gosub Binseg 'バイナリ値を2桁のセグメントコードに変換する。 Tempseg4 = Tempseg2 Tempseg3 = Tempseg1 Temp1 = Tempw3 '10と1の位を変換する。 Gosub Binseg 'バイナリ値を2桁のセグメントコードに変換する。 Return ' --------------------------------------- (Temp1 = バイナリ・データ) ' * バイナリ値を2桁のセグメントコードに * (Tempseg1 = 下位のセグメントコード) ' * 変換するサブルーチン * (Tempaeg2 = 上位のセグメントコード) ' --------------------------------------- ' Binseg: Tempseg2 = Makebcd(temp1) 'バイナリ値をBCD(Binary coded decimal)値に変換。 Tempseg1 = Tempseg2 And &H0F '下位のBCDコードを取得。 Tempseg1 = Lookup(tempseg1 , Segtab) '数値をセグメントコードへ変換する。 ' Tempseg2 = Tempseg2 And &HF0 '上位のBCDコードを取得。 Shift Tempseg2 , Right , 4 '下位へ移動する。 Tempseg2 = Lookup(tempseg2 , Segtab) '数値をセグメントコードへ変換する。 Return ' ' ******************** ' * マイク感度の設定 * ' ******************** ' Micgain: Ledbuff(1) = &H3F '[OF.]を表示する。 Ledbuff(2) = &HF1 Micgain1: Temp1 = Eepclapoffset 'オフセット値を表示する。 Gosub Binseg 'バイナリ値を2桁のセグメントコードに変換する。 Ledbuff(3) = Tempseg2 Ledbuff(4) = Tempseg1 ' Bitwait Sw_1 , Set 'スイッチが離されるまで待つ。 Waitms 30 'チャタリングの待ち時間。 ' Micgain2: Debounce Sw_1 , 0 , Micgain3 'If スイッチが押されたか? Then Goto Micgain2 ' ' Micgain3: Temp1 = Eepclapoffset 'オフセット値を加算する。 Temp1 = Temp1 + 10 If Temp1 > 90 Then 'If 上限か? Then Temp1 = 10 End If Eepclapoffset = Temp1 Goto Micgain1 ' ' *************************************** ' * TIMER0 比較一致(A) 割り込みルーチン * ' *************************************** ' $notransform On 'R23またはR0を使用する命令に自動修正させない。 ' $asm Tint0a: PUSH R1 IN R1,SREG 'ステータス・レジスタを待避。 PUSH R24 PUSH R25 PUSH ZL PUSH ZH ; LDI ZL,Low(Tintjpt) 'LEDの桁に合わせて分岐する。 LDI ZH,High(Tintjpt) LDS R24,{LEDcounter} CLR R25 ADD ZL,R24 ADC ZH,R25 IJMP ; Tintjpt: RJMP Tintcom1 'ジャンプ・テーブル。 RJMP Tintcom2 RJMP Tintcom3 RJMP Tintcom4 ; Tintcom1: '[C1]の場合。 LDS R25,{Bright(1)} '桁ごとの輝度を設定する。 Out Ocr0b , R25 'TIMER0の比較器Bにパルス幅を設定する。 LDS R25,{LEDbuff(1)} 'セグメントデータをセットする。 Out Led_seg , R25 SBI LED_ifp,led_if1 'LEDの[C1]接続ポートをONにする。 RJMP Tintjpend ; Tintcom2: '[C2]の場合。 LDS R25,{Bright(2)} '桁ごとの輝度を設定する。 Out Ocr0b , R25 'TIMER0の比較器Bにパルス幅を設定する。 LDS R25,{LEDbuff(2)} 'セグメントデータをセットする。 Out Led_seg , R25 SBI LED_ifp,led_if2 'LEDの[C2]接続ポートをONにする。 RJMP Tintjpend ; Tintcom3: '[C3]の場合。 LDS R25,{Bright(3)} '桁ごとの輝度を設定する。 Out Ocr0b , R25 'TIMER0の比較器Bにパルス幅を設定する。 LDS R25,{LEDbuff(3)} 'セグメントデータをセットする。 Out Led_seg , R25 SBI LED_ifp,led_if3 'LEDの[C3]接続ポートをONにする。 RJMP Tintjpend ; Tintcom4: '[C4]の場合。 LDS R25,{Bright(4)} '桁ごとの輝度を設定する。 Out Ocr0b , R25 'TIMER0の比較器Bにパルス幅を設定する。 LDS R25,{LEDbuff(4)} 'セグメントデータをセットする。 Out Led_seg , R25 SBI LED_ifp,led_if4 'LEDの[C4]接続ポートをONにする。 ; Tintjpend: INC R24 'ダイナミック点灯の桁カウンターを更新する。 ANDI R24,$03 STS {LEDcounter},R24 STS {Int1msf},R24 '1mS経過フラグをセットする。 STS {Intwaitf},R24 'ダイナミック点灯中フラグをONにする。 ; POP ZH POP ZL POP R25 POP R24 Out Sreg , R1 'ステータス・レジスタを復帰 POP R1 RETI $end Asm ' ' *************************************** ' * TIMER0 比較一致(B) 割り込みルーチン * ' *************************************** ' $asm Tint0b: PUSH R1 IN R1,SREG 'ステータス・レジスタを待避。 PUSH R24 ; IN R24,Led_ifp '全ての桁のコモン信号をオフにする。 ANDI R24,Led_maskbit Out Led_ifp , R24 LDI R24,$FF STS {Intwaitf},R24 'ダイナミック点灯中フラグをOFFにする。 ; POP R24 Out Sreg , R1 'ステータス・レジスタを復帰 POP R1 RETI $end Asm ' ' **************************** ' * スイッチ割り込みルーチン * ' **************************** ' $asm Swint: PUSH R1 IN R1,SREG 'ステータス・レジスタを待避。 PUSH R24 ; IN R24,Gimsk 'Enable Pcint1 ピン変化割込を禁止する。 ANDI R24,$DF Out Gimsk , R24 LDI R24,$FF STS {Swintf},R24 'スイッチ割り込みフラグをセットする。 ; POP R24 Out Sreg , R1 'ステータス・レジスタを復帰 POP R1 RETI $end Asm ' ' $notransform Off ' ' End ' ' ***************************************** ' * LEDのセグメントコードへの変換テーブル * ' ***************************************** ' Segtab: Data &B0011_1111 '0 Data &B0000_0110 '1 Data &B0101_1011 '2 Data &B0100_1111 '3 Data &B0110_0110 '4 Data &B0110_1101 '5 Data &B0111_1101 '6 Data &B0000_0111 '7 Data &B0111_1111 '8 Data &B0110_1111 '9 ' ' ******************** ' * 思案中の顔データ * ' ******************** ' Facedata1: Data &H23 , &H23 , &H43 , &H43 , &H62 , &H62 , &H61 , &H61 Facedata2: Data &H23 , &H23 , &H43 , &H61 , &H62 , &H62 , &H61 , &H43 Facedata3: Data &H23 , &H23 , &H43 , &H43 , &H23 , &H23 , &H61 , &H61 Facedata4: Data &H03 , &H21 , &H63 , &H21 , &H63 , &H63 , &H03 , &H63 Facedata5: Data &H63 , &H40 , &H40 , &H40 , &H40 , &H63 , &H63 , &H63 Facedata6: Data &H40 , &H40 , &H23 , &H23 , &H40 , &H40 , &H63 , &H63 Facedata7: Data &H03 , &H21 , &H03 , &H40 , &H40 , &H40 , &H40 , &H21 Facedata8: Data &H23 , &H23 , &H23 , &H40 , &H23 , &H23 , &H40 , &H23