PIC-BASICでリアルタイムクロック(RTC-8564NB)の時刻データを読み込み、ロギング時刻に使おうと考えた。PIC-BASICには、I2Cバスに接続されたEEPROMを読み書きする機能が実装されている。これを使えば簡単にRTC-8564のデータを読めるのではないかと考え試してみた。しかし、予期しないデータを持ってきてしまいうまく行かない。
良く考えるとEEPROMのアドレス指定は16bit、RTC-8564は8bitのため、アドレス転送シーケンスが一つ余計である。そのため、おかしな動作をしている模様。
諦めようかとも思ったが、BASICでI2C制御ルーチンを実装したところ動き出した。
しかし、これはBASICで実装するものではない。アセンブラを使うものです。
'/////////////////////////////////////////////////////////////
' RTC-8564NB テストプログラム
'
Dim rtcaddr As Byte
rtcaddr = &ha2
Dim sdata As Byte
progstart:
Initlcd
Gosub init
'//// 分データREAD ////
Gosub stCond
sdata = rtcaddr '送信データへスレーブアドレスセット
Gosub send
sdata = &h03 '分アドレス送信
Gosub send
Gosub restart '秒データread要求
sdata = rtcaddr | &h01 'アドレス+read bit
Gosub send
Gosub lastreceive
Putlcd Hex(rdata&&h7f)
Gosub stopseq
'//// 秒データREAD ////
Gosub stCond
sdata = rtcaddr '送信データへスレーブアドレスセット
Gosub send
sdata = &h02 '秒アドレス送信
Gosub send
Gosub restart '秒データread要求
sdata = rtcaddr | &h01 'アドレス+read bit
Gosub send
Gosub lastreceive
Putlcd Hex(rdata&&h7f)
Gosub stopseq
Sleep 1000
Goto progstart
End
'////////////////////////////////////////////////////////////
' I2C制御サブルーチン
'////////////////////////////////////////////////////////////
'//// I2C制御 初期設定 ////
'SSPCON1 14h
'SSPCON2 91h
'SSPADD 93h
'SSPSTAT 94h
'PIE1 8ch
'INTCON 0bh
init:
Poke &h14,&h28 'master, enable
Poke &h91,&h00 'SSPCON2 clear
Poke &h93, &h18 'SSPADD set 400Kbps
Poke &h94, &h00 'SSPSTAT clear
' Poke &h8c, Peek(&h8c)|&h04
' Poke &h0b, Peek(&h0b)|&hc0
Return
'//// start condition send ////
'SSPCON1 14h WCOL &h80
'SSPCON2 91h SEN &h01
stCond:
Poke &h14, Peek(&h14)&&h7f '衝突フラグクリア
Poke &h91, Peek(&h91)|&h01 'スタート出力
If Peek(&h14)&&h80 = &h80 Then stCond '衝突ならば再送
loop1:
If Peek(&h91)&&h01 = &h01 Then loop1 'スタート待ち
Return
'//// restart ////
'PIR1 0ch SSPIF &h08
'SSPCON2 91h RSEN &h02
restart:
Poke &h0c, Peek(&h0c)&&hf7 '割込みフラグクリア
Poke &h91, Peek(&h91)|&h02 '再スタート出力
loop2:
If Peek(&h91)&&h02 = &h02 Then loop2 '再スタート待ち
Return
'//// 1byte data send ////
'PIR1 0ch SSPIF &h08
'SSPBUF 13h メイン側でsdataへセット
'SSPCON2 91h ACKSTAT &h40
Dim ack As Byte '送信結果 error=&hff
send:
Poke &h0c, Peek(&h0c)&&hf7 '割込みフラグクリア
Poke &h13, sdata '送信データセット
loop3:
If Peek(&h0c)&&h08 = &h00 Then loop3 '送信完了確認
If Peek(&h91)&&h40 = &h40 Then
ack = &hff 'ack検出
Return
Else
ack = 0
Return
Endif
'//// data resive ////
'PIR1 0ch SSPIF &h08
'SSPCON2 91h RCEN &h08
'SSPCON2 91h ACKDT &h20
'SSPCON2 91h ACKEN &h10
'SSPBUF 13h 受信データ
Dim rdata As Byte
receive:
rdata = 0
Poke &h0c, Peek(&h0c)&&hf7 '割込みフラグクリア
Poke &h91, Peek(&h91)|&h08 '受信イネーブル
loop4:
If Peek(&h91)&&h08 = &h08 Then loop4 '受信完了待ち
Poke &h91, Peek(&h91)&&hbf 'ack set
Poke &h91, Peek(&h91)|&h10
loop5:
If Peek(&h91)&&h10 = &h10 Then loop5
rdata = Peek(&h13)
Return
'//// Last byte receive ////
'PIR1 0ch SSPIF &h08
'SSPCON2 91h RCEN &h08
'SSPCON2 91h ACKDT &h20
'SSPCON2 91h ACKEN &h10
'SSPBUF 13h 受信データ
lastreceive:
rdata = 0
Poke &h0c, Peek(&h0c)&&hf7 '割込みフラグクリア
Poke &h91, Peek(&h91)|&h08 '受信イネーブル
loop6:
If Peek(&h91)&&h08 = &h08 Then loop6 '受信完了待ち
Poke &h91, Peek(&h91)|&h20 'nack set
Poke &h91, Peek(&h91)|&h10
loop7:
If Peek(&h91)&&h10 = &h10 Then loop7
rdata = Peek(&h13)
Return
'//// Stop Sequence ////
'PIR1 0ch SSPIF &h08
'SSPCON2 91h PEN &h04
'
stopseq:
Poke &h0c, Peek(&h0c)&&hf7 '割込みフラグクリア
Poke &h91, Peek(&h91)|&h04 'stop出力
loop8:
If Peek(&h91)&&h04 = &h04 Then loop8
Poke &h0c, Peek(&h0c)&&hf7 '割込みフラグクリア
Return