STM32資料 発展編5

実際にクラスを書いてみよう

前回学習した内容を使って、発展編3のクラスをよりよくしてみよう

今回やること

発展編3で書いたクラスに次の要素を追加してみよう

仕様 やること 内容
I2CとSPIに対応 仮想関数を使う ICM45686_I2C, ICM45686_SPIクラスを作成する
設定の数字を文字に対応させる enum classを使用 REGISTERの設定を対応させる

enum classを使う

レジスタの値を直接書き込んでいるので、ここにenum classを使ってみよう

基底クラス(ICM45686.hpp)のpublicの中に定義してみよう

値を書いたあとは";(セミコロン)"ではなく、",(カンマ)"を用いる

enum class REGISTER : uint8_t {

    WIA = 0x72, //WIAレジスタのアドレス
    //他2つのレジスタの値を定義してみよう
}

仮想関数を定義する

2つの通信を実装するために、仮想関数と継承を使う

発展編3のクラスで定義したRead/Write関数を仮想関数にしてみよう

//書き込みと読み取りの関数

virtual void Read(uint8_tregister, uint8_t* rx_buffer, uint8_t len) = 0; //Read関数の宣言
virtual void Write(uint8_t register, uint8_t* tx_buffer, uint8_t len) = 0; //Write関数の宣言

仮想関数は、派生クラス(通信のクラス)で実装するので、ICM45686.cppからこの関数の実装部分を消しておこう

派生クラスを作成する

先ほど定義した仮想関数を実装するために派生クラスを作成する

この中で仮想関数を実装するので、

ICM45686.cppを参考にICM45686_I2C.cppを作成してみよう

// I2Cのクラスを定義
class ICM45686_I2C: public ICM45686{
    
    public:

        ICM45686_I2C(I2C_HandleTypeDef* use_i2c_pin); 

    private:

        //仮想関数の実装
        void Read(uint8_t register, uint8_t* rx_buffer, uint8_t len); //Read関数の実装
        void Write(uint8_t register, uint8_t* tx_buffer, uint8_t len); //Write関数の実装
        I2C_HandleTypeDef* i2c_pin; //I2Cのピン情報を格納する変数

}; //I2Cのクラスの定義

難しそうに聞こえるが、コンストラクタの実装とHALライブラリのI2C関数を利用して

3つの関数を実装するだけなので、頑張ってみてね

実際に使ってみよう

ICM45686_I2Cクラスで具体的な通信を定義したので、ICM45686_I2Cクラスを呼び出そう

基本的には発展編3と同じように使うことができる

#include "wrapper.hpp"
#include "ICM45686_I2C.hpp"
#include "i2c.h"
#include "usart.h"

ICM45686 ICM45686_I2C(&hi2c1); //ICM45686_I2Cのインスタンスを作成
int16_t accel_data[3]; //加速度データを格納する変数
int16_t gyro_data[3]; //ジャイロデータを格納する変数[

uint8_t wia; //WIAを格納する変数

void init(){

    wia = icm.WIA(); //WIAを取得

    //WIAが正しいか確認のため送信する(成功なら0、失敗なら1が送信される)
    HAL_UART_Transmit(&huart2, &wia, 1, 1000);

    //電源モードを設定する関数を呼び出す
    icm.PowerON(); 
}

void loop(){   

    //データを取得する関数を呼び出す
    icm.GetSensorData(accel_data, gyro_data);

    //取得したデータを送信する(コメントアウトで送信するデータを選べる)

    HAL_UART_Transmit(&huart2, (uint8_t*)"Accel Data: ", 12, 1000);
    HAL_UART_Transmit(&huart2, (uint8_t*)&accel_data, sizeof(accel_data), 1000);

    //HAL_UART_Transmit(&huart2, (uint8_t*)"Gyro Data: ", 12, 1000);
    //HAL_UART_Transmit(&huart2, (uint8_t*)&gyro_data, sizeof(gyro_data), 1000);
}

やってみよう

ICM45686_I2Cクラスを参考にSPI通信を行うICM45686_SPIクラスを作成してみよう

仮想関数とコンストラクタの実装だけなので、ICM45686クラスや

wrapper.cppのインクルードとインスタンス作成以外は変更しないで実装できる

終わりに

今回は継承や仮想関数を利用したクラスを作成してみました

ICM45686(基底クラス)やwrapper.cppにほとんど影響を与えずに通信形式を変更でき

リンク

・メインページ