' ' ************************************************** ' * * ' * RTC-8564 I2C デジタル時計 LCD表示プログラム * ' * * ' * AVR is using ATtiny2313 * ' * Basic Compiler is BASCOM-AVR * ' * Copyright By O-Family 2008. 5.10 * ' ************************************************** ' ' Ver 01.01 初回公開バージョン ' ' $regfile = "ATtiny2313.DAT" 'AVRデバイスを"ATtiny2313"に設定。 $crystal = 1000000 'クロック周波数を1MHzに設定。 ' ' Dim Timbuf(7) As Byte '時刻データバッファ。 Dim I2ccmd As Byte 'I2C 送信コマンド。 Dim Curpos 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 ' ' * ポートの割り当て * ' Porta = &H03 '未使用ポートをプルアップ。 Portb = &H03 Portd = &H4F ' Sw1 Alias Pind.0 'スイッチ1接続ポートピン。 Sw2 Alias Pind.1 'スイッチ2接続ポートピン。 ' Config Scl = Portd.4 'I2CバスのSCLラインを接続するポートピンを設定。 Config Sda = Portd.5 'I2CバスのSDAラインを接続するポートピンを設定。 ' Config Lcdmode = Port 'LCDを4ビットのポートモードに設定。 Config Lcdbus = 4 'LCDデータバスを4bitに設定。 Config Lcdpin = Pin , Db4 = Portb.5 , Db5 = Portb.4 'LCDのポート割り当て。 Config Lcdpin = Pin , Db6 = Portb.3 , Db7 = Portb.2 Config Lcdpin = Pin , E = Portb.6 , Rs = Portb.7 Config Lcd = 16 * 2 'LCD表示を16文字2行に設定。 ' ' * 初期設定 * ' Cursor Off 'LCDのカーソルをオフ。 Cls 'LCD表示をすべて消去。 ' Config I2cdelay = 1 'SCLクロック速度を設定。(BASCOMバグにより約25KHz) I2cinit 'I2CバスのSCL,SDAラインを初期化。 Config Int1 = Rising '外部割り込みピン INT1を立ち上りエッジにセット。 ' Wait 1 'RTC-8564起動待ち。 ' ' * RTC-8564の動作状態を確認 (バックアップ切れを確認) * ' I2cstart 'I2Cバスを、[スタート・コンディション]に設定。 I2cwbyte &HA2 'RTC-8564へ、I2Cアドレス+Writeを送信。 I2cwbyte &H02 'レジスタ[02]を選択。 I2cstart 'I2Cバスを、[再スタート]に設定。 I2cwbyte &HA3 'RTC-8564へ、I2Cアドレス+Readを送信。 I2crbyte Temp1 , Nack '[電圧低下(VL)]ビットを読み込み。 I2cstop 'I2Cバスを、[ストップ・コンディション]に設定。 'Waitus 2 '1.3μSの待ち時間。(AVRクロック速度により必要になります) If Temp1.7 = 1 Then Gosub Rtc8564init 'If RTC-8564の初期化が必要? Then ' Gosub Rtc8564start 'RTC-8564の時計機能を始動。(初期化中に中断した場合の対策) ' ' ******************** ' * メイン・ルーチン * ' ******************** ' Main: Gosub Timdisp '1秒毎に日時をLCDに表示。 Gosub Keyin 'キー入力処理。 Goto Main End ' ' *************************** ' * 1秒毎に日時をLCDに表示 * ' *************************** ' Timdisp: If Eifr.intf1 = 0 Then Return 'If 1秒経過? Else Set Eifr.intf1 'INT1フラグをリセット。 ' Gosub Rtcread 'RTC-8564から、日時データを取り出す。 ' Timdisps: Locate 1 , 2 Lcd "20" ; Hex(timbuf(1)); '[年]を表示。 Lcd "/" ; Hex(timbuf(2)); '[月]を表示。 Lcd "/" ; Hex(timbuf(3)); '[日]を表示。 Lcd " " ; Lookupstr(timbuf(4) , Weekdata) '[曜日]を表示。 Locate 2 , 4 Lcd Hex(timbuf(5)); '[時]を表示。 Lcd ":" ; Hex(timbuf(6)); '[分]を表示。 Lcd ":" ; Hex(timbuf(7)) '[秒]を表示。 Return ' ' * 曜日 データ・テーブル * ' Weekdata: Data "SUN" , "MON" , "TUE" , "WED" , "THU" , "FRI" , "SAT" ' ' **************** ' * キー入力処理 * ' **************** ' Keyin: Temp2 = Sw1 Or Sw2 If Temp2 = 1 Then Return 'If スイッチ1と2が同時に押されたか? Else ' Gosub Rtc8564stop 'RTC-8564の時計機能を停止させる。 Curpos = 0 Gosub Curmov 'カーソル位置を移動させる。 Cursor On , Blink 'LCDのカーソルをオン。 Bitwait Sw1 , Set 'スイッチ1が離されるまで待つ。 Bitwait Sw2 , Set 'スイッチ2が離されるまで待つ。 ' Keyin1: Debounce Sw1 , 0 , Keyin2 'If スイッチ1が押されたか? Then Debounce Sw2 , 0 , Keyin3 'If スイッチ2が押されたか? Then Goto Keyin1 ' ' Keyin2: 'スイッチ1が押された。 Curpos = Curpos + 1 'カーソルを次の位置へ。 If Curpos > 6 Then Curpos = 0 'If カーソル位置を戻す? Then Keyin4: Gosub Curmov 'カーソル位置を移動させる。 Bitwait Sw1 , Set 'スイッチ1が離されるまで待つ。 Goto Keyin1 ' ' Keyin3: 'スイッチ2が押された。 If Curpos = 6 Then Goto Keyin5 'If [秒]の位置で押された(設定終了)? Then ' Temp2 = 1 Temp1 = 12 If Curpos = 1 Then Goto Keyin6 'If [月]データ修正? Then Temp1 = 31 If Curpos = 2 Then Goto Keyin6 'If [日]データ修正? Then Temp2 = 0 If Curpos = 0 Then Temp1 = 99 'If [年]データ修正? Then If Curpos = 3 Then Temp1 = 6 'If [曜日]データ修正? Then If Curpos = 4 Then Temp1 = 23 'If [時]データ修正? Then If Curpos = 5 Then Temp1 = 59 'If [分]データ修正? Then ' Keyin6: 'BCD値を+1。 Temp3 = Curpos + 1 Temp4 = Makedec(timbuf(temp3)) 'BCDを10進数の数値に変換。 Temp4 = Temp4 + 1 If Temp4 > Temp1 Then Temp4 = Temp2 'If 上限値 ? Then Timbuf(temp3) = Makebcd(temp4) '10進数の数値をBCD値に変換。 ' Gosub Timdisps '日時をLCDに表示。 Bitwait Sw2 , Set 'スイッチ2が離されるまで待つ。 Goto Keyin4 ' ' Keyin5: '秒の位置で押された(設定終了)。 Cursor Off , Noblink 'LCDのカーソルをオフ。 Timbuf(7) = 0 '[秒]を00にリセット。 ' 'RTC-8564へ、日時データを書き込む。 I2cstart 'I2Cバスを、[スタート・コンディション]に設定。 I2cwbyte &HA2 'RTC-8564へ、I2Cアドレス+Writeを送信。 I2cwbyte &H02 'レジスタ[02]を選択。 I2cwbyte Timbuf(7) '[秒]データを書き込み。 I2cwbyte Timbuf(6) '[分]データを書き込み。 I2cwbyte Timbuf(5) '[時]データを書き込み。 I2cwbyte Timbuf(3) '[日]データを書き込み。 I2cwbyte Timbuf(4) '[曜日]データを書き込み。 I2cwbyte Timbuf(2) '[月]データを書き込み。 I2cwbyte Timbuf(1) '[年]データを書き込み。 I2cstop 'I2Cバスを、[ストップ・コンディション]に設定。 'Waitus 2 '1.3μSの待ち時間。(AVRクロック速度により必要になります) ' Gosub Rtc8564start 'RTC-8564の時計機能を始動。 Return ' ' * カーソルを移動させるサブルーチン * ' Curmov: Temp1 = Lookup(curpos , Cutaby) 'カーソル位置をテーブルから決定する。 Temp2 = Lookup(curpos , Cutabx) Locate Temp1 , Temp2 '新しいカーソル位置へ移動。 Return ' ' * LCDのカーソル位置テーブル * ' Cutaby: Data 1 , 1 , 1 , 1 , 2 , 2 , 2 Cutabx: Data 4 , 7 , 10 , 13 , 4 , 7 , 10 ' ' *************************************************** ' * RTC-8564から、日時データを取り出す サブルーチン * ' *************************************************** ' Rtcread: I2cstart 'I2Cバスを、[スタート・コンディション]に設定。 I2cwbyte &HA2 'RTC-8564へ、I2Cアドレス+Writeを送信。 I2cwbyte &H02 'レジスタ[02]を選択。 I2cstart 'I2Cバスを、[再スタート]に設定。 I2cwbyte &HA3 'RTC-8564へ、I2Cアドレス+Readを送信。 I2crbyte Temp1 , Ack '[秒]データを読み込み。 Timbuf(7) = Temp1 And &H7F I2crbyte Temp1 , Ack '[分]データを読み込み。 Timbuf(6) = Temp1 And &H7F I2crbyte Temp1 , Ack '[時]データを読み込み。 Timbuf(5) = Temp1 And &H3F I2crbyte Temp1 , Ack '[日]データを読み込み。 Timbuf(3) = Temp1 And &H3F I2crbyte Temp1 , Ack '[曜日]データを読み込み。 Timbuf(4) = Temp1 And &H07 I2crbyte Temp1 , Ack '[月]データを読み込み。 Timbuf(2) = Temp1 And &H1F I2crbyte Timbuf(1) , Nack '[年]データを読み込み。 I2cstop 'I2Cバスを、[ストップ・コンディション]に設定。 'Waitus 2 '1.3μSの待ち時間。(AVRクロック速度により必要になります) Return ' ' *********************************************** ' * RTC-8564の時計機能を停止させる サブルーチン * ' *********************************************** ' Rtc8564stop: I2ccmd = &B00100000 '時計機能 停止コマンド。 Rtc8564stp1: I2cstart 'I2Cバスを、[スタート・コンディション]に設定。 I2cwbyte &HA2 'RTC-8564へ、I2Cアドレス+Writeを送信。 I2cwbyte &H00 'レジスタ[00]を選択。 I2cwbyte I2ccmd '時計機能コマンドを送信。 I2cstop 'I2Cバスを、[ストップ・コンディション]に設定。 'Waitus 2 '1.3μSの待ち時間。(AVRクロック速度により必要になります) Return ' ' *********************************************** ' * RTC-8564の時計機能を始動させる サブルーチン * ' *********************************************** ' Rtc8564start: I2ccmd = &B00000000 '時計機能 始動コマンド。 Goto Rtc8564stp1 ' ' *********************************************** ' * RTC-8564を初期化 サブルーチン * ' *********************************************** ' Rtc8564init: Gosub Rtc8564stop 'RTC-8564の時計機能を停止させる。 ' Restore Rtc8564dtt 'RTC-8564へ初期設定データを送信。 I2cstart 'I2Cバスを、[スタート・コンディション]に設定。 I2cwbyte &HA2 'RTC-8564へ、I2Cアドレス+Writeを送信。 I2cwbyte &H00 'レジスタ[00]を選択。 For Temp1 = 0 To 15 '16バイトを送信。 Read Temp2 I2cwbyte Temp2 '設定データを送信。 Next Temp1 I2cstop 'I2Cバスを、[ストップ・コンディション]に設定。 'Waitus 2 '1.3μSの待ち時間。(AVRクロック速度により必要になります) Return ' ' * RTC-8564 初期設定 データ・テーブル * ' Rtc8564dtt: Data &B00100000 '[00] Control 1 Data &B00000000 '[01] Control 2 Data &H00 '[02] Seconds Data &H00 '[03] Minutes Data &H00 '[04] Hours Data &H01 '[05] Days Data &H00 '[06] Weekdays Data &H01 '[07] Months / Century Data &H00 '[08] Years Data &H00 '[09] Minute Alarm Data &H00 '[0A] Hour Alarm Data &H00 '[0B] Day Alarm Data &H00 '[0C] Weekday Alarm Data &B10000011 '[0D] CLKOUT frequency Data &B00000000 '[0E] Timer control Data &H00 '[0F] Timer