' ' ********************************************** ' * 電子サイコロ プログラム * ' * * ' * AVR is using ATtiny13A * ' * Basic Compiler is BASCOM-AVR * ' * Copyright By O-Family 2011. 8.29 * ' ********************************************** ' ' Ver 1.01 初回公開バージョン。 2011. 8.29 ' Ver 1.02 [SLEEP]命令の記述を修正。 2020. 6.11 ' ' $regfile = "ATtiny13.DAT" '使用するAVRを設定。 $crystal = 1200000 'AVRクロックを設定。 ' $hwstack = 40 'ハードウェア・スタックの容量を設定。 $swstack = 8 'ソフトウェア・スタックの容量を設定。 $framesize = 8 'フレーム領域の容量を設定。 ' ' * 変数の宣言 * ' Dim Diceno As Byte 'サイコロの表示数(目)。 Dim Ddcun As Byte 'ダイナミック点灯カウンター。 ' Dim Temp1 As Byte '汎用テンポラリ変数 Byte型 No.1 Dim Temp2 As Byte '汎用テンポラリ変数 Byte型 No.2 Dim Temp3 As Byte '汎用テンポラリ変数 Byte型 No.3 Dim Tempw1 As Word '汎用テンポラリ変数 Word型 No.1 ' ' * ポート名の定義 * ' Sp_in Alias Pinb.2 'スピーカー入力の接続ポート。 Sp_out Alias Portb.2 'スピーカー出力の接続ポート。 Led_1 Alias Portb.3 '[LED1]の接続ポート。 Led_23 Alias Portb.1 '[LED2]と[LED3]の接続ポート。 Led_45 Alias Portb.0 '[LED4]と[LED5]の接続ポート。 Led_67 Alias Portb.4 '[LED6]と[LED7]の接続ポート。 ' ' * ハードウェアの初期設定 * ' Config Portb = Output 'ポートの初期設定を行う。 Portb = &B0000_0000 Config Aci = Off 'アナログ比較器の電源を切る。 ' Config Timer0 = Timer , Prescale = 8 , Clear Timer = 1 '1,200,000Hz / 8 = 150,000Hz Compare0a = 150 - 1 '150,000Hz / 1,000Hz(1mS) = 150カウント On Compare0a Tint1ms 'TIMER0比較一致A割り込みルーチンのラベルを設定する。 Enable Compare0a 'TIMER0比較一致A割り込みを許可する。 ' Config Adc = Single , Prescaler = Auto , Reference = Avcc 'A/Dコンバータの設定。 ' Pcmsk = &B0000_0100 'スピーカー入力のピン変化割り込みを許可する。 On Pcint0 Intspk Nosave 'スピーカー入力のピン変化割り込みルーチンを設定。 Enable Interrupts 'すべての割り込みを許可。 ' ' * メイン ルーチン * ' Main: ' ' * AVRをスリープに移行する * ' Stop Timer0 'タイマー0を停止させる。 Stop Adc 'A/Dコンバータの電源を切る。 Portb = &B0000_0000 '全てのポートを[L]にする。 Ddrb = &B0000_0000 '全てのポートを入力に変更する。 Set Gifr.pcif 'ピン変化割り込みをリセットする。 Enable Pcint0 'ピン変化割り込みを許可する。 ' Power Powerdown 'AVRをパワーダウン・モードに移行する。 Mcucr = &B0011_0000 '##### BASCOMのバグ ##### ! sleep ' ' * スピーカーをたたくとAVRがスリープから起動する * ' Start Adc 'A/Dコンバータの電源を入れる。 For Temp1 = 1 To 30 '衝撃の波形をA/D変換し、乱数にする。 Tempw1 = Getadc(1) Temp2 = Low(tempw1) Temp3 = Temp3 + Temp2 Next Temp1 Stop Adc 'A/Dコンバータの電源を切る。 Temp2 = Temp3 Mod 6 'サイコロの目を決定する。 ' Config Portb = Output 'ポートの初期設定を行う。 Diceno = 0 Start Timer0 'タイマー0を再始動させる。 ' Temp1 = Temp2 + 40 '目の表示を高速→低速へ変化させる。 Tempw1 = 10 '表示間隔タイマーの初期値。(mS) Main1: Sound Sp_out , 2 , 1000 '100Hzを20mS鳴らす。 If Diceno = 6 Then 'If 目が6か? Then Diceno = 1 Else Diceno = Diceno + 1 End If ' Waitms Tempw1 '表示間隔のタイマー。 Tempw1 = Tempw1 + 5 '表示間隔タイマーを増加させる。 Temp1 = Temp1 - 1 If Temp1 <> 0 Then Goto Main1 'If 転回表示が終了か? Else ' ' * 目の決定 * ' Sound Sp_out , 200 , 25 '4,000Hzを50mS鳴らす。 Waitms 100 Sound Sp_out , 2000 , 25 '4,000Hzを500mS鳴らす。 Wait 2 Goto Main ' ' * 1mSタイマー割り込み処理ルーチン * ' Tint1ms: Ddcun = Ddcun + 1 'ダイナミック点灯カウンターを更新する。 If Ddcun > 2 Then 'If ダイナミック点灯カウンターが最終値か? Then Ddcun = 0 End If ' On Diceno Goto Dno0 , Dno1 , Dno2 , Dno3 , Dno4 , Dno5 , Dno6 '表示目ごとの点灯処理。 ' Dno0: '消灯の場合。 Reset Led_1 Reset Led_23 Reset Led_45 Reset Led_67 Goto Dnoend ' Dno1: '表示目が[1]の場合。 If Ddcun <> 0 Then Goto Dno0 Set Led_1 Goto Dnoend ' Dno2: '表示目が[2]の場合。 If Ddcun <> 0 Then Goto Dno0 Set Led_23 Goto Dnoend ' Dno3: '表示目が[3]の場合。 If Ddcun = 2 Then Goto Dno0 If Ddcun = 0 Then Set Led_1 Reset Led_45 Else Reset Led_1 Set Led_45 End If Goto Dnoend ' Dno4: '表示目が[4]の場合。 If Ddcun = 2 Then Goto Dno0 If Ddcun = 0 Then Set Led_23 Reset Led_45 Else Reset Led_23 Set Led_45 End If Goto Dnoend ' Dno5: '表示目が[5]の場合。 Reset Led_67 Select Case Ddcun Case 0 : Set Led_1 Reset Led_23 Reset Led_45 Case 1 : Reset Led_1 Set Led_23 Reset Led_45 Case Else : Reset Led_1 Reset Led_23 Set Led_45 End Select Goto Dnoend ' Dno6: '表示目が[6]の場合。 Reset Led_1 Select Case Ddcun Case 0 : Set Led_23 Reset Led_45 Reset Led_67 Case 1 : Reset Led_23 Set Led_45 Reset Led_67 Case Else : Reset Led_23 Reset Led_45 Set Led_67 End Select ' Dnoend: Return ' ' * スピーカー入力のピン変化割り込み処理ルーチン * ' Intspk: $asm PUSH R1 IN R1,SREG 'ステータス・レジスタを待避。 PUSH R24 ' IN R24,GIMSK '[Disable Pcint0] ピン変化割り込みを禁止する。 ANDI R24,$DF Out Gimsk , R24 ' POP R24 Out Sreg , R1 'ステータス・レジスタを復帰 POP R1 $end Asm Return ' ' End