目次
前
次
RTC(Real Time Clock)動作シミュレーション(AWK)
秋月電子で販売されているRTC(Real Time Clock)の動作が
どうなっているのかを理解するため、スクリプトを書いて
みました。
ターゲットのRTCは、以下。
マイコンで実現するには、1秒ごとの割込みをキャッチして
秒、分、時、日、月、年の順番で、+1の操作をし、ドミノ
倒しの要領で、より上位の値を変化させるかを判断すれば
できそうとわかりました。
秒、分、時は、60、60、24を境界条件にして、上位の
値を更新するか、否かを決定します。
この要領で、計算処理をまとめると、以下。
# second
clk_sec++
# judge
if ( clk_sec == 60 ) {
# clear
clk_sec = 0
# minute
clk_min++
}
# minute
if ( clk_min == 60 ) {
# clear
clk_min = 0
# hour
clk_hour++
}
# hour
if ( clk_hour == 24 ) {
# clear
clk_hour = 0
# increment
clk_day++
時が23から0に戻るとき、日、月、年の順番で、判定を入れないと
うまく結果がでないことになります。
月ごとに日が異なるため、場合分けをします。
# day
mode = 0
if ( month == 12 ) { mode = 1 }
if ( month == 2 ) { mode = 2 }
if ( month == 4 || month == 6 ) { mode = 3 }
if ( month == 9 || month == 11 ) { mode = 3 }
#
if ( mode == 0 ) {
if ( clk_day == 32 ) {
clk_day = 1 ;
month++ ;
}
}
if ( mode == 1 ) {
if ( clk_day == 32 ) {
clk_day = 1
month = 1
clk_year++
}
}
if ( mode == 2 ) {
if ( clk_day == 29 ) {
clk_day = 1
month++
}
}
if ( mode == 3 ) {
if ( clk_day == 31 ) {
clk_day = 1
month++
}
}
大の月、小の月で場合分けした後、2月と12月を
より分けています。閏年は、後で考えることにして
おきます。
2つのスクリプトを合体して、関数にします。
function update_rtc()
{
# set month
month = clk_month
# second
clk_sec++
# judge
if ( clk_sec == 60 ) {
# clear
clk_sec = 0
# minute
clk_min++
}
# minute
if ( clk_min == 60 ) {
# clear
clk_min = 0
# hour
clk_hour++
}
# hour
if ( clk_hour == 24 ) {
# clear
clk_hour = 0
# increment
clk_day++
# day
mode = 0
if ( month == 12 ) { mode = 1 }
if ( month == 2 ) { mode = 2 }
if ( month == 4 || month == 6 ) { mode = 3 }
if ( month == 9 || month == 11 ) { mode = 3 }
#
if ( mode == 0 ) {
if ( clk_day == 32 ) {
clk_day = 1 ;
month++ ;
}
}
if ( mode == 1 ) {
if ( clk_day == 32 ) {
clk_day = 1
month = 1
clk_year++
}
}
if ( mode == 2 ) {
if ( clk_day == 29 ) {
clk_day = 1
month++
}
}
if ( mode == 3 ) {
if ( clk_day == 31 ) {
clk_day = 1
month++
}
}
}
clk_month = month ;
}
関数を定義しただけなので、アクション部分を考え
フィールド値を、わかりやすい変数名で代入して
対応することにします。
アクション部分は、以下。
{
clk_year = $1
clk_month = $2
clk_day = $3
clk_hour = $4
clk_min = $5
clk_sec = $6
#
update_rtc()
# show
for ( i = 1 ; i < 7 ; i++ ) {
printf("%02d ",$i)
}
printf(" => ")
printf("%02d %02d %02d %02d %02d %02d\n",clk_year,clk_month,clk_day,clk_hour,clk_min,clk_sec)
}
2つを合体して、ひとつのAWKスクリプトにします。
function update_rtc()
{
# set month
month = clk_month
# second
clk_sec++
# judge
if ( clk_sec == 60 ) {
# clear
clk_sec = 0
# minute
clk_min++
}
# minute
if ( clk_min == 60 ) {
# clear
clk_min = 0
# hour
clk_hour++
}
# hour
if ( clk_hour == 24 ) {
# clear
clk_hour = 0
# increment
clk_day++
# day
mode = 0
if ( month == 12 ) { mode = 1 }
if ( month == 2 ) { mode = 2 }
if ( month == 4 || month == 6 ) { mode = 3 }
if ( month == 9 || month == 11 ) { mode = 3 }
#
if ( mode == 0 ) {
if ( clk_day == 32 ) {
clk_day = 1 ;
month++ ;
}
}
if ( mode == 1 ) {
if ( clk_day == 32 ) {
clk_day = 1
month = 1
clk_year++
}
}
if ( mode == 2 ) {
if ( clk_day == 29 ) {
clk_day = 1
month++
}
}
if ( mode == 3 ) {
if ( clk_day == 31 ) {
clk_day = 1
month++
}
}
}
clk_month = month ;
}
{
clk_year = $1
clk_month = $2
clk_day = $3
clk_hour = $4
clk_min = $5
clk_sec = $6
#
update_rtc()
# show
for ( i = 1 ; i < 7 ; i++ ) {
printf("%02d ",$i)
}
printf(" => ")
printf("%02d %02d %02d %02d %02d %02d\n",clk_year,clk_month,clk_day,clk_hour,clk_min,clk_sec)
}
テキストファイルには、境界を跨ぐようにデータを格納。
19 1 1 23 59 59
19 1 31 23 59 59
19 2 27 23 59 59
19 2 28 23 59 59
19 3 31 23 59 59
19 4 29 23 59 59
19 4 30 23 59 59
19 5 30 23 59 59
19 5 31 23 59 59
19 6 30 23 59 59
19 7 7 12 34 0
19 7 7 12 34 59
19 7 7 12 59 59
19 7 7 23 59 59
19 7 30 23 59 59
19 7 31 23 59 59
19 8 31 23 59 59
19 9 30 23 59 59
19 10 30 23 59 59
19 10 31 23 59 59
19 11 30 23 59 59
19 12 31 23 59 59
使うときは、テキストファイルとをスクリプトファイルを
用意して、端末上で結果を貰います。
I/Oリダイレクトを使えば、テキストファイルに落とし
後から、ゆっくりと検証することもできます。
19 01 01 23 59 59 => 19 01 02 00 00 00
19 01 31 23 59 59 => 19 02 01 00 00 00
19 02 27 23 59 59 => 19 02 28 00 00 00
19 02 28 23 59 59 => 19 03 01 00 00 00
19 03 31 23 59 59 => 19 04 01 00 00 00
19 04 29 23 59 59 => 19 04 30 00 00 00
19 04 30 23 59 59 => 19 05 01 00 00 00
19 05 30 23 59 59 => 19 05 31 00 00 00
19 05 31 23 59 59 => 19 06 01 00 00 00
19 06 30 23 59 59 => 19 07 01 00 00 00
19 07 07 12 34 00 => 19 07 07 12 34 01
19 07 07 12 34 59 => 19 07 07 12 35 00
19 07 07 12 59 59 => 19 07 07 13 00 00
19 07 07 23 59 59 => 19 07 08 00 00 00
19 07 30 23 59 59 => 19 07 31 00 00 00
19 07 31 23 59 59 => 19 08 01 00 00 00
19 08 31 23 59 59 => 19 09 01 00 00 00
19 09 30 23 59 59 => 19 10 01 00 00 00
19 10 30 23 59 59 => 19 10 31 00 00 00
19 10 31 23 59 59 => 19 11 01 00 00 00
19 11 30 23 59 59 => 19 12 01 00 00 00
19 12 31 23 59 59 => 20 01 01 00 00 00
スクリプトで、動作論理が理解できれば、回路に変換したり
ワンチップマイコンのファームウエアにするのは簡単。
西暦年が4で割り切れると、無条件でうるう年。
400で割り切れて、かつ100で割り切れるならば
うるう年となります。
これを西暦年から計算で求めます。
今回使ったRTCでは、下2桁だけを入れられる
ようにしてありました。上2桁を加えられる
なら、スクリプトのどこかに判定処理を入れ
対応します。
目次
前
次