エディタ:
。1、 ()--- 概要のI2Cバス https://www.cnblogs.com/BitArt/archive/2013/05/27/3101037.html
2、(b)は---タイミングのI2Cバス https://www.cnblogs.com/BitArt/archive/2013/05/28/3103917.html
3、 理解する(3)--- C言語のI2CバスIIC https://www.cnblogs.com/BitArt/archive/2013/06/01/3112042.html
-
概要:
I²Cは、2線インタフェースである「目二乗CEE」または「眼二-CEE」と発音インター集積回路、の略語です。
I²C双方向しかし、2本のライン、1シリアル・データ・ライン(SDA)と、別のシリアルクロック(SCL)。
SCL:各EEPROMデバイスへのデータ入力の立ち上がりエッジ、EEPROMデバイスドライバは、出力データを立ち下がり。(エッジトリガ)
SDA:ODのドアのための双方向データ・ライン、および「ライン」の関係にODとOCゲート他の任意の数。
-
出力段
各内部デバイスバスI2C SDAは、SCLピンは同一の回路構成は、出力ピンと一緒に駆動される入力バッファです。入力バッファ相は高入力インピーダンスであると出力は、オープンドレインのFETであり、この回路は、2つの特性を有しています。
1)SDA、SCLオープンドレイン構造(OD)ので、プルアップ抵抗の大きしばしば1k8、4k7および10Kが、1k8最高のパフォーマンスを持っている必要があります。バスは、2アイドル状態のとき行が高いです。バス上のローレベル出力に接続された任意のデバイスは、バス信号は、すなわち、各デバイスのSDAとSCLラインが関係である、低くなるでしょう「と。」
2)ピン端子の出力信号レベルが検出されるが、出力は以前、「クロック同期」と「バス調停」ハードウェアベースと一致しているか否かを検出します。
-
マスターとスレーブデバイス
システム内のすべての周辺装置は、7ビットの「デバイス固有のコードからのアドレス」を有する、請求製造者によって開発されたデバイス4種類の高さは、ユーザによって定義されたデバイスのアドレスピンを定義下位3ビット。このように関係なく、多くのデバイスがバス上に存在するどのように、周辺機器のI2Cバスチップセレクト線を除去するアドレスコードによってマスタデバイス、マルチプロセッサ通信メカニズム、依然としてシステムの単純な配線構造。端末は、マスター端末を有効に同時に同じバス上で、メイン側とサブ側から、マスタがCPUを有する論理モジュールである必要があり、バスに取り付けられ、端部から数から端部が複数存在してもよいですアドレス空間と400pFのバスの最大容量の制限によって。
-
- マスタSCLラインのメインドライブ。
- デバイスからマスタ装置に応答して生成します。
両方がデータを送信することができるが、装置からの送信を開始することができず、送信は、マスタ装置によって制御されます。
4.率:
ノーマルモード:100kHzの。
高速モード:最大400kHz。
高速モード:最大3.4MHz。
高速SCLを使用する必要はありません、SCLはそれを忘れて、で、または100Kの下に残ります。
I2Cバス(B)---タイミング
プロトコル 1.アイドル状態 バスアイドル状態として定義される2本の信号線、一方、ハイレベルのバスI2CバスSDAとSCL。このとき、各ステージのFETデバイスの出力がOFFの状態、すなわち、バスがデアサートプルアップ抵抗器の各々の2本の信号線によって放出されています。 2.スタートとストップビットの定義:
- スタート信号:SCLがハイからSDAの低い遷移に、高い期間、活性化信号ではなく、信号レベルよりも、レベル遷移のタイミング信号です。
- 停止信号:SCLがハイの期間、ハイからローへのSDAの遷移、ストップ信号レベル遷移が、またタイミング信号ではなく、信号レベルです。
3.ACK
各送信機は、受信機からのフィードバック応答信号によってクロックパルス9中のデータラインを解放し、バイトを送信します。応答信号が高く、所定の非アクノリッジビット(NACK)、受信が一般表し、応答信号は、受信機が正常にバイトを受信したことを示し、低い、所定のビットに有効な応答(ACK肯定応答短いためのビット)でありますこのバイトは正常に受信されません。9番目のクロックの間の受信機がSDAラインをローにパルス、安定したクロックのローレベルの間ハイレベルを確保する前に、効果的なフィードバックACKビット要件のために低いです。受信機がマスターである場合には、後に、データ送信の送信端の彼を知らせるためにNACK信号を送信し、最後のバイトを受信し、マスタ受信機にSDAラインを解放停止信号を送信P.
無応答信号場合、バスを解放した後、SDAがハイレベルで継続しなければならないが、ローレベルにプルダウンされている部分に示す青い点線、受信した証明:図サンプリングロジックアナライザ以下の結果応答信号。 2)応答信号はSCLの立ち下がりエッジが終了するまで維持される;として前述赤ロゴ1)受信機は、SCLの立ち上がりエッジの到来前に低い期間中にSDAをプルする:これは、私たちの2つである内部情報を与えますその。
4.データの妥当性:
I2Cバスのデータ転送は、クロック信号がハイレベルであり、データラインは安定していなければならない、クロックラインの信号のみが専用データラインのハイ又はロー状態の間に低いです変更させました。 私は理解して:だけハイ期間中は安定を維持することが、ある前進を、持っているために、SCLの立ち上がりエッジの到着前のデータが原因の前に、準備する必要があります必要がI2Cバス()の概要---記事は、データが中SCL装置(EEPROM)の立ち上がりエッジに駆動され、指摘されています。
5.データ転送:
I2Cバス上のすべてのデータ転送は、すなわち、シリアルクロックSCLと協働して、SDAのビットのビット当たりのシリアルデータによってビットを対応するクロックパルス(または同期制御)を有しています。データビットのエッジトリガです。
第二に、作業プロセス
バス上のすべての通信は、マスターによって開始されています。通信では、マスタとスレーブは劇中で常に2つの異なる役割です。
デバイスにマスタ装置から送信された1データ
マスターは、他のスレーブが次の送信を無視しながら、開始バス上のすべてのデバイスの送信を通知するスタートビットは、ホストは、次のデバイスアドレスは、この転送プロセスを継続するスレーブのアドレスと一致して送信し送信しますそして次の送信のための待ち時間が開始されます。送信データの後に、マスタデバイスがデバイス宛から、それが読み取るまたは内部デバイスレジスタアドレスから書き込むように送信します。データが送信された後、送信停止ビット:
次のように書き込みプロセスは以下のとおりです。
スタートを送信
- EEPROM無回答または全く交渉があることを必要とする、成功したデータ伝送エラーがない場合、EEPROM受信に成功した場合、それが応答する、ダウン応答バスEEPROMまで、リリース・バス、デバイスアドレスと、リード/ライト選択ビットから送信されませんまたは再送信を終了します。
- 彼らの問題にEEPROM応答;あなたが書きたい内部レジスタのアドレスを送信します。
- データを送信します
- ストップビット。
- 停止信号を受信した後、EEPROMに10ms程度かかり書き込み期間の内側に行く、操作はここで任意の応答EEPROMではありません。(そのため、このように二回の書き込みの間の遅延を挿入する、または故障の原因となり、ブロガーは)一瞬のためにピットにここにいました
詳細:
注:①他のコントローラは、アドレスコードを受信している間にコントローラに対応するアドレスコードを送信することにより、バス上の通信を確立し、しかし、その独自のアドレスのマスタがありません一貫性のあるので、事前にマスターと通信終了。
2.マスターデータ読み出しプロセス:
より複雑なプロセスを読んで、かつての奴隷からデータを読み込むには、まずあなたが内部レジスタを読みたいので、(ダミーライト)書き込まれなければならない何かであることを教えなければなりません。
-
スタートビットが送信されます。
-
スレーブアドレス+書き込みビットセットを送信します。
-
内部レジスタのアドレスを送信します。
-
スタートビットを再送信、即ち、再起動。
-
再送スレーブアドレス+読み取りビットセット。
-
読み取りデータ
最後のバイトを受信した後、マスター受信機は、ACK信号が発行されていません。従って、スレーブはホストP.によって送信された送信信号の終了を可能にするために、SDAライントランスミッタを解放します
-
送信ストップビット
詳細:
IICを理解するためのI2Cバス(C)--- C言語
I2Cバスは、読み出し波形源側を見てC言語のシミュレーションIICバスの理解を深めるために:
書き込み動作のタイミングチャートに以下に示すように:
理解共感タイミング読みます。友人のために「を参照してタイミングを理解していない(2)---タイミングのI2Cバス」
完全なプログラムは次のよう:
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define write_ADD 0xa0
#define read_ADD 0xa1
uchar a;
sbit SDA=P2^0;
sbit SCL=P2^1;
void SomeNop(); //短延时
void init(); //初始化
void check_ACK(void);
void I2CStart(void);
void I2cStop(void);
void write_byte(uchar dat);//写字节
void delay(uint z);
uchar read_byte(); //读字节
void write(uchar addr,uchar dat); //指定地址写
uchar read(uchar addr); //指定地址读
bit flag; //应答标志位
void main()
{
init();
write_add(5,0xaa); //向地址5写入0xaa
delay(10); //延时,否则被坑呀!!!
P1=read_add(5); //读取地址5的值
while(1);
}
//***************************************************************************
void delay()//简单延时函数
{ ;; }
//***************************************************************************
void start() //开始信号 SCL在高电平期间,SDA一个下降沿则表示启动信号
{
sda=1; //释放SDA总线
delay();
scl=1;
delay();
sda=0;
delay();
}
//***************************************************************************
void stop() //停止 SCL在高电平期间,SDA一个上升沿则表示停止信号
{
sda=0;
delay();
scl=1;
delay();
sda=1;
delay();
}
//***************************************************************************
void respons() //应答 SCL在高电平期间,SDA被从设备拉为低电平表示应答
{
uchar i;
scl=1;
delay();
//至多等待250个CPU时钟周期
while((sda==1)&&(i<250))i++;
scl=0;
delay();
}
//***************************************************************************
void init()//总线初始化 将总线都拉高一释放总线 发送启动信号前,要先初始化总线。即总有检测到总线空闲才开始发送启动信号
{
sda=1;
delay();
scl=1;
delay();
}
//***************************************************************************
void write_byte(uchar date) //写一个字节
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
scl=0;//拉低SCL,因为只有在时钟信号为低电平期间按数据线上的高低电平状态才允许变化;并在此时和上一个循环的scl=1一起形成一个上升沿
delay();
sda=CY;
delay();
scl=1;//拉高SCL,此时SDA上的数据稳定
delay();
}
scl=0;//拉低SCL,为下次数据传输做好准备
delay();
sda=1;//释放SDA总线,接下来由从设备控制,比如从设备接收完数据后,在SCL为高时,拉低SDA作为应答信号
delay();
}
//***************************************************************************
uchar read_byte()//读一个字节
{
uchar i,k;
scl=0;
delay();
sda=1;
delay();
for(i=0;i<8;i++)
{
scl=1;//上升沿时,IIC设备将数据放在sda线上,并在高电平期间数据已经稳定,可以接收啦
delay();
k=(k<<1)|sda;
scl=0;//拉低SCL,使发送端可以把数据放在SDA上
delay();
}
return k;
}
//***************************************************************************
void write_add(uchar address,uchar date)//任意地址写一个字节
{
start();//启动
write_byte(0xa0);//发送从设备地址
respons();//等待从设备的响应
write_byte(address);//发出芯片内地址
respons();//等待从设备的响应
write_byte(date);//发送数据
respons();//等待从设备的响应
stop();//停止
}
//***************************************************************************
uchar read_add(uchar address)//读取一个字节
{
uchar date;
start();//启动
write_byte(0xa0);//发送发送从设备地址 写操作
respons();//等待从设备的响应
write_byte(address);//发送芯片内地址
respons();//等待从设备的响应
start();//启动
write_byte(0xa1);//发送发送从设备地址 读操作
respons();//等待从设备的响应
date=read_byte();//获取数据
stop();//停止
return date;//返回数据
}