アナログGPIO IIC s5pc100付き
、IICバスの紹介
PHILIPS社によって開発されたIIC(IICも呼ばれる集積回路間)バス、マイクロコントローラと、以下の特性を有し、その周辺機器を接続するために、シリアルバスです。
(1)2つだけバスライン:シリアルデータ線(SDA)、シリアルクロックライン(SCL)
(2)バスに接続されたデバイスのそれぞれは、識別するための固有のアドレスに応じてソフトウェアを使用することができ
装置間(3)データの送信は、単純なマスタ/スレーブ関係であります
ホストまたはホストは、ホスト受信機を送信するように(4)を使用することができます
(5)これは、真のマルチマスタバスである、二つ以上のホストがデータ破壊が衝突検出および調停によって防止することができ、同時にデータ送信を開始します
400kbit / sの高速モードにおける3.4Mbit /秒まで高速モードで最大100kbit / sの標準モード(6)8ビットの双方向シリアルデータ転送、ビットレートアップ
注:ホストがバスの制御を取得するためにホストによってのみ製造することができるバス調停の複数を制御しようとする場合、それは情報を送信し、破壊されません
第二に、信号タイプIICバス
3種類のIICバスの信号は、データ転送中にあります。信号、応答信号およびエンド信号を開始します
(1)信号(S)を開始:SCLはSDAがデータ転送を開始するために、ハイからローに遷移する、高いです
(2)終了信号(P):SCLは、データ転送の終了、HIGH遷移に、SDAのLOW高いです
(3)応答信号(ACK)9クロックサイクルで、8ビットのデータを受信した後、受信機は、SDAのレベルを引き下げます
注意:SDA上のデータ伝送が高い期間SCLの間に安定している必要があり、SCL上のSDAデータのみを中に低く、
三、IICバスのデータ転送フォーマット
SDAラインに送られる各バイトは8ビットである必要があり、転送ごとに送信することができるバイトの数は限定されません。最初の送信は、最上位ビット(MSB)です。
送信を開始する場合、ホストは最初の信号Sを送信する、8ビットのデータは、送信されます。送信前に、この8ビットのデータが7つのスレーブアドレス、ビット8つの方向である(0が書き込み動作を示し、読み出し動作が1を示します)。スレーブが送信されます場合はACK信号が受信されます。
注意:最後のバイトを受信した後、マスター受信機がACK信号ではありません。従って、スレーブはホストP.によって送信された送信信号の終了を可能にするために、SDAライントランスミッタを解放します
アナログGPIOと第三に、IICバスタイミング
以前導入することにより、我々はすでにIICバスを知っています。以下は、私たちは、LM75が安定しているセンサによって測定された温度を読み取るためにIICバスタイミングをシミュレートするために2本のピンを使用します。
のは、LM75ハードウェアの接続を見てみましょう:
データラインは、図3に示すように、それぞれ、GPD3のs5pc100とGPD4に接続されているI2C_SDA0、I2C_SCL0クロックライン、です。
シミュレーションIIC、GPD3送信データまたはデータピンを読んだとき、GPD4ピンにクロック信号を提供します。
ピンGPDのs5pc100のこのグループ多くの理由ではなく、個別動作の各ピンの前記ピンの対を分離するために前記別の操作、ここで、C言語のビットフィールドの使用。
構造体のtypedef
{
UINT8 GPDDAT_0:1;
UINT8 GPDDAT_1:1;
UINT8 GPDDAT_2:1;
UINT8 GPDDAT_3:1;
UINT8 GPDDAT_4:1;
UINT8 GPDDAT_5:1;
UINT8 GPDDAT_6:1;
UINT8 GPDDAT_7:1;
} gpddat_t。
#define GPD_DAT(*(揮発性gpddat_t *)0xE0300084)
#define SDA GPD_DAT.GPDDAT_3
#定義SCL GPD_DAT.GPDDAT_4
(1)スタート信号IICを生成します
SCLが高く、SDAは、データ転送を開始するためにハイからローに遷移します
/ * IIC開始:SCL = 1、SDA = 1-> 0 * /
iic_startを無効()
{
SDA = HIGH;
SCL = HIGH;
delay(50);
//高到低的跳变产生start信号
SDA = LOW;
delay(50);
//在SCL高时,SDA必须保持稳定,SCL低时,SDA可以任意改变
//此处将SCL拉低的目的是,接下来就要发送数据了
SCL = LOW;
delay(50);
return;
}
(2)产生IIC停止信号
SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据
/*IIC STOP:SCL = 1,SDA = 0->1*/
void iic_stop()
{
SDA = LOW;
SCL = LOW;
delay(50);
SCL = HIGH;
delay(50);
//SCL为高电平时,SDA从低电平跳变到高电平,产生停止信号
SDA = HIGH;
delay(50);
return;
}
(3)发送数据
/*Write 1 Byte to IIC*/
void iic_write_byte(uint8 data)
{
uint8 loop;
for(loop = 8;loop > 0;loop --)
{
//先发送最高位,在SCL高电平时,SDA必须保持稳定
SDA = data >> 7;
SCL = HIGH;
delay(50);
//SCL为低电平时,SDA可以任意改变
SCL = LOW;
//低位向高位移动
data <<= 1;
delay(50);
}
return;
}
(4)读取数据
/*Read 1 byte from IIC*/
uint8 iic_read_byte()
{
uint8 loop;
uint8 value = 0;
for(loop = 8; loop > 0;loop --)
{
SCL = HIGH;
delay(50);
value <<= 1;
//读取1位数据
value |= SDA;
SCL = LOW;
delay(50);
}
return value;
}
(5)主机向从机发送ACK信号
void iic_send_ack()
{
SCL = HIGH;
SDA = LOW;
delay(50);
SCL = LOW;
delay(50);
return;
}
(6)获取从机给主机的ACK信号
uint8 iic_get_ack()
{
uint8 ret;
SCL = HIGH;
delay(50);
ret = SDA;
SCL = LOW;
delay(50);
return ret;
}
四、读取LM75测量的温度值
通过IIC读取LM75测量温度值的时序如下:
实例代码如下:
unsigned int __read_lm75()
{
uint8 ack;
uint8 high,low;
//设置IIC连接的pin为输出模式
SET_GPIO_MODE(GPD.GPDCON,3,1);
SET_GPIO_MODE(GPD.GPDCON,4,1);
delay(100);
//产生起始信号
iic_start();
//发送从机地址
iic_write_byte(0x91);
//设置IIC连接的pin(SDA)为输入模式
SET_GPIO_MODE(GPD.GPDCON,3,0);
//等待从机的ACK
do{
ack = iic_get_ack();
}while(ack);
//读取从机发送过来的数据
high = iic_read_byte();
//设置IIC连接的pin(SDA)为输出模式
SET_GPIO_MODE(GPD.GPDCON,3,1);
//发送ACK信号
iic_send_ack();
//设置IIC连接的pin(SDA)为输入模式
SET_GPIO_MODE(GPD.GPDCON,3,0);
//读取从机发送过来的数据
low = iic_read_byte();
//设置IIC连接的pin(SDA)为输出模式
SET_GPIO_MODE(GPD.GPDCON,3,1);
//发送停止信号
iic_stop();
return (high << 8) | low;
}
实验的经验:
1.读不到从机发送的ACK信号,原因是没有将SDA的那根线设为输入模式
2.在做的过程中,一开始每次读取的时候温度的值一直没有改变,后来发现是由于每次没有发送停止信号产生的。