mirror of
https://github.com/rvtr/ctr_mcu.git
synced 2025-06-18 16:45:33 -04:00
170 lines
4.0 KiB
C
170 lines
4.0 KiB
C
/* ========================================================
|
||
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出力なし */
|
||
|
||
HOUR = 0x00;
|
||
MIN = 0x00;
|
||
SEC = 0x00;
|
||
MONTH = 0x01;
|
||
DAY = 0x01;
|
||
WEEK = 0x01; // Mon
|
||
YEAR = 0x01;
|
||
|
||
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 = false;
|
||
rtc_dirty = false;
|
||
rtc_alarm_dirty = false;
|
||
}
|
||
|
||
|
||
|
||
/* ========================================================
|
||
RTC アラーム割り込み
|
||
======================================================== */
|
||
__interrupt void int_rtc( )
|
||
{
|
||
RWAIT = 1;
|
||
while( !RWST )
|
||
{;}
|
||
// 日付も指定日で
|
||
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 ) )
|
||
{
|
||
set_irq( VREG_C_IRQ1, REG_BIT_RTC_ALARM );
|
||
}
|
||
RWAIT = 0;
|
||
}
|
||
|
||
|
||
|
||
/* ========================================================
|
||
RTC のリード
|
||
レジスタは、sec,min,hour,week,day,month,year の順
|
||
======================================================== */
|
||
void rtc_buf_reflesh( )
|
||
{
|
||
if( !rtc_lock )
|
||
{
|
||
rtc_lock = true;
|
||
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 )
|
||
{
|
||
rtc_dirty = true;
|
||
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( )
|
||
{
|
||
// リードロック
|
||
rtc_lock = false;
|
||
|
||
// ライトロック
|
||
if( rtc_dirty )
|
||
{
|
||
rtc_dirty = false;
|
||
RWAIT = 1;
|
||
while( !RWST )
|
||
{;}
|
||
memcpy( &SEC, rtc_work, 7 );
|
||
RWAIT = 0;
|
||
}
|
||
|
||
// アラームセット
|
||
if( rtc_alarm_dirty )
|
||
{
|
||
rtc_alarm_dirty = false;
|
||
WALE = 0;
|
||
ALARMWM = vreg_ctr[VREG_C_RTC_ALARM_MIN];
|
||
ALARMWH = vreg_ctr[VREG_C_RTC_ALARM_HOUR];
|
||
WALE = 1;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/* ========================================================
|
||
RTC システムチックタイマ割り込みベクタ
|
||
2^6/fXT(1.953125 ms)
|
||
======================================================== */
|
||
__interrupt void int_rtc_int( )
|
||
{
|
||
renge_flg_interval += 1; // インクリメント/デクリメント命令を使うので DI()不要
|
||
}
|