やりたいこととしては、SiliconLabsのAM/FMラジオ Si4730の制御です。Si4730は、STM32のI2C1に接続されていてアドレスは0x11です。STM32CubeMXでI2C1を適切に設定し、初期化コードが生成されていることを前提とします。
I2Cで送信
まずは送信です。0x12 SET_PROPERTYコマンドでProperty 0x0104 DIGITAL_OUTPUT_SAMPLE_RATEに0xBB80を設定します。I2C送信データとしては、レジスタ0x12にレジスタ値0x000104BB80を送信することになります。ロジアナ波形は次の通りです。HAL_I2C_Master_Transmit()関数の場合
uint8_t txBuffer4730[6];uint16_t Si4730_Pri_address = 0x11<<1;
txBuffer4730[0] = 0x12;
txBuffer4730[1] = 0x00;
txBuffer4730[2] = 0x01;
txBuffer4730[3] = 0x04;
txBuffer4730[4] = 0xBB;
txBuffer4730[5] = 0x80;
HAL_I2C_Master_Transmit(&hi2c1, Si4730_Pri_address, txBuffer4730, 6, 100);
- 第2引数は7ビットのデバイスアドレスを1ビット左シフトさせます
- 第4引数は送信データのByte数
HAL_I2C_Mem_Write()関数の場合
この関数を使って同じ波形を作れます。メモリアクセス用の関数なのでレジスタとデータを分けて指定します。uint8_t txBuffer4730[5];
uint16_t Si4730_Pri_address = 0x11<<1;
txBuffer4730[0] = 0x00;
txBuffer4730[1] = 0x01;
txBuffer4730[2] = 0x04;
txBuffer4730[3] = 0xBB;
txBuffer4730[4] = 0x80;
HAL_I2C_Mem_Write(&hi2c1, Si4730_Pri_address, 0x12, 1, txBuffer4730, 5, 100);
- 第2引数は7ビットのデバイスアドレスを1ビット左シフトさせます
- 第3引数はメモリ(レジスタ)アドレスを指定
- 第4引数はメモリ(レジスタ)アドレスサイズのByte数
- 第6引数は送信データのByte数
I2Cで受信
次に受信です。先ほど設定したプロパティを 0x13 GET_PROPERTYコマンドで読み出します。I2Cでの通信手順としては、まず最初に4バイトのレジスタ指定(書き込み)を送信し、直後に受信する2ステップの流れとなります。HAL_I2C_Master_Receive()関数の場合
uint8_t txBuffer4730[4];uint8_t rxBuffer4730[4];
uint16_t Si4730_Pri_address = 0x11<<1;
txBuffer4730[0] = 0x13;
txBuffer4730[1] = 0x00;
txBuffer4730[2] = 0x01;
txBuffer4730[3] = 0x04;
HAL_I2C_Master_Transmit(&hi2c1, Si4730_Pri_address, txBuffer4730, 4, 100);
HAL_I2C_Master_Receive(&hi2c1, Si4730_Pri_address, rxBuffer4730, 4, 100);
- 第2引数は7ビットのデバイスアドレスを1ビット左シフトさせます
- 第3引数は受信バッファのポインタ
- 第4引数は受信データのByte数
HAL_I2C_Mem_Read()関数の場合
この関数では、送信と受信を一括して行える反面、2バイトまでしかレジスタ指定できません。参考としてレジスタ0x12ABから3バイトを受信する場合を例示します。uint16_t txBuffer4730;
uint8_t rxBuffer4730[3];
uint16_t Si4730_Pri_address = 0x11<<1;
HAL_I2C_Mem_Read(&hi2c1, Si4730_Pri_address, txBuffer4730, 2, rxBuffer4730, 3 , 1000);
- 第2引数は7ビットのデバイスアドレスを1ビット左シフトさせます
- 第3引数はレジスタアドレス
- 第4引数はレジスタアドレスのByte数
- 第5引数は受信バッファのポインタ
- 第6引数は受信データのByte数