' ' ********************************************** ' * * ' * Mini Digital Photo frame Program * ' * Olimex MOD-NOKIA6610 LCD * ' * * ' * AVR is using ATmega328P * ' * Basic Compiler is BASCOM-AVR * ' * Copyright By O-Family 2010. 1.21 * ' ********************************************** ' ' Const Prgver = "01.01" 'プログラム・バージョン。 ' ' $regfile = "m328pdef.dat" '使用するAVRを設定。 $crystal = 12800000 'AVRクロックを設定。 ' $hwstack = 128 'ハードウェア・スタックの容量を設定。 $swstack = 128 'ソフトウェア・スタックの容量を設定。 $framesize = 128 'フレーム領域の容量を設定。 ' ' * 変数の宣言 * ' Dim Tint1sflg As Byte '1秒経過フラグ。 Dim Daychgf As Byte '日付変更フラグ。 Dim Monthlast As Byte '月の最終日。 Dim Mf1224h As Byte '[時]表示モード・フラグ 0=24時間制 / 1=12時間制 Dim Dispcont As Byte '表示制御モード。(0:強制スリープ, 1:常時オン, 2:センサー制御) Dim Dispmode As Byte '画面表示モード。(0:表示オフ, 1:設定中, 2:通常表示, 3:エラー画面) Dim Disptimsel As Byte '表示変更間隔の選択値。 Dim Dispchgtim As Word '表示変更間隔のタイマー設定値。 Dim Disptimer As Word '表示変更間隔タイマー。 Dim Photochgf As Byte '写真の変更要請を保留するフラグ。 Dim Sentime As Byte 'センサーONからの表示時間。(0:1分, 1:5分, 2:10分) Dim Powtime As Word 'センサーONからの表示時間タイマー値。 Dim Poffcun As Word 'センサーONからの表示時間カウンター。 Dim Keycun As Byte 'キー入力チェック用タイマーカウンター。 Dim Keyflg As Byte 'キー入力検出フラグ。 Dim Keydata As Byte 'キー入力データ。 Dim Keytemp As Byte 'キー入力用テンポラリ。 Dim Temperature As Integer '温度。 Dim Refadj As Byte 'AVR 1.1V基準電圧の校正値。(100〜120→1.00〜1.20V) Dim Totalfile As Word 'ファイルの総数。 Dim Dispfile As Word '表示するファイルの番号。 Dim Schlen As Byte 'スケジュール・データのブロック数。 Dim Strbuf(5) As String * 16 'スケジュール・データ用の文字バッファー。 Dim Timebuf(8) As Byte '時刻設定用のテンポラリ。 Dim Setcur 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 Dim Temp5 As Byte '汎用テンポラリ変数 Byte型 No.5 Dim Tempw1 As Word '汎用テンポラリ変数 Word型 No.1 Dim Templ1 As Long '汎用テンポラリ変数 Long型 No.1 Dim Tempt1 As Byte '時刻カウント用の汎用テンポラリ変数 Byte型 No.1 Dim Tempstr As String * 60 '汎用テンポラリ変数 String型 No.1 Dim Tempstr2 As String * 5 '汎用テンポラリ変数 String型 No.2 Dim Tempstr3 As String * 5 '汎用テンポラリ変数 String型 No.3 ' Dim Eep1224h As Eram Byte At $10 'EEPROM 時間表示モード 0=24時間制 / 1=12時間制。 Dim Eepsentime As Eram Byte At $12 'EEPROM センサーONからの表示時間。(0:1分, 1:5分, 2:10分) Dim Eeprefadj As Eram Byte At $14 'EEPROM AVR 1.1V基準電圧の校正値。(100〜120→1.00〜1.20V) ' ' * ポート名の定義 * ' Sw_1 Alias Pind.0 'スイッチ[1]の接続ポート。 Sw_2 Alias Pind.2 'スイッチ[2]の接続ポート。 Sw_3 Alias Pind.1 'スイッチ[3]の接続ポート。 Back_light Alias Portd.3 'LCDのバックライト制御端子。 Pir_sensor Alias Pinc.5 '焦電型赤外線センサーの接続ポート。 Sd_cd Alias Pinb.0 'SDカードのCD(Card Detect)接続ポート。 Ad_thermo Alias 3 '温度センサーのA/Dコンバータ・チャネル番号。 ' ' カラーLCDの初期設定 * ' $lib "LCD-EPSON-ex.LBX" 'EPSON カラーLCD 拡張ライブラリ。 Config Graphlcd = Color , Controlport = Portd , Cs = 6 , Rs = 7 , Scl = 4 , Sda = 5 'カラーLCDの接続ポートとピンを指定する。 ' Glcdcmd &H81 '[VOLCTR] Electronic volume control. Glcddata 38 'コントラスト値(0-59) デフォルト(38) ' Const Red = &B11100000 '8bitカラーの色情報に名前を付ける。 Const Green = &B00011100 Const Blue = &B00000011 Const Black = &B00000000 Const White = &B11111111 Const Magenta = &B11100011 Const Yellow = &B11111100 Const Cyan = &B00011111 ' Const Brown = &B01100000 Const Darkgreen = &B00001100 Const Darkblue = &B00000001 Const Orange = &B11101100 Const Brightgreen = &B10011100 Const Brightblue = &B01111110 Const Grey = &B01101101 Const Silver = &B10010010 ' Setfont Color8x8 'フォントを指定する。 Cls 'LCD画面を消去する。 ' ' * AVR-DOSの初期設定 * ' $include "Config_MMC_JP_MPF328P.bas" 'SD/MMCカードのピン設定プログラムを組み込む。 If Gbdriveerror <> 0 Then Gosub Driveerr 'If 初期化でエラーが発生したか? Then ' $include "CONFIG_AVR-DOS_JP_Mega328P.bas" 'AVR-DOSの設定プログラムを組み込む。 Temp1 = Initfilesystem(1) 'ファイル・システムを初期化する。 If Gbdoserror <> 0 Then Gosub Avrdoserr 'If AVR-DOSエラーが発生したか? Then ' ' * ポートの初期設定 * ' Set Portd.0 'スイッチ[1]の接続ポートをプルアップする。 Set Portd.2 'スイッチ[2]の接続ポートをプルアップする。 Set Portd.1 'スイッチ[3]の接続ポートをプルアップする。 Set Portc.5 '焦電型赤外線センサーの接続ポートをプルアップする。 Set Portb.0 'SDカードのCD(Card Detect)接続ポートをプルアップする。 Set Portb.4 'SDカードのDO(Data Out)接続ポートをプルアップする。 Set Portb.5 '未使用ポートをプルアップ。 Set Portb.7 '未使用ポートをプルアップ。 Set Portc.0 '未使用ポートをプルアップ。 Set Portc.1 '未使用ポートをプルアップ。 Set Portc.2 '未使用ポートをプルアップ。 Set Portc.4 '未使用ポートをプルアップ。 Config Back_light = Output 'LCDのバックライト制御ポートを出力に設定する。 Set Back_light 'LCDのバックライトを点灯させる。 Set Didr0.ad_thermo 'デジタル入力禁止レジスタの設定。 ' ' * タイマーを設定 * ' Config Timer1 = Timer , Prescale = 1024 , Clear Timer = 1 'Timer1 12800000 / 1024 = 12,500Hz Compare1a = 12500 - 1 '12,500Hz / 1Hz(1秒) = 12500カウント On Compare1a Tint1sec 'TIMER1比較一致A割り込みルーチンのラベルを設定。 Enable Compare1a 'TIMER1比較一致A割り込みを許可。 ' Config Timer2 = Timer , Prescale = 1024 , Clear Timer = 1 'Timer2 12800000 / 1024 = 12,500Hz Ocr2a = 125 - 1 '12,500Hz / 100Hz(10mS) = 125カウント ' ' * A/Dコンバーターの設定 * ' Config Adc = Single , Prescaler = Auto , Reference = Internal_1.1 'A/Dコンバータの基準電圧を変更。(内部1.1V) Start Adc 'A/Dコンバータに電源を供給。 ' ' * EEPROM 保存データの読み込み * ' If Eep1224h > 1 Then 'If EEPROMが初期状態か? Then Eep1224h = 1 'EEPROM 時間表示モード 0=24時間制 / 1=12時間制。 Eepsentime = 0 'EEPROM センサーONからの表示時間。(0:1分, 1:5分, 2:10分) Eeprefadj = 110 'EEPROM AVR 1.1V基準電圧の校正値。(100〜120→1.00〜1.20V) End If Mf1224h = Eep1224h Sentime = Eepsentime Refadj = Eeprefadj ' ' * プログラムの初期設定 * ' Config Clock = User '時計(タイマー)をUserモードに設定。 _year = 10 '日付の初期値を設定する。 _month = 1 _day = 1 Enable Interrupts 'すべての割り込みを許可。 ' Dispcont = 2 '表示制御モードを、(2:センサー制御)にする。 Gosub Sentimcal 'センサーONからの表示時間を計算する。 Dispmode = 2 '画面表示モードを、(2:通常表示)にする。 Disptimsel = 2 '表示変更間隔の初期値。(10秒) Dispchgtim = 10 '表示変更間隔を10秒に設定する。 Tint1sflg = 1 '時刻を強制表示させる。 Daychgf = 1 '最初の写真を強制表示させる。 Gosub Filecount '画像ファイルの総数を調べる。 ' ' ******************* ' * メイン ルーチン * ' ******************* ' Main: Gosub Sdcardchk 'SDカードをチェックする。 Gosub T1secpro '1秒ごとに行う処理。 Gosub Keychk 'スイッチ入力を調べる。 If Keyflg = 1 Then Goto Keyin 'If スイッチ入力が有ったか? Then Goto Main ' ' **************************** ' * スイッチ入力処理ルーチン * ' **************************** ' Keyin: Keyflg = 0 If Keydata = &B00000001 Then Goto Keyin1 'If スイッチ[1]が押されたか? Then If Dispmode = 0 Then Goto Main 'If 表示消灯中か? Then If Keydata = &B00000110 Then Goto Keyin4 'If スイッチ[2]と[3]が同時に押されたか? Then If Dispmode = 3 Then Goto Main 'If エラー表示中か? Then If Keydata = &B00000010 Then Goto Keyin2 'If スイッチ[2]が押されたか? Then If Keydata = &B00000100 Then Goto Keyin3 'If スイッチ[3]が押されたか? Then Goto Main ' ' Keyin1: '表示制御モードの選択。 Dispcont = Dispcont + 1 '表示制御モードを変更する。 If Dispcont > 2 Then Dispcont = 0 'If 表示制御モードが最大値か? Then If Dispcont = 0 Then Goto Keyin11 'IF 表示強制オフか? Then ' If Dispcont = 1 Then 'If 常時ONか? Then Lcdat 103 , 0 , "ON" , Magenta , Black '常時ONを表示する。 Else Lcdat 103 , 0 , "AT" , Orange , Black 'センサー自動制御を表示する。 End If ' If Dispmode <> 0 Then Goto Main 'If 表示中か? Then Gosub Lcdconton 'LCDの電源をONにする。 Dispmode = 2 '通常表示に設定する。 Gosub Sentimcal 'センサーONからの表示時間を計算する。 Goto Main ' ' Keyin11: '表示をオフにする。 If Dispmode = 0 Then Goto Main 'If 表示消灯中か? Then ' Gosub Lcdcontoff 'LCDの電源をOFFにする。 Dispmode = 0 '表示オフに設定する。 Goto Main ' ' Keyin2: '表示変更の間隔を増加する。 Disptimsel = Disptimsel + 1 If Disptimsel > 7 Then Disptimsel = 0 'If 上限値か? Then ' Keyin21: Select Case Disptimsel Case 0 : Dispchgtim = 3 '3秒毎。 Tempstr = " 3sec" Case 1 : Dispchgtim = 5 '5秒毎。 Tempstr = " 5sec" Case 2 : Dispchgtim = 10 '10秒毎。 Tempstr = "10sec" Case 3 : Dispchgtim = 30 '30秒毎。 Tempstr = "30sec" Case 4 : Dispchgtim = 60 '1分毎。 Tempstr = " 1min" Case 5 : Dispchgtim = 300 '5分毎。 Tempstr = " 5min" Case 6 : Dispchgtim = 1800 '30分毎。 Tempstr = "30min" Case 7 : Dispchgtim = 3600 '60分毎。 Tempstr = "60min" End Select Disptimer = 0 Lcdat 103 , 90 , Tempstr , Cyan , Black '間隔時間を表示する。 Goto Main ' ' Keyin3: '表示変更の間隔を減少する。 If Disptimsel = 0 Then 'If 下限値か? Then Disptimsel = 7 Else Disptimsel = Disptimsel - 1 End If Goto Keyin21 ' ' Keyin4: Gosub Setmode '設定モード処理。 Goto Main ' ' ********************************** ' * SDカードをチェックするルーチン * ' ********************************** ' Sdcardchk: If Dispmode < 2 Then Return 'If 表示オフまたは設定中か? Then If Sd_cd = 1 Then Goto Sdcardchk1 'If SDカードが挿されていないか? Then If Dispmode = 3 Then Goto Sdcardchk2 'エラー画面表示中か? Then ' If Gbdoserror <> 0 Then 'If AVR-DOSエラーが発生したか? Then Cls Gosub Avrdoserr 'AVR-DOSエラーコードを表示する。 Dispmode = 3 'エラー画面表示に設定する。 End If Return ' ' Sdcardchk2: 'エラー画面表示中の場合。 Gbdriveerror = Driveinit() 'SD/MMCカードを初期化する。 Temp1 = Initfilesystem(1) 'ファイル・システムを初期化する。 Gosub Filecount '画像ファイルの総数を調べる。 If Gbdoserror = 0 Then 'If AVR-DOSエラーが解消されたか? Then Dispmode = 2 '通常表示に設定する。 Daychgf = 1 '最初の写真を強制表示させる。 End If Return ' ' Sdcardchk1: 'SDカードが挿されていない場合。 If Dispmode = 2 Then '通常画面表示中か? Then Cls Gosub Sdcarderr 'SDカードのエラーを表示する。 Dispmode = 3 'エラー画面表示に設定する。 End If Return ' ' ***************************** ' * 1秒ごとに行う処理ルーチン * ' ***************************** ' T1secpro: If Tint1sflg = 0 Then Return 'If 1秒経過していないか? Then Tint1sflg = 0 ' Gosub Timedisp 'LCDに時刻と温度を表示する。 ' If Daychgf <> 0 Then 'If 日付が変わったか? Then Daychgf = 0 Gosub Schduchk '「スケジュール」ファイルを確認する。 Gosub Photodisp '画面を更新する。 End If ' ' * 写真を定期的に変更する * ' Disptimer = Disptimer + 1 If Disptimer = Dispchgtim Then 'If 表示間隔の設定時間になったか? Then Disptimer = 0 ' If Dispmode <> 3 Then 'エラー画面以外か? Then Dispfile = Dispfile + 1 '表示するファイルを更新する。 If Dispfile > Totalfile Then 'If 表示ファイルが最後か? Then Dispfile = 1 End If ' If Dispmode = 2 Then '通常画面表示中か? Then Gosub Photodisp '画面を更新する。 Else Photochgf = 1 '消灯中は写真変更を保留する。 End If End If End If ' ' * センサーONからの表示時間を管理する * ' If Dispcont <> 2 Then Goto Pirmsen01 'If センサー制御か? Else If Pir_sensor = 1 Then Goto Pirmsen03 'If センサーがOFFか? Then If Dispmode <> 0 Then Goto Pirmsen02 'If 画面は表示中か? Then ' Gosub Lcdconton '[消灯からの復帰] LCDの電源をONにする。 Dispmode = 2 '通常表示に設定する。 If Photochgf = 1 Then 'If 定期写真変更が保留中か? Then Photochgf = 0 Gosub Photodisp '画面を更新する。 End If ' Pirmsen02: Gosub Sentimcal 'センサーONからの表示時間を計算する。 Goto Pirmsen01 ' ' Pirmsen03: 'センサーOFFからの表示時間をカウントする。 If Dispmode = 0 Then Goto Pirmsen01 'If 表示消灯中か? Then Poffcun = Poffcun + 1 If Poffcun < Powtime Then Goto Pirmsen01 'If 自動消灯の時間になったか? Else ' Gosub Lcdcontoff 'LCDの電源をOFFにする。 Dispmode = 0 '表示オフに設定する。 ' ' * センサータイマー調整用の臨時ルーチン * ' Pirmsen01: ' Lcdat 103 , 24 , Pir_sensor , Orange , Black 'センサーの状態を表示する。 ' Tempstr2 = Str(poffcun) 'タイマーのカウント値を表示する。 ' Tempstr3 = Format(tempstr2 , "000") ' Lcdat 103 , 40 , Tempstr3 , Orange , Black Return ' ' * LCDに時刻と温度を表示するサブルーチン * ' Timedisp: If Dispmode < 2 Then Return 'If 時刻表示が必要ない画面か? Then Tempstr = "20" Tempstr2 = Str(_year) '[年]を準備する。 Tempstr3 = Format(tempstr2 , "00") Tempstr = Tempstr + Tempstr3 Tempstr = Tempstr + "/" ' Tempstr2 = Str(_month) '[月]を準備する。 Tempstr3 = Format(tempstr2 , " 0") Tempstr = Tempstr + Tempstr3 Tempstr = Tempstr + "/" ' Tempstr2 = Str(_day) '[日]を準備する。 Tempstr3 = Format(tempstr2 , " 0") Tempstr = Tempstr + Tempstr3 Tempstr = Tempstr + " " ' Temp1 = Dayofweek() '曜日を計算する。 Tempstr2 = Lookupstr(temp1 , Weekdata) '[曜日]を準備する。 Tempstr = Tempstr + Tempstr2 ' Lcdat 112 , 1 , Tempstr , White , Black '[年/月/日 曜日]を表示する。 ' If Mf1224h = 0 Then 'If [月]表示モードが24時間制か? Then Tempstr = " " Tempstr2 = Str(_hour) '[時]を準備する。 Else Temp1 = _hour '24時間制時刻を12時間制に変換。 If Temp1 = 0 Then Temp1 = 24 'If 午前0時か? Then If Temp1 > 12 Then Temp1 = Temp1 - 12 'If 午後か? Then ' If _hour < 12 Then 'If 午前か? Then Tempstr = "am" Else Tempstr = "pm" End If Tempstr2 = Str(temp1) '数値変数を文字変数に変換する。 End If Tempstr3 = Format(tempstr2 , " 0") Tempstr = Tempstr + Tempstr3 Tempstr = Tempstr + ":" ' Tempstr2 = Str(_min) '[分]を準備する。 Tempstr3 = Format(tempstr2 , "00") Tempstr = Tempstr + Tempstr3 ' Lcdat 121 , 25 , Tempstr , White , Black '[時/分]を表示する。 ' ' Temperature = Getadc(ad_thermo) '温度センサー値をA/D変換する。 Tempw1 = Refadj * 10 '小数点を省くため校正値を1000倍しておく。(1.1V*1000=1100) Templ1 = Temperature * Tempw1 '1.1V ÷ 1024 × 1000000 × [A/D値] ÷ 1000 Shift Templ1 , Right , 10 , Signed '式を変えて 1.1V × 1000 × [A/D値] ÷ 1024(割り算を使わない) Temperature = Templ1 - 600 '温度センサーIC [LM61]の温度変換計算。 ' Tempstr2 = Str(temperature) '温度を表示する。 If Temperature < 0 Then 'If マイナスの温度か? Then If Temperature > -100 Then 'If -9.9度以上か? Then Tempstr3 = Format(tempstr2 , "0.0") Else Tempstr = Left(tempstr2 , 3) '-10度以下。 Tempstr3 = " " + Tempstr End If Else 'プラスの温度。 Tempstr3 = Format(tempstr2 , " 0.0") End If Tempstr = Tempstr3 + "C" Lcdat 121 , 89 , Tempstr , Green , Black '[温度]を表示する。 Return ' ' * SDカードの写真を表示するサブルーチン * ' Photodisp: If Dispmode <> 2 Then Return 'If 通常表示中ではないか? Then ' Tempw1 = Dispfile - 1 '表示する写真ファイルのファイル名を取得する。 Tempstr = Dir( "*.raw") '最初のディレクトリを読み込む。 While Tempw1 <> 0 Tempw1 = Tempw1 - 1 Tempstr = Dir() '次のファイル名を読み込む。 Wend If Gbdoserror <> 0 Then Return 'If AVR-DOSエラーが発生したか? Then ' Glcdcmd &H15 '[CASET] (X:0-129) Column address set Glcddata 0 Glcddata 129 ' Glcdcmd &H75 '[PASET] (Y:2-131) Page address set Glcddata 2 Glcddata 131 ' Glcdcmd &H5C '[RAMWR] Writing to memory ' Open Tempstr For Binary As #1 '表示するファイルを開く。 For Tempw1 = 1 To 21450 'X:(130dot / 2 x 3) x Y:110dot Get #1 , Temp1 'SDカードからデータを読み込む。 Glcddata Temp1 Next Tempw1 Close #1 'ファイルを閉じる。 ' If Strbuf(1) = "" Then Return 'If 「スケジュール」表示が無いか? Then ' Temp1 = Black '文字色から背景色を選択する。 Temp2 = White '文字色の初期値[黒]。 If Strbuf(2) = "re" Then 'If 文字色が[赤]か? Then Temp1 = Red Temp2 = Yellow End If If Strbuf(2) = "gr" Then 'If 文字色が[緑]か? Then Temp1 = Green Temp2 = Magenta End If If Strbuf(2) = "bl" Then 'If 文字色が[青]か? Then Temp1 = Blue Temp2 = Yellow End If If Strbuf(2) = "wh" Then 'If 文字色が[白]か? Then Temp1 = White Temp2 = Black End If If Strbuf(2) = "ma" Then 'If 文字色が[桃色]か? Then Temp1 = Magenta Temp2 = Cyan End If If Strbuf(2) = "ye" Then 'If 文字色が[黄]か? Then Temp1 = Yellow Temp2 = Blue End If If Strbuf(2) = "cy" Then 'If 文字色が[水色]か? Then Temp1 = Cyan Temp2 = Red End If ' Lcdat 0 , 0 , Strbuf(3) , Temp1 , Temp2 'スケジュールの1行目を表示する。 Lcdat 9 , 0 , Strbuf(4) , Temp1 , Temp2 'スケジュールの2行目を表示する。 Lcdat 18 , 1 , Strbuf(5) , Temp1 , Temp2 'スケジュールの3行目を表示する。 Return ' ' * 「スケジュール」ファイルを確認するサブルーチン * ' Schduchk: Strbuf(1) = "" '「スケジュール」データをクリアする。 ' Open "Schedule.txt" For Input As #1 '「スケジュール」ファイルを開く。 If Gbdoserror = 66 Then Goto Schduchk1 'If 「スケジュール」ファイルが無いか? Then ' Schduchk2: If Eof(#1) <> 0 Then Goto Schduchk3 'If ファイルが終わりに達したか? Then Line Input #1 , Tempstr '「スケジュール」ファイルから1行分を読み込む。 Tempstr2 = Left(tempstr , 2) '[月]の文字列を抜き出す。 Temp1 = Val(tempstr2) '文字列を数値に変換する。 If Temp1 <> _month Then Goto Schduchk2 'If [月]は一致していないか? Then Tempstr2 = Mid(tempstr , 4 , 2) '[日]の文字列を抜き出す。 Temp1 = Val(tempstr2) '文字列を数値に変換する。 If Temp1 <> _day Then Goto Schduchk2 'If [日]は一致していないか? Then ' Strbuf(3) = "" '「スケジュール」データをクリアする。 Strbuf(4) = "" Strbuf(5) = "" Schlen = Split(tempstr , Strbuf(1) , ",") '文字列を","で分割する。 ' Schduchk3: Close #1 'ファイルを閉じる。 Return ' ' Schduchk1: '「スケジュール」ファイルが無い場合。 Gbdoserror = 0 Return ' ' * 画像ファイルの総数を調べるサブルーチン * ' Filecount: Totalfile = 0 Tempstr = Dir( "*.raw") '最初のディレクトリを読み込む。(RAWファイル) While Len(tempstr) > 0 'ファイル名が無くなるまで繰り返し。 Totalfile = Totalfile + 1 Tempstr = Dir() '次のファイル名を読み込む。 Wend Dispfile = 1 '表示ファイル番号の初期値。 Return ' ' * LCDの電源をONにするサブルーチン * ' Lcdconton: Start Adc 'A/Dコンバータに電源を供給。 ' Glcdcmd &H94 '[SLPOUT] Sleep out コマンド。 Glcdcmd &HD1 '[OSCON] Internal oscillation on コマンド。 Glcdcmd &H20 '[PWRCTR] Power control コマンド。 Glcddata &H0F '全てON。 Waitms 100 '100mSの待ち時間。 Glcdcmd &HAF '[DISON] Display on コマンド。 ' Set Back_light 'LCDのバックライトを点灯させる。 Return ' ' * LCDの電源をOFFにするサブルーチン * ' Lcdcontoff: Reset Back_light 'LCDのバックライトを消灯させる。 ' Glcdcmd &HAE '[DISOFF] Display off コマンド。 Glcdcmd &H20 '[PWRCTR] Power control コマンド。 Glcddata &H00 '全てOFF。 Glcdcmd &HD2 '[OSCOFF] Internal oscillation off コマンド。 Glcdcmd &H95 '[SLPIN] Sleep in コマンド。 ' Stop Adc 'A/Dコンバータの電源を遮断。 Return ' ' * センサーONからの表示時間を計算するサブルーチン * ' Sentimcal: Select Case Sentime 'センサーONからの表示時間を設定する。 Case 0: Powtime = 60 '1分。 Case 1: Powtime = 300 '5分。 Case 2: Powtime = 600 '10分。 End Select Poffcun = 0 'センサーONからの表示時間カウンター。 Return ' ' * スイッチ入力 サブルーチン * (Keyflg = スイッチ入力が有ると1) ' (Keydata = スイッチ・データ) Keychk: If Tifr2.ocf2a = 0 Then Return 'If 10mS経過したか? Else Set Tifr2.ocf2a 'Timer2 比較A一致フラグをリセット。 ' If Keycun = 0 Then Goto Keychk1 'If キー入力チェック開始か? Then If Keycun < 3 Then Goto Keychk5 'If チャタリング チェック期間か? Then If Keycun = 3 Then Goto Keychk3 'If キー入力再確認か? Then ' Gosub Keyport 'キーオフを確認する。 If Keydata <> Keytemp Then Goto Keychk4 'If キーオフか? Then If Keycun < 103 Then Goto Keychk5 'If リピート期間待ち(1秒)か? Then Keyflg = 1 Keycun = 92 'リピートを開始。 Return ' ' Keychk1: 'キー入力チェック開始。 Gosub Keyport 'キー接続ポートからデータを入力。 If Keydata <> 0 Then Goto Keychk2 'If キー入力有りか? Then Keychk4: Keycun = 0 Return ' Keychk2: 'キー入力有り。 Keytemp = Keydata 'キー・データを一時保存。 Keychk5: Keycun = Keycun + 1 Return ' Keychk3: 'キー入力再確認。 Gosub Keyport 'キー接続ポートからデータを入力。 If Keydata <> Keytemp Then Goto Keychk4 'If キー入力エラーか? Then Keyflg = 1 Goto Keychk5 ' ' * キー接続ポートからのデータ入力サブルーチン * (Keydata = キー・データ) ' Keyport: Keydata = 0 If Sw_1 = 0 Then Set Keydata.0 End If If Sw_2 = 0 Then Set Keydata.1 End If If Sw_3 = 0 Then Set Keydata.2 End If Return ' ' ************** ' * 設定モード * ' ************** ' Setmode: Cls 'LCD画面を消去する。 Lcdat 4 , 24 , "Year:" , White , Black '[年] Lcdat 16 , 16 , "Month:" , White , Black '[月] Lcdat 28 , 32 , "Day:" , White , Black '[日] Lcdat 40 , 24 , "Hour:" , White , Black '[時] Lcdat 52 , 32 , "Min:" , White , Black '[分] Lcdat 64 , 8 , "12/24h:" , White , Black '[12時間/24時間制] Lcdat 76 , 8 , "SenTim:" , White , Black '[センサーONからの表示時間] Lcdat 88 , 8 , "RefAdj:" , White , Black '[温度の微調整<基準電圧値>] Lcdat 100 , 8 , "SetEnd:" , White , Black '[設定終了] ' Timebuf(1) = _year Timebuf(2) = _month Timebuf(3) = _day Timebuf(4) = _hour Timebuf(5) = _min Timebuf(6) = Mf1224h Timebuf(7) = Sentime Timebuf(8) = Refadj Setcur = 9 Temp5 = 0 '日時設定変更フラグ。 ' Setmode1: Gosub Setpardsp '設定項目の値を表示する。 ' Setmode2: If Pir_sensor = 0 Then 'センサーがONか? Then Lcdat 120 , 104 , "ON " , Orange , Black 'センサーの状態を表示する。 Else Lcdat 120 , 104 , "OFF" , Blue , Black 'センサーの状態を表示する。 End If ' Gosub Keychk 'スイッチ入力を調べる。 If Keyflg = 0 Then Goto Setmode2 'If スイッチ入力が無いか? Then ' Keyflg = 0 If Keydata = &B00000001 Then Goto Setmode3 'If スイッチ[1]が押されたか? Then If Keydata = &B00000010 Then Goto Setmode4 'If スイッチ[2]が押されたか? Then If Keydata = &B00000100 Then Goto Setmode5 'If スイッチ[3]が押されたか? Then Goto Setmode2 ' ' Setmode3: 'スイッチ[1] 項目選択。 Setcur = Setcur + 1 If Setcur > 9 Then Setcur = 1 'If 項目選択の上限か? then ' Temp3 = Setcur - 1 '設定項目の上・下限値を取得する。 Temp3 = Temp3 * 2 Temp1 = Lookup(temp3 , Setpardat) '[Temp1] = 下限値。 Temp3 = Temp3 + 1 Temp2 = Lookup(temp3 , Setpardat) '[Temp2] = 上限値。 ' If Setcur = 3 Then 'If [日]か? Then Select Case Timebuf(2) '月ごとの日にちの最終日を計算する Case 2 : '2月。 Temp3 = Timebuf(1) And &H03 If Temp3 = 0 Then 'If 閏年か? Then Temp2 = 29 Else Temp2 = 28 End If Case 4 : Temp2 = 30 '4月。 Case 6 : Temp2 = 30 '6月。 Case 9 : Temp2 = 30 '9月。 Case 11 : Temp2 = 30 '11月。 Case Else : Temp2 = 31 '上記以外の月。 End Select End If Goto Setmode1 ' ' Setmode4: 'スイッチ[2] 設定値+。 If Setcur = 9 Then Goto Setmend 'If 設定終了か? Then If Timebuf(setcur) = Temp2 Then 'If 上限か? Then Timebuf(setcur) = Temp1 '下限値を入れる。 Else Timebuf(setcur) = Timebuf(setcur) + 1 '設定値を加算する。 End If ' Setmode6: If Setcur < 6 Then 'If 日時を変更したか? Then Temp5 = 1 End If Goto Setmode1 ' ' Setmode5: 'スイッチ[3] 設定値−。 If Setcur = 9 Then Goto Setmend 'If 設定終了か? Then If Timebuf(setcur) = Temp1 Then 'If 下限か? Then Timebuf(setcur) = Temp2 '上限値を入れる。 Else Timebuf(setcur) = Timebuf(setcur) - 1 '設定値を減算する。 End If Goto Setmode6 ' ' Setmend: '設定終了。 If Temp5 = 1 Then 'If 日時が変更されているか? Then Disable Interrupts 'すべての割り込みを禁止。 _year = Timebuf(1) _month = Timebuf(2) _day = Timebuf(3) _hour = Timebuf(4) _min = Timebuf(5) _sec = 0 Enable Interrupts 'すべての割り込みを許可。 End If ' Mf1224h = Timebuf(6) Sentime = Timebuf(7) Refadj = Timebuf(8) Eep1224h = Mf1224h 'EEPROMに書き込む。 Eepsentime = Sentime Eeprefadj = Refadj ' Gosub Sentimcal 'センサーONからの表示時間を計算する。 ' Cls 'LCD画面を消去する。 Tint1sflg = 1 '時刻を強制表示させる。 Daychgf = 1 'スケジュールファイルを強制確認させる。 Return ' ' * 設定項目の値を表示するサブルーチン * ' Setpardsp: Temp4 = 4 '[年月日時分]の値を表示する。 For Temp3 = 1 To 5 Tempstr2 = Str(timebuf(temp3)) Tempstr3 = Format(tempstr2 , "00") If Temp3 = Setcur Then 'If 設定項目に選ばれているか? Then Lcdat Temp4 , 72 , Tempstr3 , Yellow , Red Else Lcdat Temp4 , 72 , Tempstr3 , Yellow , Black End If Temp4 = Temp4 + 12 Next Temp3 ' If Timebuf(6) = 0 Then 'If [時]表示モードは24時間制か? Then Tempstr2 = "24H" Else Tempstr2 = "12H" End If If Setcur = 6 Then 'If 設定項目に選ばれているか? Then Lcdat 64 , 72 , Tempstr2 , Yellow , Red Else Lcdat 64 , 72 , Tempstr2 , Yellow , Black End If ' Select Case Timebuf(7) 'センサーONからの表示時間。 Case 0 : Tempstr2 = "1min " Case 1 : Tempstr2 = "5min " Case 2 : Tempstr2 = "10min" End Select If Setcur = 7 Then 'If 設定項目に選ばれているか? Then Lcdat 76 , 72 , Tempstr2 , Yellow , Red Else Lcdat 76 , 72 , Tempstr2 , Yellow , Black End If ' Tempstr2 = Str(timebuf(8)) 'AVR 1.1V基準電圧の校正値。(100〜120→1.00〜1.20V) Tempstr3 = Format(tempstr2 , "0.00") + "v" If Setcur = 8 Then 'If 設定項目に選ばれているか? Then Lcdat 88 , 72 , Tempstr3 , Yellow , Red Else Lcdat 88 , 72 , Tempstr3 , Yellow , Black End If ' Tempstr = "finish" '設定終了。 If Setcur = 9 Then 'If 設定項目に選ばれているか? Then Lcdat 100 , 72 , Tempstr , Yellow , Red Else Lcdat 100 , 72 , Tempstr , Yellow , Black End If Return ' ' * エラーメッセージを表示するサブルーチン * ' Driveerr: 'SDカードの初期化ドライブエラー。 Lcdat 0 , 0 , "Drive Error!" , Yellow , Red Lcdat 9 , 0 , Gbdriveerror , Yellow , Red Return ' ' Avrdoserr: 'AVR-DOSのエラー。 Lcdat 18 , 0 , "AVR-DOS Error!" , Yellow , Red Lcdat 27 , 0 , Gbdoserror , Yellow , Red Return ' ' Sdcarderr: 'SDカードのエラー。 Lcdat 28 , 16 , "No SD-card!" , Red , Yellow Tempstr = "Ver." + Prgver Lcdat 60 , 24 , Tempstr , Cyan , Black Return ' ' * [Config Clock = User]の場合、AVR-DOSから参照されるルーチン * ' Getdatetime: '割り込みで時刻カウントしているため未処理で可。 Return ' ' ************************************* ' * Timer1 [1秒]割り込み 処理ルーチン * ' ************************************* ' Tint1sec: _sec = _sec + 1 '[秒]を更新。 If _sec < 60 Then Goto Tint1sec1 'If 60秒 経過したか? Else ' _sec = 0 _min = _min + 1 '[分]を更新。 If _min < 60 Then Goto Tint1sec1 'If 60分 経過したか? Else ' _min = 0 _hour = _hour + 1 '[時]を更新。 If _hour < 24 Then Goto Tint1sec1 'If 24時間 経過したか? Else ' _hour = 0 _day = _day + 1 '[日]を更新。 Daychgf = 1 '日付変更フラグをセットする。 ' Select Case _month '月ごとの日にちの最終日を計算する。 Case 2 : '2月。 Tempt1 = _year And &H03 If Tempt1 = 0 Then 'If 閏年か? Then Monthlast = 29 Else Monthlast = 28 End If Case 4 : Monthlast = 30 '4月。 Case 6 : Monthlast = 30 '6月。 Case 9 : Monthlast = 30 '9月。 Case 11 : Monthlast = 30 '11月。 Case Else : Monthlast = 31 '上記以外の月。 End Select ' If _day =< Monthlast Then Goto Tint1sec1 'If 月の最終日を超えたか? Else ' _day = 1 _month = _month + 1 '[月]を更新。 If _month < 13 Then Goto Tint1sec1 'If 12ヶ月 経過したか? Else ' _month = 1 _year = _year + 1 '[年]を更新。 If _year < 100 Then Goto Tint1sec1 'If 100年 経過したか? Else _year = 0 ' Tint1sec1: Tint1sflg = 1 '1秒経過フラグをセットする。 Return ' ' End ' ' * 曜日 データ・テーブル * ' Weekdata: Data "MON" , "TUE" , "WED" , "THU" , "FRI" , "SAT" , "SUN" ' ' * 設定モードの上・下限値 テーブル * ' Setpardat: Data 0 , 99 , 1 , 12 , 1 , 31 , 0 , 23 , 0 , 59 '[年,月,日,時,分] Data 0 , 1 , 0 , 2 , 100 , 120 , 0 , 1 '[12/24,SenTim,RefAdj,SetEnd] ' ' $include "color8x8.font" 'フォントファイルを組み込む。