Stingray's ブログ

米作りと趣味の電子工作

PIC-BASICでI2C制御

2007-02-03 20:31:57 | 電子工作

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


コメント    この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« LPIC-3 | トップ | PIC-BASICでI2C制御 »
最新の画像もっと見る

コメントを投稿

ブログ作成者から承認されるまでコメントは反映されません。

電子工作」カテゴリの最新記事