HAL_I2C_Master_Transmit()
関数から始めましょう。その宣言を確認すると:
HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
2番目のパラメータの軽微な問題、スレーブデバイスのアドレス。スレーブデバイスのアドレスはb1010000
、8ビット形式に完成させると0xA0
、あなたが言ったようにになります。これを渡すとHAL_I2C_Master_Transmit()
、R / Wビットを手動で設定する必要がなくなり、HALが代わりに設定します。したがってHAL_I2C_Master_Transmit()
、送信されたR / Wビットを呼び出すと自動的に0にHAL_I2C_Master_Receive()
なり、送信されたR / Wビットを呼び出すと自動的に1になり、書き込み操作を示します。R / W値を混在させましたが、これは関数のドントケアビットであるため、コードの実際のエラーではありません。
3番目のパラメータは、( uint8_t *pData
)でバッファへのポインタ含まれて送信されるデータを。さて、あなたの呼び出しで3番目のパラメータ0x0C
はあなたの実際のデータ、レジスタアドレスです。問題は、HAL_I2C_Master_Transmit()
未定義のデータが見つかる可能性のあるメモリ位置へのポインタとして(によって)解釈されることです。
4番目のパラメータであり、バッファのサイズ、送信されるバイトの数。1バイトを送信する場合、このパラメーターは10ではなく1にする必要があります。
使用する場合は、スレーブデバイスのデータシートを取得し、書き込みおよび読み取り操作のドキュメントを調べることが最善の方法です。I2C
レジスターの書き込み
これは、データシートの対応する図です。
したがって、スレーブアドレスをバスに送信した後、レジスタポインタ、MSBバイト、LSBバイトの 3バイトを送信する必要があります。HALが16ビットレジスタを書き込む一般的な実装:
void write_register(uint8_t register_pointer, uint16_t register_value)
{
uint8_t data[3];
data[0] = register_pointer; // 0x0C in your example
data[1] = register_value>>8; // MSB byte of 16bit data
data[2] = register_value; // LSB byte of 16bit data
HAL_I2C_Master_Transmit(&hi2c1, 0xA0, data, 3, 100); // data is the start pointer of our array
}
あなたの値の例: write_register(0x0C, 0x0054);
あるいは、HAL定義のレジスタ書き込み関数も使用できます。これには、レジスタアドレスとアドレスサイズを渡すための追加のパラメータがあります。
void write_register(uint8_t register_pointer, uint16_t register_value)
{
HAL_StatusTypeDef status = HAL_OK;
status = HAL_I2C_Mem_Write(&hi2c1, 0xA0, (uint16_t)register_pointer, I2C_MEMADD_SIZE_8BIT, (uint8_t*)(®ister_value), 2, 100);
/* Check the communication status */
if(status != HAL_OK)
{
// Error handling, for example re-initialization of the I2C peripheral
}
}
これで、HAL_I2C_Master_Receive()
機能はほぼ同じになります。
HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
唯一の違いは、3番目のパラメータが、受信したデータが格納されるバッファへのポインタであることです。それは0x02
あなたのコードにあり、あなたの目的が何であったかはわかりませんが、ポインタとして解釈されます(残念ながらランダムなメモリ位置への)。
レジスタを読み取る
レジスタを読み取るには、適切なレジスタポインタを送信して、書き込み操作でそのレジスタを選択する必要があります(このレジスタを読み取りの直前に書き込んだ場合、そのアドレスをポインタに再度送信する必要はありません。レジスタ、書き込み時に設定済みです)。次に、読み取り操作で、16ビットデータを読み取ります。I2CI2C
void read_register(uint8_t register_pointer, uint8_t* receive_buffer)
{
// first set the register pointer to the register wanted to be read
HAL_I2C_Master_Transmit(&hi2c1, 0xA0, ®ister_pointer, 1, 100); // note the & operator which gives us the address of the register_pointer variable
// receive the 2 x 8bit data into the receive buffer
HAL_I2C_Master_Receive(&hi2c1, 0xA0, receive_buffer, 2, 100);
}
例:
uint8_t reg_ptr = 0x0C;
uint8_t buffer[2];
read_register(reg_ptr, buffer);
// the register content available in the buffer
また、HALで定義されたレジスタ読み取り関数もあります。
uint16_t read_register(uint8_t register_pointer)
{
HAL_StatusTypeDef status = HAL_OK;
uint16_t return_value = 0;
status = HAL_I2C_Mem_Read(&hi2c1, 0xA0, (uint16_t)register_pointer, I2C_MEMADD_SIZE_8BIT, &return_value, 2, 100);
/* Check the communication status */
if(status != HAL_OK)
{
}
return return_value;
}
詳細については、データシートの「8.5プログラミング」セクションをお読みください。