STM32 I2C 通信プロトコル + CubeMx 構成

コンセプト

2線シリアルバス。データラインSDAクロックSCLで構成されるシリアルバスはデータの送受信が可能です。半二重通信) CPUと制御対象IC間、およびICとIC間で双方向通信を行い、一般に400kbps以上の高速IICバスを実現します。

I2Cプロトコル

アイドル状態

I2C バスの2 本の信号線 SDA と SCLが同時にハイレベルになると、バスのアイドル状態と定義されますこのとき、各デバイスの出力段電界効果トランジスタはカットオフ状態、つまりバスが解放され、2本の信号線のプルアップ抵抗によりレベルがプルアップされています。

スタート信号とストップ信号

  • スタート信号: SCL が HighのときSDA はHigh から Low にジャンプします。スタート信号はレベル信号ではなく、レベルジャンプのタイミング信号です。
  • ストップ信号: SCL が Highの場合SDA はLow から High にジャンプします。ストップ信号もレベル信号ではなく、レベル ジャンプ タイミング信号です。
    I2C の図

一般的なスタート信号とストップ信号を理解するにはどうすればよいでしょうか?

SDAを単極単投スイッチとみなすことができ、スイッチを下ろし(つまり、SDA がハイからローへのプロセス)、SDA と SCL が接続され、これが始まり (スタート) とみなすことができます。 。逆に、スイッチを持ち上げると(つまり、SDA のプロセスが Low から High に)、SDA と SCL が切断され、これで終了(停止)とみなすことができます。

確認信号ACK

送信機がバイト (8 ビット) を送信するたびに、クロック パルス 9の間にデータ ラインを解放し、受信機は応答信号をフィードバックします。応答信号がローレベルの場合、それは有効な応答ビット(略してACK)として定義され、受信機がバイトを正常に受け入れたことを示します(つまり、8番目の信号が受信されたとき、つまり完全な応答ビット) (受信が受信されました) バイト、SDA データ ラインをプルダウンする時間です); 応答信号が High の場合、それは非確認応答ビット (NACK) として。バイト。

有効な肯定応答ビット ACK をフィードバックするための要件は、レシーバーが 9 番目のクロック パルスの前のロー レベル期間中に SDA ラインをローにプルし、クロックのハイ レベル期間中に安定したロー レベルであることを保証することです。

受信機がマスターの場合、最後のバイトを受信した後、NACK信号を送信して制御対象の送信機にデータ送信を終了し、SDA ラインを解放してマスター受信機が停止信号 P を送信するように通知します。
I2Cバス応答

データの可用性

I2C バスがデータを送信している場合、クロック信号が High レベルのときにデータ ライン上のデータは安定した状態を維持する必要があり、変動は許容されます。

つまり、データは SCL の立ち上がりエッジが到着する前に準備ができている必要があり、立ち下がりエッジが到着する前に安定している必要があります。

データの可用性

データ送信

I2C バス上で送信されるデータの各ビットには、対応するクロック パルス (または同期制御) があります。つまり、SCL シリアル クロックの協力により、データの各ビットは SDA 上で 1 ビットずつシリアルに送信されます。データ ビットの送信はエッジ トリガで行われます

IIC の読み取りおよび書き込みプロセス

マスターからスレーブへのデータの書き込み

マスターからスレーブへのデータの書き込み

(灰色はマスター→スレーブ、白はスレーブ→マスター、A は ACK、非 A は NACK、読み取りおよび書き込みビット: 0 書き込み/1 読み取り)

プロセス: まず、ホストはデータ送信を開始するための開始信号を生成します。次に、マスターはアドレス ビットと読み書きビット 0 をスレーブに送信し (どのスレーブでどのような操作を実行するかを決定する必要があるため)、応答が成功した後、データの送信を開始し、スレーブは受信したデータに応じて有効な応答または無効な応答が返され、ホストが停止信号を生成するまでは、送信が終了したことを意味します。

マスターからデータを読み取る

マスターからデータを読み取る
(灰色はマスター→スレーブ、白はスレーブ→マスター、A は ACK、非 A は NACK、読み取りおよび書き込みビット: 0 書き込み/1 読み取り)

プロセス: 一般的なロジックは上記と同じなので、ここでは詳しく説明しません。

マルチマスター IIC バス調停

複数のデバイスが IIC バス上にハングしている場合、2 つ以上のマスター デバイスが同時にバスを占有しようとすることがあります (バス競合)。IIC バスにはマルチマスター機能があるため、この時点ではバス調停が必要です。

複数のマスターデバイスが同時にバスを占有したい場合、1 つのマスターデバイスがハイレベルを送信し、別のマスターデバイスがローレベルを送信すると、その時点で送信レベルが SDA バスレベルと一致していないデバイスは自動的にオフになります。その出力段

バス競合の調停は 2 つのレベルで実行されます。まず、アドレス ビットの比較です。マスター デバイスが同じスレーブ デバイスをアドレス指定している場合は、次にデータ ビットの比較に入り、競合調停の信頼性が保証されます。IICバス上の情報を調停に使用するため、情報の損失は発生しません

たとえば:

マスタコントローラ1が送信するデータDATA1が「101 …」、マスタコントローラ2が送信するデータDATA2が「1001 …」とすると、バス開始後、2つのマスタコントローラはデータ ビットが送信されるたびにチェックする必要があります。自身の出力レベルが検出されます。検出されたレベルが自身が送信したレベルと一致する限り、バスを占有し続けます。この場合、アービトレーションを受けることはできません。マスタコントローラ1がデータの3ビット目「1」を送信したとき(メインコントローラ2は「0」を送信) 、「 wire AND 」の結果はSDAのレベルが「0」であるため、メインコントローラ1が自身のデータを検出すると、このとき、マスタコントローラ1はバスの制御を放棄せざるを得ず、マスタコントローラ2がバスの唯一のマスタとなる。

簡単にわかります:

  1. 調停プロセス全体を通じて、マスター 1 もマスター 2 もデータを失うことはありません
  2. 個々のマスターにはバスに対する制御の優先レベルはありません。
  3. バス制御は即座に決定され、「低レベル優先」の原則に従います。つまり、最初に低レベルを送信した人がバスの制御を取得します。

要約:

  1. マスター コントローラーは、SCL (クロック同期)のレベルを検出することにより、スレーブ デバイスとの速度同期の問題を調整します。
  2. マスタコントローラは、SDA-バスアービトレーションで自身が送信するレベルを検出することで、バス競合が発生しているかどうかを判断しますしたがって、I2Cバスの「クロック同期」と「バスアービトレーション」は、デバイス独自のインターフェースの特殊な構造によって実現されています。

IIC CubeMX 構成

構成

1. RCC クロックを設定し、高速外部クロック HSE として構成して、外部クロック ソースを選択します。
I2C構成

2. IIC 構成ここではクロック ストレッチング (クロック ストレッチング)
IIC構成2
について説明しますクロック ストレッチングはSCL ラインを Low にプルすることで送信を一時停止し、 SCL ラインが High レベルに解放されるまで送信は続行されません。クロック ストレッチングはオプションです。実際、ほとんどのスレーブ デバイスには SCL ドライバーが含まれていないため、クロックを伸ばすことができません。

重要な機能

実は、割り込みの送信や受信なども重要ですが、紙面が長くなるので割愛しますが、実はシリアルポートの割り込みと似ています。最も基本的な通信機能のいくつかを次に示します。

HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c,uint16_t DevAddress,uint8_t *pData,uint16_t Size,uint32_t Timeout);
- 功能: 写数据
- 参数:
  *hi2c      设置使用的是那个IIC 例:&hi2c1
  DevAddress 写入的地址 设置写入数据的地址 例:0xA0
  *pData     需要写入的数据
  Size       需要发送的字节数
  Timeout    最大传输时间,超过传输时间将自动退出传输函数
  
  // 发送两个字节数据,IIC写数据函数
- 例如:HAL_I2C_Master_Transmit(&hi2c1,0xA0,(uint8_t*)TxData,2,1000);
HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c,uint16_t DevAddress,uint8_t *pData,uint16_t Size,uint32_t Timeout);
- 功能: 接收数据
- 参数:
  *hi2c      设置使用的是那个IIC 例:&hi2c2
  DevAddress 写入的地址 设置写入数据的地址 例:0xA0
  *pData     存储读取到的数据
  Size       需要发送的字节数
  Timeout    最大传输时间,超过传输时间将自动退出传输函数
HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);
- 功能:IIC写多个数据,该函数适用于IIC外设里面还有子地址寄存器的地址,比如E2PROM,除了
       设备地址,每个存储字节都有其对应的地址。
- 参数:
  *hi2c      设置使用的是那个IIC 例:&hi2c2
  DevAddress 写入的地址 设置写入数据的地址 例:0xA0
  MemAddress 从机寄存器地址,每写入一个字节数据,地址就会自动+1
  MemAddSize 从机寄存器地址字节长度 8/16位
             写入数据的字节类型 8/16I2C_MEMADD_SIZE_8BIT
             I2C_MEMADD_SIZE_16BIT
  *pData     需要写入的数据的起始地址
  Size       传输数据的大小,需要发送的字节数
  Timeout    最大传输时间,超过传输时间将自动退出传输函数
- 例如:HAL_I2C_Mem_Write(&hi2c1,ADDR,i,I2C_MEMADD_SIZE_8BIT,&(I2C_Buffer_Write[i]),8,1000);

実際、HAL_I2C_Mem_Write は、最初に HAL_I2C_MHALaster_Transmit を使用して最初のレジスタ アドレスを送信し、次に HAL_I2C_MHALaster_Transmit を使用して最初のレジスタに書き込まれたデータを送信することと同じです

したがって、特定のペリフェラルにデータを読み書きするだけの場合は、 Master_Receive/Master_Transmitを使用し、ペリフェラルの場合は、各データのサブアドレス (E2PROM など)、デバイス アドレス、およびレジスタ ストレージが存在します(Mem_Write には 2 つのアドレスがあり、Master_Transmit にはスレーブ アドレスのみがあります)。

おすすめ

転載: blog.csdn.net/dbqwcl/article/details/127094071