おはようございます。
としぶぅ~です。
なんか眠たいです。。。。休みはちゃんと寝たはずなんですが。。。。
春!。。。。ということでしょうか(笑)
さて今日は、プログラムを少しさわってタイミングを調整しました。
プログラムは大分すっきりしましたかね。。。
一応リスト載せときます。(あまり参考にならないかもしれませんが・・・・)
#include
#include "delay.h"
void I2C_DELAY();
void I2C_DELAY_DT();
void i2c_stop();
//i2cの初期化
void i2cinit(unsigned char i2cmode)
{
/*************************************************
SPIモード
spimode = 0000 :spi-master-mode OSC/4
spimode = 0001 :spi-master-mode OSC/16
spimode = 0010 :spi-master-mode OSC/64
spimode = 0011 :spi-master-mode TMR2 output/2
spimode = 0010 :spi-slave-mode SSpin Disable
spimode = 0010 :spi-slave-mode SSpin Enable
**************************************************/
unsigned char i2cmode0;
i2cmode0=(SSPCON & 0xf0) | i2cmode;
SSPCON=i2cmode0;
// SSPM=i2cmode; //I2Cモードの設定
CKP=1; //送信up-受信down
SMP=0; //I2C mode:clear
CKE=0; //I2C mode:clear
D_nA=0; //I2C mode:(0:ADDRESS/1:DATA)
R_nW=0; //I2C mode:(0:write/1:read)
P=0; //I2C mode:STOP bit(0:not detected/1:detect)
S=0; //I2C mode:START bit(0:not detected/1:detect)
TRISB4=0; //RB4/SDA:output select
TRISB6=0; //RB1/SCL:output select
//initialize Start bit
RB4=1; //RB4/SDA
RB6=1; //RB1/SCL
SSPEN=1; //SPI port enable
SSPIE=1; //SSP Interrupt enable
SSPIF=0; //SSP Interrupt status
}
//I2C start bit output
void i2c_start()
{
TRISB4=1; //RB4/SDA _|
DelayUs(5);
TRISB6=1; //RB1/SCL _|
DelayUs(5);
TRISB4=0; //RB4/SDA |_
DelayUs(5);
TRISB6=0; //RB1/SCL |_
DelayUs(5);
}
//I2C stop bit output
void i2c_stop()
{
TRISB6=0; //RB4/SDA _|
DelayUs(5);
TRISB6=0; //RB1/SCL _|
DelayUs(5);
TRISB6=1; //RB4/SDA |_
DelayUs(5);
TRISB4=1; //RB1/SCL |_
DelayUs(5);
}
//I2C data 1バイト送信
void i2c_8bit_out(unsigned char out_data)
{
unsigned char dtcnt,point;
unsigned char data;
unsigned char outdata;
outdata=out_data;
point=0x80;
data=0;
dtcnt=8;
while(dtcnt!=0)
{
dtcnt--;
if(outdata & point){
data=1;
}else data=0;
point=point >> 1;
//bit7
TRISB4=data; //RB4/SDA **
DelayUs(5);
//CLOCK
TRISB6=1; //RB1/SCL _|
DelayUs(10);
TRISB6=0; //RB1/SCL |_
DelayUs(5);
}
//ACC CLOCK
DelayUs(20);
TRISB6=1; //RB1/SCL _|
DelayUs(10);
TRISB6=0; //RB1/SCL |_
DelayUs(5);
}
上記で作った関数をmain()に組み込みます
//I2Cモードイニシャライズ
i2cinit(i2cmode);
i2c_start();
i2c_8bit_out(0x70);
while(!I2C_ACK){I2C_ACK=0;}
i2c_8bit_out(1);
i2c_stop();
こんな感じですかね。。。
まず
①イニシャライズ
②スタートビット出力
③アドレス出力
④アクノレッジ信号待ち(割り込み)
⑤データ出力
⑥ストップビット出力
こんな手順です。
上記プログラムを使うことで、周波数は50KHzくらいになりました。。。
100KHzでもできますが(一応動いてました)。。。。なんせシーケンスで”H"”L"出力しているので。。。大変!
ということで50KHzで通信するようにします。
波形は下記
上記プログラムを実行すると下記ののように波形が出力されます。
上がデータ(SDA)、下がクロック(SCL)
周波数は50KHz
上がデータ(SDA)、下がクロック(SCL)
”H"パルス幅は、5.6uS
上がデータ(SDA)、下がクロック(SCL)
動作的には問題ないかな・・・・
ちなみにPICのマスタークロックは外部のセラロック20MHzを使用しています。
さて、タイミングの調整はこの辺でいいかなと思いますので。。。
明日からはLCD用の関数に、I2C通信を埋め込んでいこうと思います。
。。。。順調に行けばいいですが。。。。うまくいかないほうが楽しめる?(笑)
さあきょうはこの辺にしておきます。
それでは今日も一日よい一日を~(^o^)/