/* ======================================================== RTC ======================================================== */ #pragma sfr #pragma inline #include "incs.h" // ======================================================== u8 rtc_work[7]; bit rtc_lock; bit rtc_dirty; bit rtc_alarm_dirty; /* ======================================================== ペリフェラルの初期化 レジスタの電池交換ビットのセット ======================================================== */ void RTC_init( void ) { if( !RTCEN ) // ビットが立っていたらリブート { RTCEN = 1; // モジュールON // RTC設定 RTCC0 = 0b00001000; /* 動作停止、24時間制、32k出力「まだなし」、定周期割り込みなし */ RTCC1 = 0b11000000; /* アラーム割り込み有効&動作開始 */ RTCC2 = 0b10000000; /* インターバル:32k/2^6=2ms、RTCDIV出力なし */ SEC = 0x00; MIN = 0x00; HOUR = 0x15; DAY = 0x01; WEEK = 0x00; MONTH = 0x11; YEAR = 0x09; ALARMWW = 0x7F; vreg_ctr[VREG_C_MCU_STATUS] |= REG_BIT_RTC_BLACKOUT; } // 割り込み設定 RTCIF = 0; RTCIIF = 0; RTCMK = 1; /* 割り込み(定周期)禁止 */ RTCIMK = 0; /* 割り込み(アラーム&インターバル)許可 */ RTCE = 1; /* 動作開始 */ RWAIT = 1; while( !RWST ) {; } RWAIT = 0; rtc_lock = 0; rtc_dirty = 0; rtc_alarm_dirty = 0; } /* ======================================================== RTC アラーム割り込み 2^6/fXT(1.953125 ms) ======================================================== */ __interrupt void int_rtc( ) { // 日付も指定日で if( ( vreg_ctr[VREG_C_RTC_ALARM_DAY] == DAY ) && ( vreg_ctr[VREG_C_RTC_ALARM_MONTH] == MONTH ) && ( vreg_ctr[VREG_C_RTC_ALARM_YEAR] == YEAR ) ) { if( ( vreg_ctr[VREG_C_IRQ_MASK1] & REG_BIT_RTC_ALARM ) == 0 ) { vreg_ctr[VREG_C_IRQ1] |= REG_BIT_RTC_ALARM; IRQ0_ast; // マスクをしてあったら、電源を入れません if(( system_status.pwr_state == BT_CHARGE ) || ( system_status.pwr_state == OFF )) { system_status.poweron_reason = RTC_ALARM; } } } } /* ======================================================== RTC のリード レジスタは、sec,min,hour,week,day,month,year の順 ======================================================== */ void rtc_buf_reflesh( ) { if( rtc_lock == 0 ) { rtc_lock = 1; RWAIT = 1; while( !RWST ) {; } memcpy( &vreg_ctr[VREG_C_RTC_SEC], &SEC, 7 ); RWAIT = 0; // renge_task_immed_add( tski_rtc_close ); } } /* ======================================================== RTC のライト set_rtc_close と対で使って下さい。 こいつはバッファにコピーするだけで、 実際にRTCにセットするのはset_rtc_close()です。 ======================================================== */ void set_rtc( u8 adrs, u8 data ) { if( rtc_dirty == 0 ) { rtc_dirty = 1; memcpy( rtc_work, &SEC, 7 ); // renge_task_immed_add( tski_rtc_close ); // I2C終了時に行う } rtc_work[adrs] = data; } /* ======================================================== 必要ならば、RTCレジスタの更新 ======================================================== */ // task_status_immed tski_rtc_close(){ void rtc_unlock( ) { // リードロック // if( rtc_lock != 0 ){ rtc_lock = 0; // } // ライトロック if( rtc_dirty != 0 ) { rtc_dirty = 0; RWAIT = 1; while( !RWST ) {; } memcpy( &SEC, rtc_work, 7 ); RWAIT = 0; } // アラームセット if( rtc_alarm_dirty ) { WALE = 0; ALARMWM = vreg_ctr[VREG_C_RTC_ALARM_MIN]; ALARMWH = vreg_ctr[VREG_C_RTC_ALARM_HOUR]; rtc_dirty = 0; WALE = 1; } } /* ======================================================== RTC システムチックタイマ割り込みベクタ 2^6/fXT(1.953125 ms) ======================================================== */ __interrupt void int_rtc_int( ) { renge_flg_interval = 1; }