' ' ********************************************** ' * MPL115A1 デジタル気圧センサー * ' * 気圧計(天気予報) + 時計 プログラム * ' * * ' * AVR is using ATmega328P * ' * Basic Compiler is BASCOM-AVR * ' * Copyright By O-Family 2018. 7. 3 * ' ********************************************** ' ' Ver 1.01 初回公開バージョン。2012. 2. 3 ' Ver 1.11 簡易グラフ表示を追加。気圧計算式を簡略化。2013. 9.13 ' Ver 5.11 MPL115A1(SPI)対応バージョン。2018. 7. 3 ' ' Const Prgver = "05.11" 'プログラム・バージョン。 ' ' $regfile = "m328pdef.dat" '使用するAVRを設定。 $crystal = 1000000 'AVRクロックを設定。 ' $hwstack = 64 'ハードウェア・スタックの容量を設定。 $swstack = 10 'ソフトウェア・スタックの容量を設定。 $framesize = 24 'フレーム領域の容量を設定。 ' ' * 変数の宣言 * ' Dim Rxbuff(20) As Byte 'SPIの受信データ・バッファー。 Dim Uipadc As Word '圧力のA/D変換値。 Dim Uitadc As Word '温度のA/D変換値。 Dim Sia0 As Integer '[a0] 圧力のオフセット係数。 Dim Sib1 As Integer '[b1] 圧力の感度係数。 Dim Sib2 As Integer '[b2] 1次の温度オフセット係数 (TCO)。 Dim Sic12 As Integer '[c12]温度感度係数(TCS)のための係数。 ' Dim Sic11 As Integer '[c11]圧力の直線性(2次)係数。 ' Dim Sic22 As Integer '[c22]2次の温度オフセット係数。 ' Dim Tl1 As Long '汎用テンポラリ変数 Long型 No.1 Dim Tl2 As Long '汎用テンポラリ変数 Long型 No.2 Dim Tl3 As Long '汎用テンポラリ変数 Long型 No.3 Dim Tl4 As Long '汎用テンポラリ変数 Long型 No.4 ' Dim Average(32) As Word '移動平均用バッファー。 Dim Avgpoi As Byte '移動平均のポインター。 Dim Avgsum As Long '移動平均の合計値。 Dim Baropress As Word '気圧値。 Dim Deviation As Integer '気圧の24時間偏差値。 Dim Weather As Byte '天気予報値。 Dim Dbuf(24) As Word '24時間のデータバッファー。 Dim Dbufpoi As Byte '24時間のデータバッファー用ポインター。 Dim Sectemp As Byte '[秒]更新用テンポラリ。 Dim Hourtemp As Byte '[時]更新用テンポラリ。 Dim Swintf As Byte 'スイッチ割り込みフラグ。 Dim Mf1224h As Byte '[月]表示モード・フラグ (0=12時間制 , 1=24時間制) Dim Lcdmode As Byte 'LCDの表示電源モード。(0:強制OFF , 1:自動OFF , 2:ON , 3:ワンショット , 4:バックライト) Dim Dispmode As Byte '表示モード。(0:時刻+偏差 , 1:温度表示 , 2:秒表示 , 3:簡易グラフ表示) Dim Temperature As Integer '温度値。(x0.1) Dim Modetemp As Byte 'モード移行時の保管用。 Dim Serioutf As Byte 'シリアル入出力制御フラグ。 ' Dim Oneshtintv As Byte '[ワンショット動作]の時間設定値。 Dim Oneshcun As Byte '[ワンショット動作]のカウンター。 Dim Cdsgain As Byte '[CDSの感度]の設定値。 Dim Cdsmax As Word '[CDSの感度]の最大値。 Dim Cdsmin As Word '[CDSの感度]の最小値。 Dim Bpinterval As Byte '[気圧測定間隔]の設定値。 Dim Bpintcun As Byte '[気圧測定間隔]のカウンター。 Dim Adinterval As Byte '[A/D間隔]の設定値。 Dim Adintcun As Byte '[A/D間隔]のカウンター。 Dim Tempsentype As Byte '温度センサーの種別。(1:MCP9700-E/TO , 2:LM61BIZ) Dim Tempsenofs As Word '温度センサーの係数。 [MCP9700-E/TO] = 500 , [LM61BIZ] = 600 Dim Refvolt As Word 'AVRの内部基準電圧較正値。 Dim Pregbasis As Word '気圧グラフのベース気圧値。(500〜990hPa) ' 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 Tempw1 As Word '汎用テンポラリ変数 Word型 No.1 Dim Tempi1 As Integer '汎用テンポラリ変数 Integer型 No.1 Dim Tempstr As String * 20 '汎用テンポラリ変数 String型 No.1 ' Dim Tbuff_tm(192) As Word '8日分の[時刻]記録バッファー。 Dim Tbuff_bp(192) As Word '8日分の[気圧]記録バッファー。 Dim Tbuff_dt(192) As Integer '8日分の[偏差+天気]記録バッファー。 Dim Tbuff_tp(192) As Integer '8日分の[温度]記録バッファー。 Dim Tbuffpoi As Byte '8日分の記録バッファー用ポインター。 ' Dim Dummy As Eram Long 'EEPROM 4バイトのダミーエリア。 Dim Eep1224h As Eram Byte 'EEPROM 時間表示モード (0=24時間制 , 1=12時間制) Dim Eeponeshtintv As Eram Byte 'EEPROM [ワンショット動作]の時間設定値。 Dim Eepcdsgain As Eram Byte 'EEPROM [CDSの感度]の設定値。 Dim Eepbpinterval As Eram Byte 'EEPROM [気圧測定間隔]の設定値。 Dim Eepadinterval As Eram Byte 'EEPROM [A/D間隔]の設定値。 Dim Eeprefvolt As Eram Byte 'EEPROM AVRの内部基準電圧較正値。 Dim Eeptempsentype As Eram Byte 'EEPROM 温度センサーの種別。 Dim Eeppregbasis As Eram Byte 'EEPROM 気圧グラフのベース気圧値。(50〜99 *10 hPa) ' ' * ポート名の定義 * ' Sw_1 Alias Pind.5 'スイッチ[1]の接続ポート。 Sw_1pu Alias Portd.5 'スイッチ[1]の接続ポート(プルアップ用)。 Sw_2 Alias Pind.6 'スイッチ[2]の接続ポート。 Sw_2pu Alias Portd.6 'スイッチ[2]の接続ポート(プルアップ用)。 Sw_3 Alias Pind.7 'スイッチ[3]の接続ポート。 Sw_3pu Alias Portd.7 'スイッチ[3]の接続ポート(プルアップ用)。 ' Power_lcd Alias Portd.4 'LCDモジュールの電源制御ポート。 Power_temp Alias Portc.5 '温度センサーの電源制御ポート。 Back_light Alias Portb.0 'LCDのバックライト制御ポート。 Lcd_rs Alias Portd.3 'LCDの[RS]接続ポート。 Lcd_e Alias Portd.2 'LCDの[E]接続ポート。 Lcd_db4 Alias Portc.4 'LCDの[DB4]接続ポート。 Lcd_db5 Alias Portb.5 'LCDの[DB5]接続ポート。 Lcd_db6 Alias Portc.3 'LCDの[DB6]接続ポート。 Lcd_db7 Alias Portc.2 'LCDの[DB7]接続ポート。 ' Ad_temp Alias 1 '温度電圧のA/Dコンバータのチャネル番号。 Ad_cds Alias 0 'CDS電圧のA/Dコンバータのチャネル番号。 ' Spi_cs Alias Portb.3 'MPL115A1の[CS]端子接続ポート。 Spi_sck Alias Portb.1 'MPL115A1の[SCLK]端子接続ポート。 Spi_dout Alias Portb.2 'MPL115A1の[DIN]端子接続ポート。 Spi_din Alias Pinb.4 'MPL115A1の[DOUT]端子接続ポート。 Spi_din_pu Alias Portb.4 'MPL115A1の[DOUT]端子接続ポート(プルアップ用)。 $lib "mcsbyteint.lbx" '文字列変換ルーチンを最適化するライブラリ。 ' ' * ポートの初期設定 * ' Config Power_lcd = Output 'LCDモジュールの電源制御ポートを出力に設定。 Set Power_lcd 'LCDモジュールの電源をONにする。 Config Power_temp = Output '温度センサーの電源制御ポートを出力に設定。 Set Power_temp '温度センサーの電源をONにする。 Config Back_light = Output 'LCDのバックライト制御ポートを出力に設定。 Set Sw_1pu 'スイッチ[1]の接続ポートをプルアップ。 Set Sw_2pu 'スイッチ[2]の接続ポートをプルアップ。 Set Sw_3pu 'スイッチ[3]の接続ポートをプルアップ。 Reset Ucsr0b.txen0 'USART送信許可を無効にする。 Reset Ucsr0b.rxen0 'USART受信許可を無効にする。 Config Portd.1 = Output 'USART TXDポートを出力に設定。 Reset Portd.1 'TXDポートを[L]にする。 ' Set Portb.3 '未使用ポートをプルアップ。 ' Set Portb.4 '未使用ポートをプルアップ。 ' ' * SPIの初期設定 * ' Config Spi_cs = Output 'MPL115A1の[CS]端子接続ポートを出力に設定。 Config Spi_sck = Output 'MPL115A1の[SCLK]端子接続ポートを出力に設定。 Config Spi_dout = Output 'MPL115A1の[DIN]端子接続ポートを出力に設定。 Set Spi_din_pu 'MPL115A1の[DOUT]端子接続ポートをプルアップ。 Set Spi_cs 'MPL115A1の[CS]端子を[H]にする。 Set Spi_sck 'MPL115A1の[SCLK]端子を[H]にする。 Set Spi_dout 'MPL115A1の[DIN]端子を[H]にする。 Waitms 10 'MPL115A1の起動待ち時間。 ' ' * AVR内部回路の設定 * ' Didr0 = &B0000_0011 'デジタル入力禁止レジスタの設定。 Config Aci = Off 'アナログ比較器の電源を切る。 Config Adc = Single , Prescaler = Auto , Reference = Internal 'A/Dコンバータの設定。 ' Set Prr.prusart0 '電力削減 USART回路の停止。 Set Prr.prspi '電力削減 SPI回路の停止。 Set Prr.prtim1 '電力削減 Timer1回路の停止。 Set Prr.prtim0 '電力削減 Timer0回路の停止。 Set Prr.7 '電力削減 TWI回路の停止。 ' ' * スイッチ割り込みの設定 * ' On Pcint2 Swint 'スイッチ割り込みルーチンのラベルを設定。 Set Pcmsk2.pcint21 '[SW1](PD5)割り込みを有効にする。 Set Pcmsk2.pcint22 '[SW2](PD6)割り込みを有効にする。 Set Pcmsk2.pcint23 '[SW3](PD7)割り込みを有効にする。 Set Pcmsk2.pcint16 '[RXD](PD0)割り込みを有効にする。 Enable Pcint2 'ピン変化割込を許可する。 ' ' * LCDの初期設定 * ' Config Lcdmode = Port 'LCDを4ビットのポートモードに設定。 Config Lcdbus = 4 'LCDデータバスを4bitに設定。 Config Lcdpin = Pin , Db4 = Lcd_db4 , Db5 = Lcd_db5 'LCDのポート割り当て。 Config Lcdpin = Pin , Db6 = Lcd_db6 , Db7 = Lcd_db7 Config Lcdpin = Pin , E = Lcd_e , Rs = Lcd_rs Config Lcd = 16 * 2 'LCD表示を16文字2行に設定。 ' ' * I2Cの初期設定 * ' ' Config Scl = Portb.1 'I2CバスのSCLラインを接続するポートピンを設定。 ' Config Sda = Portb.2 'I2CバスのSDAラインを接続するポートピンを設定。 ' ' Config I2cdelay = 1 'SCLクロック速度を設定。(BASCOMの仕様により約25KHz) ' I2cinit 'I2CバスのSCL,SDAラインを初期化。 ' ' * 時計用のライブラリを組み込む * ' Config Clock = Soft '時計(Timer2を使用)をSoftモードに設定。 Config Date = Ymd , Separator = / '日付の表現方法(形式)を設定。 ' ' * MPL115A1から係数ROMデータを読み出す * ' ' Rxbuff(1) = &H04 '係数ROMデータのメモリー・アドレスを指定する。 ' I2creceive &HC0 , Rxbuff(1) , 1 , 12 'I2Cバスで、1バイトのコマンドを送信し、12バイトのデータを受信する。 ' Reset Spi_dout 'MPL115A1の[DIN]端子を[L]にする。 Reset Spi_sck 'MPL115A1の[SCLK]端子を[L]にする。 Temp2 = 1 Reset Spi_cs 'MPL115A1の[CS]を[L]にする。 For Temp1 = &H88 To &H96 Step 2 Shiftout Spi_dout , Spi_sck , Temp1 , 1 Shiftin Spi_din , Spi_sck , Rxbuff(temp2) , 1 Temp2 = Temp2 + 1 Next Temp1 ' Temp1 = 0 '[00]を送信する。 ' Shiftout Spi_dout , Spi_sck , Temp1 , 1 Set Spi_cs 'MPL115A1の[CS]を[H]にする。 Set Spi_sck 'MPL115A1の[SCLK]端子を[H]にする。 Set Spi_dout 'MPL115A1の[DIN]端子を[H]にする。 ' ' * 係数のバイト・データを16bitのワードに変換する * ' Sia0 = Makeint(rxbuff(2) , Rxbuff(1)) '[a0] 圧力のオフセット係数。 Sib1 = Makeint(rxbuff(4) , Rxbuff(3)) '[b1] 圧力の感度係数。 Sib2 = Makeint(rxbuff(6) , Rxbuff(5)) '[b2] 1次の温度オフセット係数 (TCO)。 Sic12 = Makeint(rxbuff(8) , Rxbuff(7)) '[c12]温度感度係数(TCS)のための係数。 ' Sic11 = Makeint(rxbuff(10) , Rxbuff(9)) '[c11]圧力の直線性(2次)係数。 ' Sic22 = Makeint(rxbuff(12) , Rxbuff(11)) '[c22]2次の温度オフセット係数。 ' ' * 移動平均・24時間バッファーを初期化する * ' Gosub Baroconv '[MPL115A1]から気圧取得と係数補正。 Baropress = Tempw1 For Avgpoi = 1 To 32 '移動平均バッファーを初期値で埋める。 Average(avgpoi) = Tempw1 Next Avgpoi Avgsum = Tempw1 Shift Avgsum , Left , 5 '32個の平均合計を作る。 ' For Dbufpoi = 1 To 24 '24時間のデータバッファーを初期値で埋める。 Dbuf(dbufpoi) = Tempw1 Next Dbufpoi ' Gosub Lcdinit 'LCDを初期化する。 ' ' * プログラム・バージョンの表示 * ' If Sw_1 = 0 Then 'If スイッチ1が押されているか? Then Locate 1 , 1 'プログラム・バージョンを表示。 Lcd "Barometer Clock" Locate 2 , 4 Lcd "Ver. " ; Prgver Bitwait Sw_1 , Set 'スイッチ1が離されるまで待つ。 Waitms 30 'チャタリング・タイマー。 Eep1224h = 255 'EEPROMを初期化する。 Cls End If ' ' * EEPROMのデータを確認する * ' If Eep1224h > 1 Then 'If EEPROMが初期値か? Then Eep1224h = 1 '時間表示モードを[24時間制]に設定する。 Eeponeshtintv = 10 '[ワンショット動作]の時間設定値。 Eepcdsgain = 3 '[CDSの感度]の設定値。 Eepbpinterval = 60 '[気圧測定間隔]の設定値。 Eepadinterval = 10 '[A/D間隔]の設定値。 Eeprefvolt = 10 'AVRの内部基準電圧較正値。 Eeptempsentype = 1 '温度センサーの種別。 Eeppregbasis = 99 '気圧グラフのベース気圧値。(50〜99 *10 hPa) End If Mf1224h = Eep1224h 'EEPROM値を変数に読み込む。 Oneshtintv = Eeponeshtintv Cdsgain = Eepcdsgain Gosub Cdsgaset 'CDSの感度を計算する Bpinterval = Eepbpinterval Adinterval = Eepadinterval Tempsentype = Eeptempsentype Gosub Tsentype '温度センサーの係数を選択する。 Temp1 = Eeprefvolt 'AVRの内部基準電圧較正値を計算する。 Refvolt = Temp1 * 10 Refvolt = Refvolt + 1000 Temp1 = Eeppregbasis '気圧グラフのベース気圧値を計算する。 Pregbasis = Temp1 * 10 'ベース気圧値。 ' ' * テスト・モードの確認 * ' If Sw_3 = 0 Then Goto Calout 'If 32.768KHz 水晶較正モードか? Then If Sw_2 = 0 Then Goto Adtest 'If A/Dコンバータのテスト・モードか? Then ' ' * 変数の初期値を設定 * ' Lcdmode = 2 'LCDの表示がON状態。 Avgpoi = 1 '移動平均のポインターを初期化。 Dbufpoi = 1 '24時間のデータバッファーポインターを初期化。 Tbuffpoi = 1 '8日分の記録バッファー用ポインターを初期化。 Weather = 4 '天気の初期値。 Sectemp = 255 '[秒]の更新テンポラリの初期化。 Hourtemp = 255 '[分]の更新テンポラリの初期化。 Bpintcun = 254 '[気圧測定]を強制起動する。 Adintcun = 254 '[温度測定]を強制起動する。 _year = 18 '[年]の初期値。 _month = 1 '[月]の初期値。 _day = 1 '[日]の初期値。 Enable Interrupts 'すべての割り込みを許可。 ' ' ******************* ' * メイン ルーチン * ' ******************* ' Main: Power Powersave 'スリープモードへ移行する。(1秒割り込みで再起動する) ' If Sectemp <> _sec Then 'If [秒]が更新されたか? Then Sectemp = _sec If Lcdmode > 1 Then 'If LCDがON状態か? Then Gosub Timedisp '日時をLCDに表示する。 End If ' ' * ワンショット動作中の処理 * ' If Lcdmode > 2 Then 'If ワンショット動作中か? Then Oneshcun = Oneshcun - 1 'ワンショット動作時間のカウント。 If Oneshcun = 0 Then 'ワンショット時間の終了か? Then If Lcdmode = 3 Then 'If ワンショットON動作中か? Then Gosub Lcdoff 'LCDをOFFにする。 End If Reset Back_light 'LCDのバックライトをOFFにする。 Lcdmode = Modetemp 'ワンショット以前のモードに戻す。 End If End If ' ' * A/D変換(温度+CDS)の処理 * ' Adintcun = Adintcun + 1 If Adintcun >= Adinterval Then 'If 設定時間を経過したか? Then Adintcun = 0 Start Adc 'A/Dコンバータに電源を供給する。 Waitus 100 'AVR内部基準電源の安定待ち時間。 Tempw1 = Getadc(ad_cds) 'CDSセンサー値をA/D変換する。 ' If Lcdmode > 1 Then 'If LCDがON状態か? Then Tl1 = Getadc(ad_temp) '温度センサー値をA/D変換する。 Stop Adc 'A/Dコンバータの電源を切る。 ' Tl1 = Refvolt * Tl1 '1.100V(較正値)÷1024×1000000×[A/D値]÷1000 Shift Tl1 , Right , 10 , Signed '式を変えて 1.100V(較正値)×1000×[A/D値]÷1024 Temperature = Tl1 - Tempsenofs '温度センサーICの温度変換計算。 Gosub Tempdisp '温度値をLCDに表示する。 ' If Lcdmode = 2 Then 'If LCDが強制ON中か? Then If Serioutf = 0 Then 'If シリアル入出力がOFFか? Then If Tempw1 > Cdsmax Then 'If CDSが[暗]を検出したか? Then Lcdmode = 1 'ONから自動OFFへ変更する。 Gosub Lcdoff 'LCDをOFFにする。 End If End If End If Else 'LCDがOFFの状態。 If _min > 57 Then 'If 毎時58〜59分か? Then Set Power_temp '温度センサーの電源をONにする。 Tl1 = Getadc(ad_temp) '温度センサー値をA/D変換する。 Stop Adc 'A/Dコンバータの電源を切る。 ' Tl1 = Refvolt * Tl1 '1.100V(較正値)÷1024×1000000×[A/D値]÷1000 Shift Tl1 , Right , 10 , Signed '式を変えて 1.100V(較正値)×1000×[A/D値]÷1024 Temperature = Tl1 - Tempsenofs '温度センサーICの温度変換計算。 Else Stop Adc 'A/Dコンバータの電源を切る。 Reset Power_temp '温度センサーの電源をOFFにする。 End If ' If Lcdmode = 1 Then 'If LCDが自動OFF中か? Then If Tempw1 < Cdsmin Then 'If CDSが[明]を検出したか? Then Lcdmode = 2 '自動OFFからONへ。 Gosub Lcdon 'LCDをONにする。 End If End If End If End If ' ' * 気圧測定の処理 * ' Bpintcun = Bpintcun + 1 If Bpintcun >= Bpinterval Then 'If 設定時間を経過したか? Then Bpintcun = 0 Gosub Baravg '気圧値を取得して移動平均をする。 If Lcdmode > 1 Then 'If LCDがON状態か? Then Gosub Bardisp '気圧値をLCDに表示する。 End If ' If Serioutf <> 0 Then 'If シリアル入出力がONか? Then Gosub Seriout 'シリアル出力に測定値を送信する。 End If End If ' ' * 1時間毎の処理 * ' If _hour <> Hourtemp Then 'If 1時間経過したか? Then Hourtemp = _hour ' Gosub Weatherreport '気圧値24時間偏差を求めて天気を予報する。 ' Tbuff_tm(tbuffpoi) = Makeint(_hour , _day) '8日分の[時刻]記録バッファーに保存する。 Tbuff_bp(tbuffpoi) = Baropress '8日分の[気圧]記録バッファーに保存する。 ' Tempi1 = Deviation '[偏差+天気]の合成値を作る。 Shift Tempi1 , Left , 4 '[偏差]の下位12ビットを有効にする。 Temp1 = 0 Tempw1 = Makeint(weather , Temp1) Tempi1 = Tempi1 Or Tempw1 Tbuff_dt(tbuffpoi) = Tempi1 '8日分の[偏差+天気]記録バッファーに保存する。 ' Tbuff_tp(tbuffpoi) = Temperature '8日分の[温度]記録バッファーに保存する。 Tbuffpoi = Tbuffpoi + 1 'ポインターを更新する。 If Tbuffpoi > 192 Then 'If バッファーの終わりか? Then Tbuffpoi = 1 End If ' If Lcdmode > 1 Then 'If LCDがON状態か? Then If Dispmode < 3 Then 'If 簡易グラフ表示以外か? Then Gosub Divdisp '気圧の偏差値をLCDに表示する Gosub Weadisp '天気予報をLCDに表示する。 Else Cls 'LCDを全面消去する。 Gosub Graphdisp '簡易気圧グラフを表示する。 End If End If End If End If ' ' * スイッチ入力の処理 * ' If Swintf <> 0 Then 'If スイッチ入力が有るか? Then ' Swintf = 0 Waitms 30 'チャタリングの待ち時間。 Temp1 = 0 If Sw_1 = 0 Then 'If スイッチ[1]がONか?Then Set Temp1.0 'ビットに変換する。 End If If Sw_2 = 0 Then 'If スイッチ[2]がONか?Then Set Temp1.1 'ビットに変換する。 End If If Sw_3 = 0 Then 'If スイッチ[3]がONか?Then Set Temp1.2 'ビットに変換する。 End If ' If Temp1 = &B0000_0001 Then Goto Disppower 'If LCDの表示ON/OFFか? Then If Temp1 = &B0000_0100 Then Goto Oneshot 'If ワンショット動作か? Then If Lcdmode > 1 Then 'If LCDがON状態か? Then If Temp1 = &B0000_0010 Then Goto Chgmode 'If 表示タイプの切換か? Then If Temp1 = &B0000_0110 Then Goto Serimode 'If シリアル出力の切換か? Then If Temp1 = &B0000_0101 Then Goto Timeset 'If 時刻設定か? Then If Temp1 = &B0000_0011 Then Goto Oprset 'If 機能設定か? Then End If Swoffchk: Temp1 = Sw_1 And Sw_2 'スイッチが離されるのを待つ。 Temp1 = Temp1 And Sw_3 If Temp1 = 0 Then Goto Swoffchk 'If スイッチが押されているか? Then Waitms 30 'チャタリングの待ち時間。 Set Pcifr.pcif2 'ピン変化割り込みフラグをリセットする。 Enable Pcint2 'ピン変化割込を許可する。 End If ' ' * シリアル入力の処理 * ' If Serioutf <> 0 Then 'If シリアル入出力がONか? Then If Ucsr0a.fe0 = 1 Then 'If フレーミング・エラーが発生したか? Then Gosub Serioff 'シリアル入出力をOFFにする。 Gosub Seridisp 'シリアル入出力マークをLCDに表示する。 Else Temp1 = Inkey() Reset Temp1.5 '大文字に統一する。 Select Case Temp1 Case &H54 : '"T"キー入力。 Gosub Trendout '記録した測定データをシリアル送信する。 Case &H4D : '"M"キー入力。 Gosub Seriout 'シリアル出力に測定値を送信する。 Case &H51 : '"Q"キー入力。 Print "" Gosub Seriwait '送信終了まで待つ。 Waitms 50 'ハイパーターミナル用の対策。 Gosub Serioff 'シリアル入出力をOFFにする。 Gosub Seridisp 'シリアル入出力マークをLCDに表示する。 End Select End If End If Goto Main ' ' * LCDの表示ON/OFF * ' Disppower: If Lcdmode < 2 Then 'If LCDがOFF状態か? Then Lcdmode = 2 'OFFからONへ。 Adintcun = 0 Gosub Lcdon 'LCDをONにする。 Else Lcdmode = 0 'ONから強制OFFへ。 Gosub Lcdoff 'LCDをOFFにする。 End If Goto Swoffchk ' ' * ワンショット動作 * ' Oneshot: Modetemp = Lcdmode '以前のモードを保管する。 Oneshcun = Oneshtintv 'ワンショット動作の保持時間を設定。 Set Back_light 'LCDのバックライトをONにする。 If Lcdmode < 2 Then 'If LCDがOFF状態か? Then Lcdmode = 3 Gosub Lcdon 'LCDをONにする。 Else Lcdmode = 4 'LCDがON中。(バックライトのみON) End If Goto Swoffchk ' ' * 表示タイプの切り換え * ' Chgmode: Dispmode = Dispmode + 1 Chgmode1: Cls 'LCDを全面消去する。 If Dispmode > 3 Then 'If 表示モードの上限か? Then Dispmode = 0 Gosub Lcdcustom 'カスタム文字をLCDに設定する。 End If If Dispmode < 3 Then 'If 簡易グラフ表示以外か? Then Gosub Timedisp '日時をLCDに表示する。 Gosub Bardisp '気圧値をLCDに表示する。 Gosub Divdisp '気圧の偏差値をLCDに表示する Gosub Weadisp '天気予報をLCDに表示する。 Gosub Tempdisp '温度値をLCDに表示する。 Gosub Seridisp 'シリアル出力マークをLCDに表示する。 Else '簡易グラフ表示の場合。 Gosub Lcdcustom 'カスタム文字をLCDに設定する。 Gosub Graphdisp '簡易気圧グラフを表示する。 End If Goto Swoffchk ' ' * シリアル出力の切り換え * ' Serimode: If Serioutf = 0 Then 'If シリアル入出力はOFFか? Then If Pind.0 = 1 Then '[RXD]端子が[H]レベルになっているか? Then Serioutf = 1 'シリアル入出力を[ON]にする。 Reset Prr.prusart0 '電力削減 USART回路の起動。 Set Ucsr0a.u2x0 'USARTクロックの倍速許可。 Ubrr0l = 12 'ボーレートを9600に設定する。 Ubrr0h = 0 Set Ucsr0b.txen0 'USART送信許可を有効にする。 Set Ucsr0b.rxen0 'USART受信許可を有効にする。 If Lcdmode = 3 Then 'If LCDがOFFからのワンショット動作中か? Then Lcdmode = 4 Modetemp = 2 End If End If Else Gosub Serioff 'シリアル入出力をOFFにする。 End If Gosub Seridisp 'シリアル出力マークをLCDに表示する。 Goto Swoffchk ' ' * 時刻設定モード * ' Timeset: Gosub Tsetsub '時刻設定処理。 Goto Chgmode1 ' ' * 機能設定 * ' Oprset: Gosub Opsetsub '機能設定処理。 Goto Chgmode1 ' ' ------------------ ' * LCDをOFFにする * ' ------------------ ' Lcdoff: Reset Lcd_db4 'LCDの接続ポートをすべて[L]レベルにする。 Reset Lcd_db5 Reset Lcd_db6 Reset Lcd_db7 Reset Lcd_rs Reset Lcd_e Reset Power_lcd 'LCDモジュールの電源をOFFにする。 Reset Back_light 'LCDのバックライトをOFFにする。 Return ' ' ----------------- ' * LCDをONにする * ' ----------------- ' Lcdon: Set Power_temp '温度センサーの電源をONにする。 Adintcun = 254 '[温度測定]を強制起動して値を表示する。 Set Power_lcd 'LCDモジュールの電源をONにする。 Gosub Lcdinit 'LCDを初期化する。 If Dispmode < 3 Then 'If 簡易グラフ表示以外か? Then Gosub Timedisp '日時をLCDに表示する。 Gosub Bardisp '気圧値をLCDに表示する。 Gosub Divdisp '気圧の偏差値をLCDに表示する Gosub Weadisp '天気予報をLCDに表示する。 Gosub Seridisp 'シリアル出力マークをLCDに表示する。 Else '簡易グラフ表示の場合。 Gosub Graphdisp '簡易気圧グラフを表示する。 End If Return ' ' ------------------- ' * LCDを初期化する * ' ------------------- ' Lcdinit: Initlcd 'LCDを初期化する。 Cls 'LCDを全面消去する。 Gosub Lcdcustom 'カスタム文字をLCDに設定する。 Cursor Off 'LCDのカーソルをオフにする。 Return ' ' ------------------------------- ' * カスタム文字をLCDに設定する * ' ------------------------------- ' Lcdcustom: Deflcdchar 0 , &H08 , &H0C , &H0E , &H0F , &H0E , &H0C , &H08 , &H00 'カスタム文字[シリアル出力]をLCDへ書き込む。 If Dispmode < 3 Then 'If 簡易グラフ表示以外か? Then Deflcdchar 1 , &H10 , &H18 , &H14 , &H14 , &H02 , &H05 , &H06 , &H04 'カスタム文字[hp]をLCDへ書き込む。 Deflcdchar 2 , &H08 , &H14 , &H08 , &H06 , &H09 , &H08 , &H09 , &H06 'カスタム文字[℃]をLCDへ書き込む。 Deflcdchar 3 , &H02 , &H03 , &H02 , &H00 , &H00 , &H00 , &H00 , &H00 'カスタム文字[AM]をLCDへ書き込む。 Deflcdchar 4 , &H00 , &H00 , &H00 , &H00 , &H02 , &H03 , &H02 , &H00 'カスタム文字[PM]をLCDへ書き込む。 Deflcdchar 5 , &H04 , &H15 , &H0E , &H1F , &H0E , &H15 , &H04 , &H00 'カスタム文字[晴]をLCDへ書き込む。 Deflcdchar 6 , &H00 , &H0C , &H1E , &H1F , &H1F , &H0E , &H07 , &H00 'カスタム文字[雲]をLCDへ書き込む。 Deflcdchar 7 , &H04 , &H0E , &H1F , &H04 , &H04 , &H05 , &H02 , &H00 'カスタム文字[雨]をLCDへ書き込む。 Else Deflcdchar 1 , &H1F , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 'カスタム文字[バー0bit]をLCDへ書き込む。 Deflcdchar 2 , &H00 , &H1F , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 'カスタム文字[バー1bit]をLCDへ書き込む。 Deflcdchar 3 , &H00 , &H00 , &H1F , &H00 , &H00 , &H00 , &H00 , &H00 'カスタム文字[バー2bit]をLCDへ書き込む。 Deflcdchar 4 , &H00 , &H00 , &H00 , &H00 , &H1F , &H00 , &H00 , &H00 'カスタム文字[バー4bit]をLCDへ書き込む。 Deflcdchar 5 , &H00 , &H00 , &H00 , &H00 , &H00 , &H1F , &H00 , &H00 'カスタム文字[バー5bit]をLCDへ書き込む。 Deflcdchar 6 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H1F 'カスタム文字[バー7bit]をLCDへ書き込む。 Deflcdchar 7 , &H00 , &H00 , &H00 , &H00 , &H00 , &H11 , &H0A , &H04 'カスタム文字[下矢印]をLCDへ書き込む。 End If Return ' ' ----------------------------- ' * シリアル入出力をOFFにする * ' ----------------------------- ' Serioff: Serioutf = 0 'シリアル入出力を[OFF]にする。 Reset Ucsr0b.txen0 'USART送信許可を無効にする。 Reset Ucsr0b.rxen0 'USART受信許可を無効にする。 Set Prr.prusart0 '電力削減 USART回路の停止。 Reset Portd.1 'TXDポートを[L]にする。 Return ' ' ----------------------- ' * 日時をLCDに表示する * ' ----------------------- ' Timedisp: If Dispmode < 3 Then 'If 簡易グラフ表示以外か? Then Locate 1 , 1 Tempstr = Str(_month) '[月/日]の表示。 Lcd Format(tempstr , " ") ; "/" ; Tempstr = Str(_day) Lcd Format(tempstr , " ") ; " " ; ' If Dispmode < 2 Then 'If 秒表示は無いか? Then Temp1 = Dayofweek() '曜日を計算する。 Lcd Lookupstr(temp1 , Weekdata) ; '[曜日]を表示。 End If ' If Mf1224h = 1 Then 'If [時]表示モードが24時間制か? Then Tempstr = Str(_hour) '数値変数を文字変数に変換する。 Lcd " " ; Format(tempstr , " 0") ; '[時]を表示。 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 Lcd Chr(3) ; Else Lcd Chr(4) ; End If Tempstr = Str(temp1) '数値変数を文字変数に変換する。 Lcd Format(tempstr , " 0") ; '[時]を表示。 End If ' Tempstr = Str(_min) '数値変数を文字変数に変換する。 Lcd ":" ; Format(tempstr , "00") ; '[分]を表示。 ' If Dispmode = 2 Then 'If 秒表示が有りか? Then Tempstr = Str(_sec) '数値変数を文字変数に変換する。 Lcd ":" ; Format(tempstr , "00") '[秒]を表示。 End If End If Return ' ' ------------------------- ' * 気圧値をLCDに表示する * ' ------------------------- ' Bardisp: If Dispmode < 3 Then 'If 簡易グラフ表示以外か? Then Locate 2 , 1 'LCDへ気圧値を表示する。 Tempstr = Str(baropress) '数値を文字列に変換する。 Lcd Format(tempstr , " 0.0") ; Chr(1) End If Return ' ' ------------------------------- ' * 気圧の偏差値をLCDに表示する * ' ------------------------------- ' Divdisp: If Dispmode = 0 Then 'If 偏差の表示モードか? Then Tempstr = Str(deviation) '数値を文字列に変換する。 Locate 2 , 8 'LCDに24時間の偏差値を表示する。 Lcd Format(tempstr , "+ 0.0") End If Return ' ' --------------------------- ' * 天気予報をLCDに表示する * ' --------------------------- ' Weadisp: If Dispmode < 3 Then 'If 簡易グラフ表示以外か? Then Locate 2 , 15 '天気予報を表示する。 Select Case Weather Case 5 : '[晴れ] Lcd Chr(5) ; " " Case 4 : '[晴れ+曇り] Lcd Chr(5) ; Chr(6) Case 3 : '[曇り] Lcd Chr(6) ; " " Case 2 : '[雨] Lcd Chr(7) ; " " End Select End If Return ' ' ------------------------- ' * 温度値をLCDに表示する * ' ------------------------- ' Tempdisp: If Dispmode < 3 Then 'If 簡易グラフ表示以外か? Then If Dispmode > 0 Then 'If 温度の表示モードか? Then Locate 2 , 8 Tempstr = Str(temperature) '数値を文字列に変換する。 If Temperature < 0 Then 'If マイナス値か? Then If Temperature < -99 Then 'If -10.0℃以下か? Then Tempstr = Left(tempstr , 3) Lcd " " ; Tempstr ; Chr(2) ; " " Else '-9.9℃〜-0.1℃。 Lcd Format(tempstr , " 0.0") ; Chr(2) End If Else Lcd " " ; Format(tempstr , " 0.0") ; Chr(2) '0.0℃以上。 End If End If End If Return ' ' ------------------------------------- ' * シリアル出力マークをLCDに表示する * ' ------------------------------------- ' Seridisp: If Dispmode < 3 Then 'If 簡易グラフ表示以外か? Then Locate 1 , 16 If Serioutf = 0 Then 'If シリアル入出力はOFFか? Then Lcd Chr(&H20) Else Lcd Chr(8) End If End If Return ' ' ---------------------------------- ' * シリアル出力に測定値を送信する * ' ---------------------------------- ' Seriout: Tempstr = Str(_year) 'シリアル出力へ[年]の送信。 Print Format(tempstr , "00") ; "/"; Tempstr = Str(_month) 'シリアル出力へ[月]の送信。 Print Format(tempstr , "00") ; "/"; Tempstr = Str(_day) 'シリアル出力へ[日]の送信。 Print Format(tempstr , "00") ; " "; Tempstr = Str(_hour) 'シリアル出力へ[時]の送信。 Print Format(tempstr , "00") ; ":"; Tempstr = Str(_min) 'シリアル出力へ[分]の送信。 Print Format(tempstr , "00") ; ":"; Tempstr = Str(_sec) 'シリアル出力へ[秒]の送信。 Print Format(tempstr , "00") ; " "; ' Tempstr = Str(baropress) 'シリアル出力へ[気圧]の送信。 Print Format(tempstr , " 0.0") ; " hPa "; ' If Lcdmode > 1 Then 'If LCDがON状態か? Then Tempstr = Str(temperature) 'シリアル出力へ[温度]の送信。 Print Format(tempstr , " 0.0") ; " C"; End If ' Seriwait: Set Ucsr0a.txc0 'USART送信完了フラグをリセットする。 Print '改行を出力する。 Seriwait1: If Ucsr0a.txc0 = 0 Then Goto Seriwait1 'If USARTが送信完了していないか? Then Return ' ' ---------------------------------------- ' * 記録した測定データをシリアル送信する * ' ---------------------------------------- ' Trendout: Print Print "--- Start ---" Temp1 = Tbuffpoi '8日分の記録バッファー用ポインター。 For Temp2 = 1 To 192 Temp3 = High(tbuff_tm(temp1)) Tempstr = Str(temp3) 'シリアル出力へ[日]の送信。 Print Format(tempstr , " 0") ; " "; Temp3 = Low(tbuff_tm(temp1)) Tempstr = Str(temp3) 'シリアル出力へ[時]の送信。 Print Format(tempstr , "00") ; ":00 "; ' Tempstr = Str(tbuff_bp(temp1)) 'シリアル出力へ[気圧]の送信。 Print Format(tempstr , " 0.0") ; " hPa "; ' Tempi1 = Tbuff_dt(temp1) '[偏差]値を16ビットに戻す。 Shift Tempi1 , Right , 4 , Signed Tempstr = Str(tempi1) 'シリアル出力へ[偏差]の送信。 Print Format(tempstr , "+ 0.0") ; " hPa "; ' Temp3 = Low(tbuff_dt(temp1)) 'シリアル出力へ[天気予報]の送信。 Temp3 = Temp3 And &H0F Select Case Temp3 Case 5 : '[晴れ] Print "Sunny "; Case 4 : '[晴れ+曇り] Print "Su-Cl "; Case 3 : '[曇り] Print "Cloudy "; Case 2 : '[雨] Print "Rain "; Case Else : '[無効] Print "------ "; End Select ' Tempstr = Str(tbuff_tp(temp1)) 'シリアル出力へ[温度]の送信。 Print Format(tempstr , " 0.0") ; " C" ' Temp1 = Temp1 + 1 If Temp1 > 192 Then 'If バッファーの終わりか? Then Temp1 = 1 End If Next Temp2 ' Print "--- 20"; Tempstr = Str(_year) 'シリアル出力へ[年]の送信。 Print Format(tempstr , "00") ; "/"; Tempstr = Str(_month) 'シリアル出力へ[月]の送信。 Print Format(tempstr , " 0") ; "/"; Tempstr = Str(_day) 'シリアル出力へ[日]の送信。 Print Format(tempstr , " 0") ; Print " --- End ---" Goto Seriwait ' ' ---------------------------- ' * 簡易気圧グラフを表示する * ' ---------------------------- ' Graphdisp: Temp3 = Tbuffpoi For Temp1 = 16 To 1 Step -1 'グラフの[X]個数。 Tempw1 = 0 For Temp2 = 1 To 3 '3時間毎のデータを取り出す。 If Temp3 = 1 Then 'If 8日分バッファーの先頭位置か? Then Temp3 = 192 Else Temp3 = Temp3 - 1 End If Tempw1 = Tempw1 + Tbuff_bp(temp3) Next Temp2 Tempw1 = Tempw1 / 30 '1/30。(3個の平均値と小数点以下を切り捨て) ' If Tempw1 < Pregbasis Then 'If 気圧グラフのベース気圧値以下か? Then Temp4 = 9 '[下矢印]を指定。 Temp5 = 2 '[Y]位置。 Else Tempw1 = Tempw1 - Pregbasis Shift Tempw1 , Left , 2 '4倍する。(1/2.5) Tempw1 = Tempw1 / 10 '1/10する。 Select Case Tempw1 Case Is < 8 : '0〜7の場合。 Temp5 = 2 '[Y]位置。 Temp4 = Tempw1 Case Is < 16 : '8〜15の場合。 Temp5 = 1 '[Y]位置。 Temp4 = Tempw1 - 8 Case Else : '16以上の場合。 Temp4 = 8 '[上矢印]を指定。 Temp5 = 1 '[Y]位置。 End Select End If Temp2 = Lookup(temp4 , Graphchr) Locate Temp5 , Temp1 Lcd Chr(temp2) Next Temp1 Return ' ' ********************************** ' * 気圧値を取得して移動平均をする * ' ********************************** ' Baravg: Gosub Baroconv '[MPL115A1]から気圧を取得し係数で補正する。 ' Avgsum = Avgsum - Average(avgpoi) '一番古いデータを減算する。 Average(avgpoi) = Tempw1 '移動平均バッファーに格納する。 Avgsum = Avgsum + Tempw1 '新しいデータを合算する。 ' Avgpoi = Avgpoi + 1 '移動平均ポインターを更新する。 If Avgpoi > 32 Then 'If ポインターが上限か? Then Avgpoi = 1 End If ' Tl4 = Avgsum Shift Tl4 , Right , 5 '32個の移動平均を取る。 Baropress = Tl4 '平均気圧値。 Return ' ' ****************************************** ' * 気圧値24時間偏差を求めて天気を予報する * ' ****************************************** ' Weatherreport: Tempw1 = Dbuf(dbufpoi) '24時間前のデータを読み出す。 Dbuf(dbufpoi) = Baropress '最新の気圧値を格納する。 Dbufpoi = Dbufpoi + 1 '24時間のデータバッファーポインターを更新する。 If Dbufpoi > 24 Then 'If ポインターが上限か? Then Dbufpoi = 1 End If ' Deviation = Baropress - Tempw1 '24時間の差分を求める。 ' Select Case Deviation Case Is > 50 : '[晴れ] Temp1 = 5 Case Is > 20 : '[晴れ+雲] Temp1 = 4 Case Is < -50 : '[雨] Temp1 = 2 Case Is < -20 : '[曇り] Temp1 = 3 Case Else : '[天候変化無し] Temp1 = Weather End Select Weather = Temp1 '天気予報値。 Return ' ' ********************************** ' * [MPL115A1]の気圧変換と係数補正 * (Tempw1 = 気圧値[XXXX.XhPa] ※整数値で下1桁が小数点以下) ' ********************************** ' Baroconv: ' Rxbuff(1) = &H12 '[圧力と温度] 両方の変換開始コマンド。 ' Rxbuff(2) = &H01 'コマンドに続くダミーのデータ。 ' I2csend &HC0 , Rxbuff(1) , 2 'I2Cバスで、2バイトのデータを送信する。 ' Reset Spi_dout 'MPL115A1の[DIN]端子を[L]にする。 Reset Spi_sck 'MPL115A1の[SCLK]端子を[L]にする。 Reset Spi_cs 'MPL115A1の[CS]を[L]にする。 Temp1 = &H24 '[24]を送信する。 Shiftout Spi_dout , Spi_sck , Temp1 , 1 Temp1 = 0 '[00]を送信する。 Shiftout Spi_dout , Spi_sck , Temp1 , 1 Set Spi_cs 'MPL115A1の[CS]を[H]にする。 Set Spi_sck 'MPL115A1の[SCLK]端子を[H]にする。 Set Spi_dout 'MPL115A1の[DIN]端子を[H]にする。 ' Waitms 10 'MPL115Aの変換待ち時間。 ' ' * [圧力と温度]のデータを読み出す * ' ' Rxbuff(1) = &H00 '[圧力の上位バイト Padc MSB]のメモリー・アドレスを指定する。 ' I2creceive &HC0 , Rxbuff(1) , 1 , 4 'I2Cバスで、1バイトのコマンドを送信し、4バイトのデータを受信する。 ' Reset Spi_dout 'MPL115A1の[DIN]端子を[L]にする。 Reset Spi_sck 'MPL115A1の[SCLK]端子を[L]にする。 Temp2 = 1 Reset Spi_cs 'MPL115A1の[CS]を[L]にする。 For Temp1 = &H80 To &H86 Step 2 Shiftout Spi_dout , Spi_sck , Temp1 , 1 Shiftin Spi_din , Spi_sck , Rxbuff(temp2) , 1 Temp2 = Temp2 + 1 Next Temp1 ' Temp1 = 0 '[00]を送信する。 ' Shiftout Spi_dout , Spi_sck , Temp1 , 1 Set Spi_cs 'MPL115A1の[CS]を[H]にする。 Set Spi_sck 'MPL115A1の[SCLK]端子を[H]にする。 Set Spi_dout 'MPL115A1の[DIN]端子を[H]にする。 ' ' * [圧力と温度]のA/D変換値をワードに変換し、下位10bitに移動する * ' Uipadc = Makeint(rxbuff(2) , Rxbuff(1)) '圧力のA/D変換値(8bit)を16bitにまとめる。 Shift Uipadc , Right , 6 '下位10bitに移動させる。 ' Uitadc = Makeint(rxbuff(4) , Rxbuff(3)) '温度のA/D変換値(8bit)を16bitにまとめる。 Shift Uitadc , Right , 6 '下位10bitに移動させる。 ' ' * 圧力のA/D変換値に係数を適用し補償する * ' Pcomp = a0 + (b1 + c12 * Tadc) * Padc + b2 * Tadc ' Tl1 = Sic12 'c12x2 = (((sint32)c12) * Tadc) >> 11; // c12x2 = c12 * Tadc Tl2 = Uitadc Tl2 = Tl1 * Tl2 Shift Tl2 , Right , 11 , Signed ' Tl1 = Sib1 'a1 = (sint32)b1 + c12x2; // a1 = b1 + c12x2 Tl2 = Tl1 + Tl2 ' Tl2 = Tl2 * Uipadc 'a1x1 = a1 * Padc; // a1x1 = a1 * Padc ' Tl1 = Sia0 'y1 = (((sint32)a0) << 10) + a1x1; // y1 = a0 + a1x1 Shift Tl1 , Left , 10 Tl2 = Tl1 + Tl2 ' Tl1 = Sib2 'a2x2 = (((sint32)b2) * Tadc) >> 1; // a2x2 = b2 * Tadc Tl1 = Tl1 * Uitadc Shift Tl1 , Right , 1 , Signed ' Tl1 = Tl2 + Tl1 'Pcomp =(y1 + A2x2) >> 9 ; / / Pcomp = Y1 + A2x2 Shift Tl1 , Right , 13 , Signed '小数点以下を切り捨てて整数にするために、13bit右シフト ' ' * 気圧値の計算 * ' 気圧値 = ((65.0 / 1023.0) * 圧力値) + 50 [kPa] = (圧力値 * 65000 + 51150000) / 1023 [Pa] ' Tl2 = Tl1 * 65000 Tl2 = Tl2 + 51150000 Tl2 = Tl2 / 10230 '[Pa]を[XXXX.XhPa]に変換する。 Tempw1 = Tl2 '※整数値で下1桁が小数点以下 Return ' ' **************** ' * 時刻設定処理 * ' **************** ' Tsetsub: Disable Timer2 '1秒割り込みを禁止。 _sec = 0 '[秒]をリセット。 ' Cls 'LCDを全面消去する。 Locate 1 , 1 Lcd "Time 20" ; Tempstr = Str(_year) '[年]の表示。 Lcd Format(tempstr , " ") ; "/" ; Tempstr = Str(_month) '[月]の表示。 Lcd Format(tempstr , " ") ; "/" ; Tempstr = Str(_day) Lcd Format(tempstr , " ") '[日]の表示。 ' Locate 2 , 2 Lcd "set " ; Tempstr = Str(_hour) Lcd Format(tempstr , " 0") ; ":" ; '[時]を表示。 Tempstr = Str(_min) Lcd Format(tempstr , "00") ; ":" ; '[分]を表示。 Tempstr = Str(_sec) Lcd Format(tempstr , "00") '[秒]を表示。 Cursor On , Blink 'LCDのカーソルをオン・点滅にする。 ' Bitwait Sw_1 , Set 'スイッチ[1]が離されるまで待つ。 Bitwait Sw_3 , Set 'スイッチ[3]が離されるまで待つ。 Waitms 30 'チャタリングの待ち時間。 ' Temp1 = _year '[年]の設定。 Temp2 = 0 'ゼロサプレス無しを指定。 Temp3 = 0 '設定値の下限。 Temp4 = 99 '設定値の上限。 Temp5 = 1 'カーソルの[Y]位置。 Temp6 = 8 'カーソルの[X]位置。 Gosub Tmskey '時刻設定用のキー入力処理。 _year = Temp1 ' Temp1 = _month '[月]の設定。 Temp2 = 1 'ゼロサプレス有りを指定。 Temp3 = 1 '設定値の下限。 Temp4 = 12 '設定値の上限。 Temp6 = 11 'カーソルの[X]位置。 Gosub Tmskey '時刻設定用のキー入力処理。 _month = Temp1 ' Temp4 = Lookup(_month , Monthtab) '月による設定値の上限を取得する。 If _month = 2 Then 'If 2月か? Then Temp3 = _year And &H03 '閏年の確認。 If Temp3 = 0 Then 'If 閏年か? Then Temp4 = 29 End If End If Temp1 = _day '[日]の設定。 Temp2 = 1 'ゼロサプレス有りを指定。 Temp3 = 1 '設定値の下限。 Temp6 = 14 'カーソルの[X]位置。 Gosub Tmskey '時刻設定用のキー入力処理。 _day = Temp1 ' Temp1 = _hour '[時]の設定。 Temp2 = 1 'ゼロサプレス有りを指定。 Temp3 = 0 '設定値の下限。 Temp4 = 23 '設定値の上限。 Temp5 = 2 'カーソルの[Y]位置。 Temp6 = 8 'カーソルの[X]位置。 Gosub Tmskey '時刻設定用のキー入力処理。 _hour = Temp1 ' Temp1 = _min '[分]の設定。 Temp2 = 0 '右桁のゼロサプレス無しを指定。 Temp3 = 0 '設定値の下限。 Temp4 = 59 '設定値の上限。 Temp6 = 11 'カーソルの[X]位置。 Gosub Tmskey '時刻設定用のキー入力処理。 _min = Temp1 ' Cursor Off , Noblink 'LCDのカーソルをオフ・点滅無しにする。 Timer2 = 0 Set Tifr2.tov2 'Timer2 オーバーフローフラグをリセットする。 Enable Timer2 '1秒割り込みを許可。 Return ' ' **************** ' * 機能設定処理 * ' **************** ' Opsetsub: Cls '[気圧測定間隔]の設定。 Lcd "Barometer" Locate 2 , 2 Lcd "Interval" ; Spc(4) ; "Sec" ' Bitwait Sw_1 , Set 'スイッチ[1]が離されるまで待つ。 Bitwait Sw_2 , Set 'スイッチ[2]が離されるまで待つ。 Waitms 30 'チャタリングの待ち時間。 Cursor On , Blink 'LCDのカーソルをオン・点滅にする。 ' Temp1 = Bpinterval Temp2 = 1 'ゼロサプレス有りを指定。 Temp3 = 1 '設定値の下限。 Temp4 = 60 '設定値の上限。 Temp5 = 2 'カーソルの[Y]位置。 Temp6 = 11 'カーソルの[X]位置。 Gosub Tmskey '時刻設定用のキー入力処理。 Bpinterval = Temp1 Eepbpinterval = Bpinterval ' Cls '[A/D間隔]の設定。 Lcd "A/D (Temp & CDS)" Locate 2 , 2 Lcd "Interval" ; Spc(4) ; "Sec" Temp1 = Adinterval Temp2 = 1 'ゼロサプレス有りを指定。 Temp3 = 1 '設定値の下限。 Temp4 = 60 '設定値の上限。 Temp6 = 11 'カーソルの[X]位置。 Gosub Tmskey '時刻設定用のキー入力処理。 Adinterval = Temp1 Eepadinterval = Adinterval ' Cls '[ワンショット動作時間]の設定。 Lcd "One Shot action" Locate 2 , 2 Lcd "Interval" ; Spc(4) ; "Sec" Temp1 = Oneshtintv Temp2 = 1 'ゼロサプレス有りを指定。 Temp3 = 5 '設定値の下限。 Temp4 = 99 '設定値の上限。 Temp6 = 11 'カーソルの[X]位置。 Gosub Tmskey '時刻設定用のキー入力処理。 Oneshtintv = Temp1 Eeponeshtintv = Oneshtintv ' Cls '[CDS感度]の設定。 Lcd "CDS Sensitivity" Locate 2 , 2 Lcd "9:Low 1:High" Temp1 = Cdsgain Temp2 = 1 'ゼロサプレス有りを指定。 Temp3 = 1 '設定値の下限。 Temp4 = 9 '設定値の上限。 Temp6 = 15 'カーソルの[X]位置。 Gosub Tmskey '時刻設定用のキー入力処理。 Cdsgain = Temp1 Eepcdsgain = Cdsgain Gosub Cdsgaset 'CDSの感度を計算する ' Cls '[12/24時間制]の選択。 Lcd "Hour Disp.select" Locate 2 , 2 Lcd "1:12H 2:24H" Temp1 = Mf1224h + 1 Temp2 = 1 'ゼロサプレス有りを指定。 Temp3 = 1 '設定値の下限。 Temp4 = 2 '設定値の上限。 Temp6 = 14 'カーソルの[X]位置。 Gosub Tmskey '時刻設定用のキー入力処理。 Mf1224h = Temp1 - 1 Eep1224h = Mf1224h ' Cls '[AVR基準電圧]の較正。 Lcd "AVR Ref. Voltage" Locate 2 , 1 Lcd "Adjustment 1." ; Spc(2) ; "V" Start Adc 'A/Dコンバータに電源を供給する。 Temp1 = Eeprefvolt Temp2 = 0 'ゼロサプレス無しを指定。 Temp3 = 00 '設定値の下限。 Temp4 = 20 '設定値の上限。 Temp6 = 14 'カーソルの[X]位置。 Gosub Tmskey '時刻設定用のキー入力処理。 Stop Adc 'A/Dコンバータの電源を切る。 Eeprefvolt = Temp1 Refvolt = Temp1 * 10 'AVRの内部基準電圧較正値を計算する。 Refvolt = Refvolt + 1000 ' Cls '[温度センサー]の選択。 Lcd "Temp.sensor Type" Locate 2 , 1 Lcd "1:MCP97 2:LM61" Temp1 = Tempsentype Temp2 = 1 'ゼロサプレス有りを指定。 Temp3 = 1 '設定値の下限。 Temp4 = 2 '設定値の上限。 Temp6 = 15 'カーソルの[X]位置。 Gosub Tmskey '時刻設定用のキー入力処理。 Tempsentype = Temp1 Eeptempsentype = Tempsentype Gosub Tsentype '温度センサーの係数を選択する。 ' Cls '[気圧グラフのベース気圧値]設定。 Lcd "Pressure Graph" Locate 2 , 4 Lcd "Basis" ; Spc(3) ; "0 hPa" Temp1 = Eeppregbasis Temp2 = 1 'ゼロサプレス有りを指定。 Temp3 = 50 '設定値の下限。 Temp4 = 99 '設定値の上限。 Temp6 = 10 'カーソルの[X]位置。 Gosub Tmskey '時刻設定用のキー入力処理。 Eeppregbasis = Temp1 Pregbasis = Temp1 * 10 'ベース気圧値。 ' Cursor Off , Noblink 'LCDのカーソルをオフ・点滅無しにする。 Return ' ' ------------------------------------ (Temp1 = 設定するデータ値 , Temp2 = 0:ゼロサプレス無し 1:有り) ' * 時刻設定用 キー入力 サブルーチン * (Temp3 = 設定値の下限 , Temp4 = 設定値の上限) ' ------------------------------------ (Temp5 = カーソルの[Y]位置 , Temp6 = カーソルの[X]位置) ' Tmskey: Locate Temp5 , Temp6 Gosub Tsetdisp '設定値を表示する。 Locate Temp5 , Temp6 Bitwait Sw_1 , Set 'スイッチ[1]が離されるまで待つ。 Waitms 30 'チャタリングの待ち時間。 Tmskey4: Debounce Sw_1 , 0 , Tmskey1 'If スイッチ[1]が押されたか? Then Debounce Sw_2 , 0 , Tmskey2 'If スイッチ[2]が押されたか? Then Debounce Sw_3 , 0 , Tmskey3 'If スイッチ[3]が押されたか? Then Goto Tmskey4 ' ' Tmskey1: 'スイッチ[1] 設定終了。 Return ' ' Tmskey2: 'スイッチ[2] 設定値を加算。 Temp1 = Temp1 + 1 If Temp1 > Temp4 Then 'If 設定値が上限を超えたか? Then Temp1 = Temp3 End If ' Gosub Tsetdisp '設定値を表示する。 Bitwait Sw_2 , Set 'スイッチ[2]が離されるまで待つ。 Waitms 30 'チャタリングの待ち時間。 Goto Tmskey4 ' ' Tmskey3: 'スイッチ[3] 設定値を減算。 If Temp1 = Temp3 Then 'If 設定値が下限を超えるか? Then Temp1 = Temp4 Else Temp1 = Temp1 - 1 End If ' Gosub Tsetdisp '設定値を表示する。 Bitwait Sw_3 , Set 'スイッチ[3]が離されるまで待つ。 Waitms 30 'チャタリングの待ち時間。 Goto Tmskey4 ' ' -------------------------------- ' * 設定値を表示するサブルーチン * ' -------------------------------- ' Tsetdisp: Tempstr = Str(temp1) '数値変数を文字変数に変換する。 If Temp2 = 0 Then 'If ゼロサプレス無しか? Then Lcd Format(tempstr , "00") Else Lcd Format(tempstr , " 0") End If Locate Temp5 , Temp6 Return ' ' ----------------------- ' * CDSの感度を計算する * ' ----------------------- ' Cdsgaset: If Cdsgain = 1 Then Cdsmax = 100 Cdsmin = 50 Else Cdsmax = Cdsgain * 100 Cdsmin = Cdsmax - 100 End If Return ' ' -------------------------------- ' * 温度センサーの係数を選択する * ' -------------------------------- ' Tsentype: If Tempsentype = 1 Then 'If 温度センサーは[MCP9700-E/TO]か? Then Tempsenofs = 500 '[MCP9700-E/TO] Else Tempsenofs = 600 '[LM61BIZ] End If Return ' ' ************************************************** ' * 32.768KHz 水晶較正用 16.384KHz出力 [PB3:17pin] * ' ************************************************** ' Calout: Cls Lcd "Xtal Calibration" 'タイトルを表示する。 Locate 2 , 1 Lcd "16.384KHz pin:17" ' Config Timer2 = Timer , Prescale = 1 , Async = On , Clear Timer = 1 , Compare A = Toggle Ocr2a = 0 Stop ' ' ********************************* ' * A/Dコンバータのテスト・モード * ' ********************************* ' Adtest: Set Power_temp '温度センサーの電源をONにする。 Do Start Adc 'A/Dコンバータに電源を供給する。 Waitus 100 'AVR内部基準電源の安定待ち時間。 Tempw1 = Getadc(ad_cds) 'CDSセンサー値をA/D変換する。 Tl1 = Getadc(ad_temp) '温度センサー値をA/D変換する。 Stop Adc 'A/Dコンバータの電源を切る。 ' Tl1 = Refvolt * Tl1 '1.100V(較正値)÷1024×1000000×[A/D値]÷1000 Shift Tl1 , Right , 10 , Signed '式を変えて 1.100V(較正値)×1000×[A/D値]÷1024 Temperature = Tl1 - Tempsenofs '温度センサーICの温度変換計算。 ' Tempstr = Str(temperature) '数値変数を文字変数に変換する。 Locate 1 , 1 'LCDに温度を表示する。 Lcd "Temp: " ; Format(tempstr , "00.0") ; " c " Locate 2 , 1 Lcd " CDS: " ; Tempw1 ; " " Waitms 500 Loop ' ' **************************** ' * スイッチ割り込みルーチン * ' **************************** ' Swint: Disable Pcint2 'ピン変化割込を禁止する。 Swintf = 1 'スイッチ割り込みフラグをセットする。 Return ' ' End ' ' * 曜日 データ・テーブル * ' Weekdata: Data "MON" , "TUE" , "WED" , "THU" , "FRI" , "SAT" , "SUN" ' ' * 月ごとの最終日を取得するテーブル * ' Monthtab: Data 0 , 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 ' ' * 簡易気圧グラフのキャラクター・テーブル * ' Graphchr: Data &H06 , &H5F , &H05 , &H04 , &H2D , &H03 , &H02 , &H01 , &H5E , &H07