$prog &HFF , &H62 , &HDF , &HF9 'ヒューズ設定。(工場出荷状態) ' ' *************************************************** ' * * ' * ATmega88PA RTC化 時計 + 温度計 V2 プログラム * ' * * ' * AVR is using ATmega88PA-PU * ' * Basic Compiler is BASCOM-AVR * ' * Copyright By O-Family 2013. 2.26 * ' *************************************************** ' ' Ver 2.01 初回公開バージョン ' ' Const Prgverh = 02 'プログラム・バージョン。(上位桁) Const Prgverl = 01 'プログラム・バージョン。(下位桁) ' ' $regfile = "m88pdef.dat" '使用するAVRを設定。 $crystal = 1000000 'AVRクロックを設定。 ' $hwstack = 64 'ハードウェア・スタックの容量を設定。 $swstack = 10 'ソフトウェア・スタックの容量を設定。 $framesize = 24 'フレーム領域の容量を設定。 ' ' * ポート名の定義 * ' Led_com1 Alias Portc.5 'LED[1]のコモン端子を接続するポート。 Led_com2 Alias Portc.4 'LED[2]のコモン端子を接続するポート。 Led_com3 Alias Portb.2 'LED[3]のコモン端子を接続するポート。 Led_com4 Alias Portb.1 'LED[4]のコモン端子を接続するポート。 Led_segh Alias Portb 'LEDのセグメント[H]側を接続するポート。 Led_segl Alias Portd 'LEDのセグメント[L]側を接続するポート。 Const Seg_dirh = &B0011_1110 'LEDのセグメント[H]側ポート方向ビット。 Const Seg_dirl = &B0001_1111 'LEDのセグメント[L]側ポート方向ビット。 ' 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]の接続ポート(プルアップ用)。 Pt_ex Alias Pinb.0 '予備端子の接続ポート。 Pt_expu Alias Portb.0 '予備端子の接続ポート(プルアップ用)。 ' Pt_power Alias Pinc.3 '電源電圧監視用のポート。 Ad_power Alias 3 '電源電圧監視用A/Dコンバータのチャネル番号。 Pt_cds Alias Portc.2 'CDSセンサーを[L]制御するポート。 Pt_senvdd Alias Portc.1 'センサー用の電源ポート。 Ad_temp Alias 0 '温度センサーを接続するA/Dコンバータのチャネル番号。 ' ' * LEDのセグメント・コードを指定する * ' Const Seg_blank = &B1111_1111 '[空白] Const Seg_minus = &B1101_1111 '[-] Const Seg_c = &B1101_1100 '[c] Const Seg_t = &B1101_0100 '[t] Const Seg_d = &B1001_1000 '[d] Const Seg_a = &B1000_0001 '[A] Const Seg_s = &B1001_0110 '[S] Const Seg_e = &B1100_0100 '[E] Const Seg_r = &B1101_1101 '[r] Const Seg_x = &B1001_0001 '[X] Const Seg_1d = &B0011_1011 '[1.] Const Seg_upbar = &B1110_1111 '[最高値] Const Seg_unbar = &B1111_1110 '[最低値] Const Seg_upunbar = &B1110_1110 '[最高最低値] ' ' * 変数の宣言 * ' Dim Dispmode As Byte '表示モード。 Dim Modetemp As Byte '表示モードの保管用。 Dim Mf1224h As Byte '時間表示モード 0=12時間制 / 1=24時間制 Dim Timetemp As Byte '[時分]と[温度]を交互表示の秒数。(1〜9秒) Dim Tempsenofs As Word '温度センサーの係数。 [MCP9700-E/TO] = 500 , [LM61BIZ] = 600 Dim Refvolt As Word 'AVRの内部基準電圧較正値。(Eeprefadj * 10 + 1000) Dim Tempsec As Byte '[秒]更新用テンポラリ。 Dim Tempday As Byte '[日]更新用テンポラリ。 Dim Dpblken As Byte 'D.P点滅許可フラグ。 Dim Tim500ms As Byte '500mSタイマー。 Dim Brightchf As Byte 'LEDの表示輝度変更フラグ。 Dim Keycun As Byte 'キー入力チェック用タイマーカウンター。 Dim Keyflg As Byte 'キー入力検出フラグ。 Dim Keydata As Byte 'キー入力データ。 Dim Keytemp As Byte 'キー入力用テンポラリ。 Dim Autodisptm As Byte '自動で表示を切り換えるタイマー。 Dim Temperature As Integer '温度値。(x0.1) Dim Tempmax As Integer '温度の最高値。(x0.1) Dim Tempmin As Integer '温度の最低値。(x0.1) ' Dim Leddata1h As Byte '1桁目-[H]側のDMA表示データ。 Dim Leddata1l As Byte '1桁目-[L]側のDMA表示データ。 Dim Leddata2h As Byte '2桁目-[H]側のDMA表示データ。 Dim Leddata2l As Byte '2桁目-[L]側のDMA表示データ。 Dim Leddata3h As Byte '3桁目-[H]側のDMA表示データ。 Dim Leddata3l As Byte '3桁目-[L]側のDMA表示データ。 Dim Leddata4h As Byte '4桁目-[H]側のDMA表示データ。 Dim Leddata4l As Byte '4桁目-[L]側のDMA表示データ。 Dim Dmano As Byte 'DMAの表示番号。 Dim Tempsegh As Byte 'LEDのセグメント[H]側への出力値保管用。 Dim Tempsegl As Byte 'LEDのセグメント[L]側への出力値保管用。 Dim Segcode As Byte 'セグメントのコード。 Dim Segcodeh As Byte 'セグメントコード[H]側の変換値。 Dim Segcodel As Byte 'セグメントコード[L]側の変換値。 Dim Tintbflag As Byte 'LEDのブランキング期間フラグ。 ' 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 Temp8 As Byte '汎用テンポラリ変数 Byte型 No.8 Dim Temp9 As Byte '汎用テンポラリ変数 Byte型 No.9 Dim Temp10 As Byte '汎用テンポラリ変数 Byte型 No.10 Dim Tempw1 As Word '汎用テンポラリ変数 Word型 No.1 Dim Tempw2 As Word '汎用テンポラリ変数 Word型 No.2 Dim Tempi1 As Integer '汎用テンポラリ変数 Integer型 No.1 Dim Templ1 As Long '汎用テンポラリ変数 Long型 No.1 ' Dim Dummy As Eram Long 'EEPROM 4バイトのダミーエリア。 Dim Eep1224h As Eram Byte 'EEPROM 時間表示モード。(0:12時間制 , 1:24時間制) Dim Eepextremum As Eram Byte 'EEPROM 最高最低値のリセット選択。 (0=リセットしない , 1=日付変更時) Dim Eeptimetemp As Eram Byte 'EEPROM 時刻と温度を交互表示する秒数。(1〜9秒) Dim Eepautodisptm As Eram Byte 'EEPROM 自動で[SW3]の表示を切り換える秒数。(2〜60秒) Dim Eeptempsentype As Eram Byte 'EEPROM 温度センサーの種別。(0:MCP9700 , 1:LM61) Dim Eeprefadj As Eram Byte 'EEPROM AVR 1.1V基準電圧の校正値。(1.00〜1.20V) ' ' * ポートの初期設定 * ' Gosub Portinit 'ポートの初期設定を行う。 Set Prr.prusart0 '電力削減 USART回路の停止。 Set Prr.prspi '電力削減 SPI回路の停止。 Set Prr.prtwi '電力削減 TWI回路の停止。 ' ' * Timerの設定 * ' Config Timer0 = Pwm , Prescale = 8 , Clear Timer = 1 'LEDのDMA用 1,000,000Hz / 8 = 125,000Hz Set Tccr0b.wgm02 '高速PWMモード。 (TOP = OCR0A) Compare0a = 125 - 1 'スキャン周波数。(125,000Hz ÷ 125カウント = 1,000Hz) Compare0b = 110 'パルス幅 (暗15〜明110) 1カウントは8μS。 On Compare0a Tint0a 'TIMER0比較一致A割り込みルーチンのラベルを設定。 Enable Compare0a 'TIMER0比較一致A割り込みを許可する。 On Compare0b Tint0b 'TIMER0比較一致B割り込みルーチンのラベルを設定。 Enable Compare0b 'TIMER0比較一致B割り込みを許可する。 ' Config Timer1 = Timer , Prescale = 1 , Clear Timer = 1 '10mSタイマー Compare1a = 10000 - 1 '1,000,000Hz / 10000 = 100Hz (10mS) ' ' * A/Dコンバーターの設定 * ' Config Adc = Single , Prescaler = Auto , Reference = Avcc 'A/Dコンバータの設定。 Start Adc 'A/Dコンバータに電源を供給。 Config Aci = Off 'アナログ比較器の電源を切る。 ' ' * 時計用のライブラリを組み込む * ' Config Clock = Soft '時計(Timer2を使用)をSoftモードに設定。 Config Date = Ymd , Separator = / '日付の表現方法(形式)を設定。 ' ' * EEPROMのデータを確認する * ' If Eep1224h > 1 Then 'If EEPROMが初期値か? Then Eep1224h = 1 '時間表示モード。(0:12時間制 , 1:24時間制) Eepextremum = 1 '最高最低値のリセット選択。 (0=リセットしない , 1=日付変更時) Eeptimetemp = 8 '[時分]と[温度]を交互表示の秒数。(1〜9秒) Eepautodisptm = 5 '自動で[SW3]の表示を切り換えるタイマー。(2〜60秒) Eeptempsentype = 0 '温度センサーの種別。(0:MCP9700 , 1:LM61) Eeprefadj = 10 'AVR 1.1V基準電圧の校正値。(0〜20→1.00〜1.20V) End If Mf1224h = Eep1224h Timetemp = Eeptimetemp Gosub Tsentype '温度センサーの係数を選択する。 Temp1 = Eeprefadj 'AVRの内部基準電圧較正値を計算する。 Refvolt = Temp1 * 10 'Eeprefadj(0〜20) * 10 + 1000 Refvolt = Refvolt + 1000 ' ' * 変数の初期設定 * ' Dmano = 1 'LEDのDMA表示番号の初期値。 Dispmode = 2 '表示モードの初期値。 _year = 13 _month = 1 _day = 1 Tempsec = 255 '[秒]の更新テンポラリの初期化。 Tempday = _day '[日]の更新テンポラリの初期化。 Tempmax = -400 '温度の最高値を初期化する。 Tempmin = 1250 '温度の最低値を初期化する。 Enable Interrupts 'すべての割り込みを許可。 ' ' * テスト・モードの確認 * ' If Sw_3 = 0 Then Goto Xtalcal 'If 32.768KHz 水晶較正モードか? Then ' ' * プログラム・バージョンを表示 * ' Prgvds: Temp1 = Prgverh 'プログラム・バージョンの上位を表示。 Temp2 = &H41 'LEDの左2桁を小数点有りで指定。 Gosub Binsegwr 'バイナリ値を2桁のセグメントコードに変換してLED表示する。 ' Temp1 = Prgverl 'プログラム・バージョンの下位を表示。 Temp2 = 0 'LEDの下位桁を指定。 Temp3 = 0 '設定値の下限。 Temp4 = 99 '設定値の上限。 Gosub Tmskey '時刻設定用のキー入力処理。 ' ' ******************* ' * メイン ルーチン * ' ******************* ' Main: Gosub Expower '外部電源の電圧を監視する。(スリープモードに移行する) Gosub Every10ms '10mSごとの処理を行う。(キーチェック) Gosub Ledbright 'LEDの輝度を調整する。 Gosub Dispren1s '1秒ごとに表示を更新する。 Gosub Keycont 'キー入力により表示を切り換える。 Goto Main ' ' ************************************ ' * 外部電源の電圧を監視するルーチン * ' ************************************ ' Expower: Tempw1 = Getadc(ad_power) '外部電源の電圧値をA/D変換する。 If Tempw1 > 920 Then Return 'If 外部電源の電圧が4.5V以上有るか? Then Tempw1 = Getadc(ad_power) '外部電源の電圧値をA/D変換する。 If Tempw1 > 920 Then Return 'If 外部電源の電圧が4.5V以上有るか? Then ' ' * スリープモードへ移行する * ' Stop Adc 'A/Dコンバータの電源を切る。 Stop Timer0 'タイマー0を停止させる。 Stop Timer1 'タイマー1を停止させる。 Set Prr.prtim0 '電力削減 Timer0回路の停止。 Set Prr.prtim1 '電力削減 Timer1回路の停止。 Disable Compare0a 'TIMER0比較一致A割り込みを禁止する。 Disable Compare0b 'TIMER0比較一致B割り込みを禁止する。 ' Config Portb = Input 'PORTBをすべて入力に設定する。 Config Portc = Input 'PORTCをすべて入力に設定する。 Config Portd = Input 'PORTDをすべて入力に設定する。 Portb = 0 'PORTBのプルアップをすべて解除する。 Portc = 0 'PORTCのプルアップをすべて解除する。 Portd = 0 'PORTDのプルアップをすべて解除する。 Didr0 = &B0011_0111 'デジタル入力禁止レジスタの設定。(外部電源の監視を有効にする) ' Slploop: Powersave 'スリープモードへ移行する。(1秒割り込みで再起動する) If Pt_power = 0 Then Goto Slploop 'If 外部電源が切れているか? Then ' ' * 外部電源が復旧後、通常動作へ移行する * ' Gosub Portinit 'ポートの初期設定を行う。 Reset Prr.prtim0 'Timer0回路の起動。 Reset Prr.prtim1 'Timer1回路の起動。 Start Adc 'A/Dコンバータに電源を供給。 If Dispmode <> 0 Then 'If 完全消灯モード以外か? Then Start Timer0 'タイマー0を再始動させる。 Set Tccr0b.wgm02 '高速PWMモード。 (TOP = OCR0A) End If Start Timer1 'タイマー1を再始動させる。 Enable Compare0a 'TIMER0比較一致A割り込みを許可する。 Enable Compare0b 'TIMER0比較一致B割り込みを許可する。 Waitms 5 'A/Dの基準電圧が安定するまでの待ち時間。 Return ' ' -------------------------------------- ' * ポートの初期設定を行うサブルーチン * ' -------------------------------------- ' Portinit: Set Led_com1 '全ての桁のコモン信号をオフする。 Set Led_com2 Set Led_com3 Set Led_com4 Config Led_com1 = Output 'LED[1]のコモン端子接続ポートを出力に設定。 Config Led_com2 = Output 'LED[2]のコモン端子接続ポートを出力に設定。 Config Led_com3 = Output 'LED[3]のコモン端子接続ポートを出力に設定。 Config Led_com4 = Output 'LED[4]のコモン端子接続ポートを出力に設定。 Config Led_segh = Seg_dirh 'LEDのセグメント[H]側接続ポートを出力に設定。 Config Led_segl = Seg_dirl 'LEDのセグメント[L]側接続ポートを出力に設定。 Didr0 = &B0011_1111 'デジタル入力禁止レジスタの設定。 Config Pt_senvdd = Output '温度センサー用の電源ポートを出力に設定。 Set Pt_senvdd '温度センサーに電源を供給する。 Reset Pt_cds 'CDSセンサーの制御ポートを出力時に[L]にする。(ポート方向でON/OFFする) Set Sw_1pu 'スイッチ[1]の接続ポートをプルアップ。 Set Sw_2pu 'スイッチ[2]の接続ポートをプルアップ。 Set Sw_3pu 'スイッチ[3]の接続ポートをプルアップ。 Set Pt_expu '予備端子の接続ポートをプルアップする。 Tempsegh = Led_segh 'LEDのセグメント[H]側への出力値を保管する。 Tempsegl = Led_segl 'LEDのセグメント[L]側への出力値を保管する。 Return ' ' ************************************************ ' * 10mSごとに処理を行うルーチン (キーチェック)* ' ************************************************ ' Every10ms: If Tifr1.ocf1a = 0 Then Return 'If 10mS経過したか? Else Set Tifr1.ocf1a 'Timer1 比較A一致フラグをリセット。 ' Tim500ms = Tim500ms + 1 '500mSタイマーを加算。 Select Case Tim500ms Case 50 : '[D.P]点灯から500mS経過した。 If Dpblken = 1 Then 'If [D.P]の点滅が許可されているか? Then Set Leddata3h.5 '3桁目の小数点を消灯。 End If Case 25 : '500mSごとにLEDの輝度を調整する。 Brightchf = 1 Case 75 : '500mSごとにLEDの輝度を調整する。 Brightchf = 1 End Select ' ' * キー入力を確認する * (Keyflg = キー入力が有ると1) , (Keydata = キーデータ) ' Keychk: 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 リピート期間待ち(1Sec)か? 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 ' ' -------------------------------------------------- ' * キー接続ポートからデータを入力するサブルーチン * (Keydat = キー・データ) ' -------------------------------------------------- ' Keyport: Keydata = 0 If Sw_1 = 0 Then Set Keydata.0 'If [SW1]が押されているか? Then If Sw_2 = 0 Then Set Keydata.1 'If [SW2]が押されているか? Then If Sw_3 = 0 Then Set Keydata.2 'If [SW3]が押されているか? Then Return ' ' ******************************* ' * LEDの輝度を調整するルーチン * ' ******************************* ' Ledbright: If Brightchf <> 0 Then 'If 500mS経過したか? Then Brightchf = 0 ' Config Pt_cds = Output 'CDSセンサーの制御ポートを出力[L]にする。 Waitus 10 Tempw1 = Getadc(ad_power) 'CDSセンサーをA/D変換する。(電源監視Ch.と共用) Config Pt_cds = Input 'CDSセンサーの制御ポートを入力[オープン]にする。 ' Select Case Tempw1 '明るさのしきい値をチェックする。 Case Is > 800 : 'If 上限値を超えたか? Then Tempw1 = 800 Case Is < 100 : 'If 下限値を超えたか? Then Tempw1 = 100 End Select ' Tempw1 = 800 - Tempw1 'CDSの[暗800〜明100]値をパルス幅[15〜109]に変換する。 Tempw1 = Tempw1 * 10 Tempw1 = Tempw1 / 74 Tempw1 = Tempw1 + 15 Temp1 = Tempw1 Ocr0b = Temp1 'パルス幅を変更する。 End If Return ' ' **************************************** ' * 1秒ごとにLEDの表示を更新するルーチン * ' **************************************** ' Dispren1s: If Tempsec = _sec Then Return 'If [秒]が更新されたか? Else Tempsec = _sec Tim500ms = 0 '500mSタイマーを初期化。 ' Gosub Thermo '温度値を計測する。 ' If Tempday <> _day Then 'If 日付が変わったか? Then Tempday = _day If Eepextremum <> 0 Then 'If 温度湿度の最高最低値を日付変更時に初期化するか? Then Tempmax = Temperature '温度の最高値と最低値を初期化する。 Tempmin = Temperature End If End If ' ' * LEDに情報を表示する * ' Displed: On Dispmode Goto Dlmode0 , Dlmode0 , Dlmode2 , Dlmode3 , Dlmode4 , Dlmode5 , Dlmode6 , Dlmode7 , Dlmode8 , Dlmode9 ' ' * MODE(0) 表示オフ * ' Dlmode0: Gosub Ledoffright 'LEDの右2桁を消灯する。 Gosub Ledoffleft 'LEDの左2桁を消灯する。 Goto Dlmode21 ' ' * MODE(2) [時・分]を表示 * ' Dlmode2: Temp1 = _min '[分]を表示。 Temp2 = 0 'LEDの右2桁を指定。 Gosub Binsegwr 'バイナリ値を2桁のセグメントコードに変換してLED表示する。 Temp1 = _hour '[時]を表示。 Temp2 = 3 'LEDの左2桁をゼロサプレスで指定。 Gosub Hourcvwr '時間を12/24時間制で識別して表示。 ' Dlmode21: If Tim500ms < 50 Then 'If [D.P]点灯期間か? Then Reset Leddata3h.5 '3桁目に小数点を表示。 End If Dpblken = 1 '[D.P]の点滅を許可する。 Return ' ' * MODE(3) [分・秒]を表示 * ' Dlmode3: Temp1 = _sec '[秒]を表示。 Temp2 = 0 'LEDの右2桁を指定。 Gosub Binsegwr 'バイナリ値を2桁のセグメントコードに変換してLED表示する。 Temp1 = _min '[分]を表示。 Temp2 = 1 'LEDの左2桁を指定。 Gosub Binsegwr 'バイナリ値を2桁のセグメントコードに変換してLED表示する。 Goto Dlmode21 ' ' * MODE(4) [温度]を表示 * ' Dlmode4: Tempi1 = Temperature Gosub Thermodisp '温度値を表示する。 Segcode = Seg_c '1桁目に[c]を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata1h = Segcodeh Leddata1l = Segcodel Dpblken = 0 '[D.P]の点滅を禁止する。 Return ' ' * MODE(5) [ t-c]を表示 * ' Dlmode5: If Autodisptm = 0 Then 'If 自動で表示を変える時間か? Then Dispmode = 6 Else Autodisptm = Autodisptm - 1 Segcode = Seg_blank '4桁目を消灯する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata4h = Segcodeh Leddata4l = Segcodel Segcode = Seg_t '3桁目に[t]を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata3h = Segcodeh Leddata3l = Segcodel Segcode = Seg_minus '2桁目に[-]を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata2h = Segcodeh Leddata2l = Segcodel Segcode = Seg_c '1桁目に[c]を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata1h = Segcodeh Leddata1l = Segcodel Dpblken = 0 '[D.P]の点滅を禁止する。 End If Return ' ' * MODE(6) [時分]と[温度]を交互表示 * ' Dlmode6: Temp1 = _sec Gosub Binseg 'バイナリ値をBCD値に変換する。 If Temp7 < Timetemp Then Goto Dlmode2 'If [秒]の下位が時刻表示の秒数か? Then Goto Dlmode4 '[秒]の下位が温度表示の秒数の場合。 ' ' * MODE(7) [月・日]を表示 * ' Dlmode7: If Autodisptm = 0 Then 'If 自動で[SW3]の表示を変える時間か? Then Dispmode = Modetemp Else Autodisptm = Autodisptm - 1 Temp1 = _day '[日]を表示。 Temp2 = &H42 'LEDの下位桁をゼロサプレス+小数点有りで指定。 Gosub Binsegwr 'バイナリ値を2桁のセグメントコードに変換してLED表示する。 Temp1 = _month '[月]を表示。 Temp2 = &H43 'LEDの上位桁をゼロサプレス+小数点有りで指定。 Gosub Binsegwr 'バイナリ値を2桁のセグメントコードに変換してLED表示する。 Dpblken = 0 '[D.P]の点滅を禁止する。 End If Return ' ' * MODE(8) 温度の最高値を表示 * ' Dlmode8: If Autodisptm = 0 Then 'If 自動で[SW3]の表示を変える時間か? Then Dispmode = Modetemp Else Autodisptm = Autodisptm - 1 Tempi1 = Tempmax Gosub Thermodisp '温度値を表示する。 Segcode = Seg_upbar '1桁目に[最高値]を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata1h = Segcodeh Leddata1l = Segcodel Dpblken = 0 '[D.P]の点滅を禁止する。 End If Return ' ' * MODE(9) 温度の最低値を表示 * ' Dlmode9: If Autodisptm = 0 Then 'If 自動で[SW3]の表示を変える時間か? Then Dispmode = Modetemp Else Autodisptm = Autodisptm - 1 Tempi1 = Tempmin Gosub Thermodisp '温度値を表示する。 Segcode = Seg_unbar '1桁目に[最高値]を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata1h = Segcodeh Leddata1l = Segcodel Dpblken = 0 '[D.P]の点滅を禁止する。 End If Return ' ' ------------------------------ ' * 温度を計測するサブルーチン * ' ------------------------------ ' Thermo: Config Adc = Single , Prescaler = Auto , Reference = Internal_1.1 'A/Dコンバータの基準電圧を変更。(内部1.1V) Waitms 5 'A/Dの基準電圧が安定するまでの待ち時間。 ' If Dispmode <> 0 Then 'If 完全消灯モード以外か? Then Tintbflag = 0 'LEDのブランキング期間フラグをリセットする。 Do Loop Until Tintbflag <> 0 'LEDのブランキング期間まで待機する。 End If Disable Interrupts 'すべての割り込みを禁止。 Templ1 = Getadc(ad_temp) '温度センサー値をA/D変換。 Enable Interrupts 'すべての割り込みを許可。 ' Config Adc = Single , Prescaler = Auto , Reference = Avcc 'A/Dコンバータの基準電圧を戻す。(AVCC) ' Templ1 = Refvolt * Templ1 '1.100V(較正値)÷1024×1000000×[A/D値]÷1000 Shift Templ1 , Right , 10 , Signed '式を変えて 1.100V(較正値)×1000×[A/D値]÷1024 Temperature = Templ1 - Tempsenofs '温度センサーICの温度変換計算。 ' If Tempmax < Temperature Then 'If 温度の最高値を超えたか? Then Tempmax = Temperature End If ' If Tempmin > Temperature Then 'If 温度の最低値を下回ったか? Then Tempmin = Temperature End If Waitms 1 'A/Dの基準電圧が安定するまでの待ち時間。 Return ' ' -------------------------------- ' * 温度値を表示するサブルーチン * (Tempi1 = 温度値) ' -------------------------------- ' Thermodisp: If Tempi1 >= 0 Then 'If プラスの温度か? Then Gosub Partbin 'バイナリ値を[100の位]と[10と1の位]に分ける。 Segcode = Temp8 '1位桁を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata2h = Segcodeh Leddata2l = Segcodel Segcode = Temp9 '10位桁を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Reset Segcodeh.5 '3桁目に小数点を表示。 Leddata3h = Segcodeh Leddata3l = Segcodel ' Temp1 = Tempw1 '100位桁を表示する。 If Temp1 <> 0 Then 'If 10℃以上か? Then Gosub Binseg 'バイナリ値を2桁のセグメントコードにに変換する。 Segcode = Temp8 '100位桁を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata4h = Segcodeh Leddata4l = Segcodel Else Segcode = Seg_blank '消灯。(ゼロサプレス) Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata4h = Segcodeh Leddata4l = Segcodel End If ' Else 'マイナスの温度。 Segcode = Seg_minus '[-]を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata4h = Segcodeh Leddata4l = Segcodel ' Tempi1 = Abs(tempi1) '絶対値を求める。 Gosub Partbin 'バイナリ値を[100の位]と[10と1の位]に分ける。 Temp1 = Tempw1 If Temp1 <> 0 Then 'If -10℃以下か? Then Segcode = Temp9 '[-10〜-99]で表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata2h = Segcodeh Leddata2l = Segcodel ' Gosub Binseg 'バイナリ値を2桁のセグメントコードにに変換する。 Segcode = Temp8 '100位桁を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata3h = Segcodeh Leddata3l = Segcodel Else '[-X.X]で表示する。 Segcode = Temp8 '[-10〜-99]で表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata2h = Segcodeh Leddata2l = Segcodel Segcode = Temp9 '10位桁を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Reset Segcodeh.5 '3桁目に小数点を表示。 Leddata3h = Segcodeh Leddata3l = Segcodel End If End If Return ' ' -------------------------------- ' * 温度センサーの係数を選択する * ' -------------------------------- ' Tsentype: If Eeptempsentype = 0 Then 'If 温度センサーは[MCP9700-E/TO]か? Then Tempsenofs = 500 '[MCP9700-E/TO] Else Tempsenofs = 600 '[LM61BIZ] End If Return ' ' ****************************************** ' * キー入力により表示を切り換えるルーチン * ' ****************************************** ' Keycont: If Keyflg = 0 Then Return 'If キー入力が有ったか? Else Keyflg = 0 ' Select Case Keydata Case &B0000_0001 : '[SW1]が押された場合。 Select Case Dispmode Case 0 : '完全消灯モードの場合。 Dispmode = Modetemp '消灯以前の状態に戻す。 Start Timer0 'LEDのダイナミック点灯を開始する。 Set Tccr0b.wgm02 '高速PWMモード。 (TOP = OCR0A) Case 1 : 'D.Pのみ点灯モードの場合。 Stop Timer0 'LEDのダイナミック点灯を停止する。 Set Led_com1 '全ての桁のコモン信号をオフする。 Set Led_com2 Set Led_com3 Set Led_com4 Dispmode = 0 '完全消灯モードにする。 Case Is > 6 : '[日付・最高最低温度]の場合。 Dispmode = 1 'D.Pのみ点灯モードにする。 Case Else : 'LEDが表示中の場合。 Modetemp = Dispmode '表示モードを保管する。 Dispmode = 1 'D.Pのみ点灯モードにする。 End Select ' Case &B0000_0010 : '[SW2]が押された場合。 Select Case Dispmode Case 0 : '完全消灯モードの場合。 Dispmode = Modetemp '消灯以前の状態に戻す。 Start Timer0 'LEDのダイナミック点灯を開始する。 Set Tccr0b.wgm02 '高速PWMモード。 (TOP = OCR0A) Case 1 : 'D.Pのみ点灯モードの場合。 Dispmode = Modetemp '消灯以前の状態に戻す。 Case Is < 7 : '[SW2]の表示モードの場合。 Dispmode = Dispmode + 1 If Dispmode > 5 Then 'If 最終値か? Then Dispmode = 2 '[時・分]表示にする。 End If Case Else : '[日付・最高最低温度]の場合。 Dispmode = Modetemp End Select Autodisptm = 2 '自動表示切り換えタイマーを設定する。 ' Case &B0000_0100 : '[SW3]が押された場合。 Select Case Dispmode Case Is < 2 : '消灯モードの場合。 '無視する。 Case Is < 7 : '[時分秒]または[温度]表示の場合。 Modetemp = Dispmode '[SW2]の表示モードを保管する。 Dispmode = 7 '[月・日]表示にする。 Case Else : '[SW3]の表示モードの場合。 Dispmode = Dispmode + 1 If Dispmode > 9 Then 'If 最終値か? Then Dispmode = 7 End If End Select Autodisptm = Eepautodisptm '自動表示切り換えタイマーを設定する。 ' Case &B0000_0110 : '[SW2+SW3]が押された場合。 Toggle Mf1224h.0 '時間表示モードを変更。 Eep1224h = Mf1224h 'EEPROMに保存。 Select Case Dispmode Case Is < 2 : '消灯モードの場合。 Case 5 : '[時分]と[温度]の交互表示モードの場合。 Case 6 : '[時分]と[温度]の交互表示モードの場合。 Case Else : Dispmode = 2 '[時・分]表示にする。 End Select ' Case &B0000_0101 : '[SW1+SW3]が押された場合。 If Dispmode > 1 Then Goto Timset '時刻設定処理。 ' Case &B0000_0011 : '[SW1+SW2]が押された場合。 If Dispmode > 1 Then Goto Modeset 'モード設定処理。 End Select Keycont1: Gosub Displed 'LEDに情報を表示する。 Return ' ' ************************* ' * 時刻設定 処理ルーチン * ' ************************* ' Timset: Disable Timer2 '1秒割り込みを禁止。 ' Temp1 = 20 '時刻設定モードに入ったことを表示する。 Temp2 = 1 'LEDの左2桁を指定。 Gosub Binsegwr 'バイナリ値を2桁のセグメントコードに変換してLED表示する。 Gosub Ledoffright 'LEDの右2桁を消灯する。 Gosub Keyoff 'キーが離されるまで待つ。 ' Temp1 = _year '[年]の設定。 Temp2 = 0 'LEDの左2桁を指定。 Temp3 = 0 '設定値の下限。 Temp4 = 99 '設定値の上限。 Gosub Tmskey '時刻設定用のキー入力処理。 _year = Temp1 ' Temp1 = _day '[月]の設定。 Temp2 = &H42 'LEDの右2桁をゼロサプレス+小数点有りで指定。 Gosub Binsegwr 'バイナリ値を2桁のセグメントコードに変換してLED表示する。 Temp1 = _month Temp2 = &H43 'LEDの左2桁をゼロサプレス+小数点有りで指定。 Temp3 = 1 '設定値の下限。 Temp4 = 12 '設定値の上限。 Gosub Tmskey '時刻設定用のキー入力処理。 _month = Temp1 ' Temp1 = _month '[日]の設定。 Temp2 = &H43 'LEDの左2桁をゼロサプレス+小数点有りで指定。 Gosub Binsegwr 'バイナリ値を2桁のセグメントコードに変換してLED表示する。 Temp1 = _day Temp2 = &H42 'LEDの右2桁をゼロサプレス+小数点有りで指定。 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 Temp3 = 1 '設定値の下限。 Gosub Tmskey '時刻設定用のキー入力処理。 _day = Temp1 ' Temp1 = _min '[時]の設定。 Temp2 = 0 'LEDの左2桁を指定。 Gosub Binsegwr 'バイナリ値を2桁のセグメントコードに変換してLED表示する。 Temp1 = _hour Temp2 = &HC3 'LEDの左2桁をゼロサプレス+小数点有りで指定。 Temp3 = 0 '設定値の下限。 Temp4 = 23 '設定値の上限。 Gosub Tmskey '時刻設定用のキー入力処理。 _hour = Temp1 ' Temp1 = _hour '[分]の設定。 Temp2 = &H43 'LEDの左2桁をゼロサプレス+小数点有りで指定。 Gosub Hourcvwr '時間を12/24時間制で識別して表示。 Temp1 = _min Temp2 = 0 'LEDの右2桁を指定。 Temp3 = 0 '設定値の下限。 Temp4 = 59 '設定値の上限。 Gosub Tmskey '時刻設定用のキー入力処理。 _min = Temp1 ' _sec = 0 '[秒]をリセット。 Enable Timer2 '1秒割り込みを許可。 Dispmode = 2 '[時・分]表示にする。 _sec = 0 '[秒]をリセット。(時計割り込み処理後) Goto Keycont1 ' ' *************************** ' * モード設定 処理ルーチン * ' *************************** ' Modeset: Segcode = Seg_t '4桁目に[t]を表示する。(モード設定に入ったことを表示する) Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata4h = Segcodeh Leddata4l = Segcodel Segcode = Seg_upunbar '3桁目に[最高最低値]を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata3h = Segcodeh Leddata3l = Segcodel Gosub Ledoffright 'LEDの右2桁を消灯する。 Gosub Keyoff 'キーが離されるまで待つ。 ' Temp1 = Eepextremum '[温度の最高値と最低値の初期化方法]を選択。(0=リセットしない , 1=日付変更時) Temp2 = 2 'LEDの右2桁をゼロサプレスで指定。 Temp3 = 0 '設定値の下限。 Temp4 = 2 '設定値の上限。 Gosub Tmskey '時刻設定用のキー入力処理。 If Temp1 = 2 Then 'If 最高最低値の強制リセットか? Then Tempmax = Temperature '温度の最高値と最低値を初期化する。 Tempmin = Temperature Else Eepextremum = Temp1 End If ' Segcode = Seg_t '4桁目に[t]を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata4h = Segcodeh Leddata4l = Segcodel Segcode = Seg_d '3桁目に[d]を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata3h = Segcodeh Leddata3l = Segcodel Temp1 = Timetemp '[時分]と[温度]を交互表示の秒数。(1〜9秒) Temp2 = 2 'LEDの右2桁をゼロサプレスで指定。 Temp3 = 1 '設定値の下限。 Temp4 = 9 '設定値の上限。 Gosub Tmskey '時刻設定用のキー入力処理。 Timetemp = Temp1 Eeptimetemp = Timetemp ' Segcode = Seg_a '4桁目に[A]を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata4h = Segcodeh Leddata4l = Segcodel Segcode = Seg_t '3桁目に[t]を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata3h = Segcodeh Leddata3l = Segcodel Temp1 = Eepautodisptm '自動で[SW3]の表示を切り換える秒数。(2〜60秒) Temp2 = 2 'LEDの右2桁をゼロサプレスで指定。 Temp3 = 2 '設定値の下限。 Temp4 = 60 '設定値の上限。 Gosub Tmskey '時刻設定用のキー入力処理。 Eepautodisptm = Temp1 ' Segcode = Seg_s '4桁目に[S]を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata4h = Segcodeh Leddata4l = Segcodel Segcode = Seg_e '3桁目に[E]を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata3h = Segcodeh Leddata3l = Segcodel Temp1 = Eeptempsentype '温度センサーの種別。(0:MCP9700 , 1:LM61) Temp2 = 2 'LEDの右2桁をゼロサプレスで指定。 Temp3 = 0 '設定値の下限。 Temp4 = 1 '設定値の上限。 Gosub Tmskey '時刻設定用のキー入力処理。 Eeptempsentype = Temp1 Gosub Tsentype '温度センサーの係数を選択する。 ' Config Adc = Single , Prescaler = Auto , Reference = Internal_1.1 'A/Dコンバータの基準電圧を変更。(内部1.1V) Segcode = Seg_r '4桁目に[r]を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata4h = Segcodeh Leddata4l = Segcodel Segcode = Seg_1d '3桁目に[1.]を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata3h = Segcodeh Leddata3l = Segcodel Temp1 = Eeprefadj 'AVR 1.1V基準電圧の校正値。(1.00〜1.20V) Temp2 = 0 'LEDの右2桁を指定。 Temp3 = 0 '設定値の下限。 Temp4 = 20 '設定値の上限。 Gosub Tmskey '時刻設定用のキー入力処理。 Eeprefadj = Temp1 Refvolt = Temp1 * 10 'AVRの内部基準電圧較正値を計算する。 Refvolt = Refvolt + 1000 Config Adc = Single , Prescaler = Auto , Reference = Avcc 'A/Dコンバータの基準電圧を戻す。(AVCC) ' Goto Keycont1 ' ' ------------------------------------ (Temp1 = 設定するデータ値) ' * 時刻設定用 キー入力 サブルーチン * (Temp2 = 設定するデータの桁位置 b0-0:右2桁 , b0-1:左2桁 , b7-0:通常 , b7-1:12/24制) ' ------------------------------------ (Temp3 = 設定値の下限) ' (Temp4 = 設定値の上限) Tmskey: Temp5 = 1 '点滅用 F/F。 Temp6 = 1 '点滅用タイマー値。 ' Tmskey1: If Tifr1.ocf1a = 0 Then Goto Tmskey1 'If 10mS経過したか? Else Set Tifr1.ocf1a 'Timer1 比較A一致フラグをリセットする。 ' Gosub Keychk 'キー入力を確認する。 If Keyflg <> 0 Then Goto Tmskey2 'If キー入力が有りか? Then ' Temp6 = Temp6 - 1 '表示を点滅させる。 If Temp6 <> 0 Then Goto Tmskey1 'If 点滅タイマー カウント終了か? Else If Temp5 = 0 Then '点滅用 F/Fを反転する。 Temp5 = 1 Temp6 = 20 '点滅用のタイマー値。 If Temp2.0 = 0 Then 'If 右2桁を設定中か? Then Gosub Ledoffright 'LEDの右2桁を消灯する。 Else Gosub Ledoffleft 'LEDの左2桁を消灯する。 End If Else Temp5 = 0 Temp6 = 40 '点滅用のタイマー値。 If Temp2.7 = 1 Then 'If [時]表示か? Then Gosub Hourcvwr '時間を12/24時間制で識別して表示する。 Else Gosub Binsegwr 'バイナリ値を2桁のセグメントコードに変換してLED表示する。 End If End If Goto Tmskey1 ' ' Tmskey2: Keyflg = 0 'キー入力フラグをリセットする。 If Keydata = &B0000_0001 Then Goto Tmskey5 'If [SW1]が押されたか? Then If Keydata = &B0000_0010 Then Goto Tmskey3 'If [SW2]が押されたか? Then If Keydata = &B0000_0100 Then Goto Tmskey4 'If [SW3]が押されたか? Then Goto Tmskey1 ' ' Tmskey3: '[SW2] 設定値を加算。 Temp1 = Temp1 + 1 If Temp1 > Temp4 Then 'If 設定値が上限を超えたか? Then Temp1 = Temp3 End If Goto Tmskey ' Tmskey4: '[SW3] 設定値を減算。 If Temp1 = Temp3 Then 'If 設定値が下限を超えるか? Then Temp1 = Temp4 Else Temp1 = Temp1 - 1 End If Goto Tmskey ' Tmskey5: '[SW1] 設定終了。 Gosub Keyoff 'キーが離されるまで待つ。 Return ' ' -------------------------------------- ' * キーが離されるまで待つサブルーチン * ' -------------------------------------- ' Keyoff: Gosub Keyport 'キー接続ポートからデータを入力。 If Keydata <> 0 Then Goto Keyoff 'If キーが離されたか? Else Waitms 100 Return ' ' ------------------------------------------------------------- (Tempi1 = 4桁のバイナリ値) ' * 4桁バイナリ値を[100の位]と[10と1の位]に分けるサブルーチン * (Tempw1 = 100の位を保管) ' ------------------------------------------------------------- (Temp8 = 1位のセグメントコード) ' (Temp9 = 10位のセグメントコード) Partbin: Tempw1 = Tempi1 / 100 '100の位を抽出する。(Tempw1) Tempw2 = Tempw1 * 100 '10と1の位を抽出する。(Tempw2) Tempw2 = Tempi1 - Tempw2 Temp1 = Tempw2 Gosub Binseg '10と1の位を2桁のセグメントコードに変換する。 Return ' ' --------------------------------------------- ' * バイナリ値を2桁のセグメントコードに変換し * (Temp1 = バイナリ・データ) ' * LEDに表示するサブルーチン * (Temp2 = 1: LEDの左2桁へ表示 , 0: LEDの右2桁へ表示) ' --------------------------------------------- (Temp2 = 3: 左2桁へゼロサプレス表示 , 2: 右2桁へゼロサプレス表示) ' (Temp2 = b6-0: 小数点表示無し , b6-1: 下位桁に小数点表示する) Binsegwr: Gosub Binseg 'バイナリ値を2桁のセグメントコードに変換する。 ' If Temp2.1 = 1 Then 'If ゼロサプレス有りか? Then If Temp1 < 10 Then 'If バイナリ値が10未満か? Then Temp9 = Seg_blank '上位桁を消灯。 End If End If ' If Temp2.0 = 0 Then 'If LEDの右2桁を指定か? Then Segcode = Temp8 '下位桁を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 If Temp2.6 = 1 Then 'If 小数点表示有りか? Then Reset Segcodeh.5 '下位桁に小数点を表示。 End If Leddata1h = Segcodeh Leddata1l = Segcodel Segcode = Temp9 '上位桁を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata2h = Segcodeh Leddata2l = Segcodel Else 'LEDの左2桁の場合。 Segcode = Temp8 '下位桁を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 If Temp2.6 = 1 Then 'If 小数点表示有りか? Then Reset Segcodeh.5 '下位桁に小数点を表示。 End If Leddata3h = Segcodeh Leddata3l = Segcodel Segcode = Temp9 '上位桁を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata4h = Segcodeh Leddata4l = Segcodel End If Return ' --------------------------------------- (Temp1 = バイナリ・データ) ' * バイナリ値を2桁のセグメントコードに * (Temp8 = 下位のセグメントコード) ' * 変換するサブルーチン * (Temp9 = 上位のセグメントコード) ' --------------------------------------- (Temp7 = 下位のBCD値) ' Binseg: Temp9 = Makebcd(temp1) 'バイナリ値を、BCD(Binary coded decimal)値に変換。 Temp7 = Temp9 And &H0F '下位のBCDコードを取得。 Temp8 = Lookup(temp7 , Segtab) '数値をセグメントコードへ変換する。 ' Temp9 = Temp9 And &HF0 '上位のBCDコードを取得。 Shift Temp9 , Right , 4 '下位へ移動する。 Temp9 = Lookup(temp9 , Segtab) '数値をセグメントコードへ変換する。 Return ' ' -------------------------------------------------------------------- (Segcode = セグメントのコード) ' * セグメントコードを[H]側と[L]側のポート用に振り分けるサブルーチン * (Segcodeh = 変換した[H]側のコード) ' -------------------------------------------------------------------- (Segcodel = 変換した[L]側のコード) ' Segdivide: Segcodeh = Segcode And &B1110_0000 '上位側の3bitを取り出す。 Shift Segcodeh , Right , 2 Segcodeh = Tempsegh Or Segcodeh 'セグメント[H]側に設定する値を作る。 Segcodel = Segcode And &B0001_1111 '下位側の5bitを取り出す。 Segcodel = Tempsegl Or Segcodel 'セグメント[L]側に設定する値を作る。 Return ' ' ------------------------------------------ ' * 時間 12/24時間制 識別表示 サブルーチン * (Temp1 = バイナリ・データ) ' ------------------------------------------ ' Hourcvwr: If Mf1224h = 1 Then 'If 24時間制か? Then Gosub Binsegwr '24時間制で表示する。 Else '12時間制表示。 Temp10 = Temp1 '24時間制時刻を12時間制に変換する。 If Temp1 = 0 Then Temp1 = 24 If Temp1 > 12 Then Temp1 = Temp1 - 12 Gosub Binsegwr 'バイナリ値を2桁のセグメントコードに変換してLED表示する。 Temp1 = Temp10 ' If Temp1 < 12 Then 'If AM or PM? Reset Leddata4l.3 '[AM] セグメントを点灯する。 Else Reset Leddata4l.1 '[PM] セグメントを点灯する。 End If End If Return ' ' -------------------------------------- ' * LEDの右2桁を消灯するサブルーチン * ' -------------------------------------- ' Ledoffright: Segcode = Seg_blank Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata1h = Segcodeh Leddata1l = Segcodel Leddata2h = Segcodeh Leddata2l = Segcodel Return ' ' -------------------------------------- ' * LEDの左2桁を消灯するサブルーチン * ' -------------------------------------- ' Ledoffleft: Segcode = Seg_blank Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata3h = Segcodeh Leddata3l = Segcodel Leddata4h = Segcodeh Leddata4l = Segcodel Return ' ' ********************************************************* ' * 32.768KHz 水晶較正用 16.384KHz出力 [PB3:17pin (MOSI)] * ' ********************************************************* ' Xtalcal: Segcode = Seg_x '4桁目に[X]を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata4h = Segcodeh Leddata4l = Segcodel Segcode = Seg_t '3桁目に[t]を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata3h = Segcodeh Leddata3l = Segcodel Segcode = Seg_c '2桁目に[c]を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata2h = Segcodeh Leddata2l = Segcodel Segcode = Seg_a '1桁目に[A]を表示する。 Gosub Segdivide 'セグメントコードを[H]側と[L]側のポートに振り分ける。 Leddata1h = Segcodeh Leddata1l = Segcodel ' Config Timer2 = Timer , Prescale = 1 , Async = On , Clear Timer = 1 , Compare A = Toggle Ocr2a = 0 Stop ' ' *************************************** ' * TIMER0 比較一致(A) 割り込みルーチン * ' *************************************** ' Tint0a: Select Case Dmano 'DMA表示番号により、桁ごとのLEDセグメントデータをセットする。 Case 1 : Led_segh = Leddata4h '4桁目のセグメントデータ[H]側をセットする。 Led_segl = Leddata4l '4桁目のセグメントデータ[L]側をセットする。 Reset Led_com1 'LED[C1]のコモン信号をオンにする。 Dmano = 2 Case 2 : Led_segh = Leddata3h '3桁目のセグメントデータ[H]側をセットする。 Led_segl = Leddata3l '3桁目のセグメントデータ[L]側をセットする。 Reset Led_com2 'LED[C2]のコモン信号をオンにする。 Dmano = 3 Case 3 : Led_segh = Leddata2h '2桁目のセグメントデータ[H]側をセットする。 Led_segl = Leddata2l '4桁目のセグメントデータ[L]側オンをセットする。 Reset Led_com3 'LED[C3]のコモン信号をオンにする。 Dmano = 4 Case 4 : Led_segh = Leddata1h '1桁目のセグメントデータ[H]側をセットする。 Led_segl = Leddata1l '1桁目のセグメントデータ[L]側をセットする。 Reset Led_com4 'LED[C4]のコモン信号をオンにする。 Dmano = 5 Case Else : Tintbflag = 1 'LEDのブランキング期間(温度のA/D変換期間用)フラグをセットする。 Dmano = 1 End Select Return ' ' *************************************** ' * TIMER0 比較一致(B) 割り込みルーチン * ' *************************************** ' Tint0b: Set Led_com1 '全ての桁のコモン信号をオフする。 Set Led_com2 Set Led_com3 Set Led_com4 Return ' ' End ' ' ************************************************* ' * 数値からLEDのセグメントコードへの変換テーブル * ' ************************************************* ' Segtab: Data &B1010_0000 '0 Data &B1011_1011 '1 Data &B1100_1000 '2 Data &B1000_1010 '3 Data &B1001_0011 '4 Data &B1000_0110 '5 Data &B1000_0100 '6 Data &B1010_1011 '7 Data &B1000_0000 '8 Data &B1000_0010 '9 ' ' ************************************ ' * 月ごとの最終日を取得するテーブル * ' ************************************ ' Monthtab: Data 0 , 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31