忍者ブログ

Fグループ電子工作講座

秋月電子SH7125ボードで始めるマイコン開発

RX220で簡易I2C(送信編)

RX220で本気のI2C通信を行う場合はRIIC機能を使います。
RIICではSCLとSDA端子を使うのですが、64ピンのRX220ではSCLとSDAに割り当て可能な
端子はそれぞれP16P17のみとなります。
ところがP16P17貴重なPWM端子なのでI2Cとして使いたくありません。

ハードウェアマニュアルの機能別端子一覧を見るとSCL,SDAの代わりにSSCLSSDAという
端子は幾つかあります。SDAでもSSDAでもまあ、変わらないだろうと思っていたらちょっ
と厄介なことになりました。

SCLSDARIICで使用するのに対して、SSCLとSSDAはRIICの端子ではありません
マニュアルにて簡易I2Cにて使用するところまでは分かったのですが、そこから先は
ネット上でよさげな情報が見つかりません。しかも公式サンプルを探してもどれが簡易I2Cの
サンプルなのかわかりません。

そこでハードウェアマニュアルを読み解きながら設定をしました。
RIIC簡易I2Cでは設定がかなり違う様です。

ハードウェアマニュアルの
・SCI の初期化(簡易I2C モード)
および
・マスタ送信動作(簡易I2C モード))
のフローチャートに基づいて設定を行っていきます。
※Acrobat Reader DCでは「起動時に保護モードを有効にする」を無効にしておかないと
日本語検索ができませんでした。


RX220の他の機能は設定の解説を省略していましたが、今回はSH7125と異なるので真面目に紹介してみます。


簡易I2Cの初期化

初期化で必要なのは大まかに
・端子の機能設定
・通信モジュールの停止解除
・簡易I2Cモードへの変更
・クロックや通信速度など通信条件の設定
の4項目です。
※2019/02/22色々間違っていたので修正

PB6(SCI9_SSCL)、PB7(SCI9_SSDA)を使って簡易I2C通信を行います。

設定1、ピン設定と通信モジュールの停止解除
初期化関数を作成します。

<設定>
void init_I2C(void)
{
    //入出力の設定
    PORTB.PDR.BIT.B6=1;                //PB6 SSCLを出力設定
    PORTB.PDR.BIT.B7=1;                //PB7 SSDAを出力設定

    //出力方式の設定
    PORTB.ODR1.BIT.B4=1;            //PB6をオープンドレインに設定
    PORTB.ODR1.BIT.B6=1;            //PB7をオープンドレインに設定

    //特殊機能を使用する端子の設定
    PORTB.PMR.BIT.B6=1;                //PB6を周辺機能モードに変更
    PORTB.PMR.BIT.B7=1;                //PB7を周辺機能モードに変更

    //特殊機能設定開始
    MPC.PWPR.BIT.B0WI = 0;            //PFSレジスタの保護解除をするPFSWEレジスタの保護解除
    MPC.PWPR.BIT.PFSWE = 1;            //PFSレジスタの保護解除

    //Pxx 端子機能制御レジスタ(PxxPFS)
    MPC.PB6PFS.BIT.PSEL = 0xA;        //PB6の周辺機能を設定(SSCL)
    MPC.PB7PFS.BIT.PSEL = 0xA;        //PB7の周辺機能を設定(SSDA)

    //特殊機能設定終了
    MPC.PWPR.BIT.PFSWE = 0;            //PFSレジスタの保護
    MPC.PWPR.BIT.B0WI = 1;            //PFSレジスタの保護をするPFSWEレジスタの保護

    //SCI9モジュールの停止解除
    SYSTEM.PRCR.WORD = 0x0A503;        //クロックと動作モードの保護解除
    MSTP(SCI9) = 0;                    //SCI9モジュール停止解除
    SYSTEM.PRCR.WORD = 0x0A500;        //クロックと動作モードの保護

ここまでは他の機能の設定とほぼ同じです。
2019/02/22 追記
出力方式をNチャンネルオープンドレイン(オープンコレクタ)に設定する必要があります。


設定2、クロック同期式モードへの変更、通信条件の設定
ここからはハードウェアマニュアルのSCI の初期化(クロック同期式モード)のフローチャートに従って記述していきます。

    //クロックの設定準備
    SCI9.SCR.BIT.CKE = 0x00;        //内部クロックを使用
    SCI9.SCR.BYTE&=~0x30;            //送信禁止+受信禁止

    //[2]
    SCI9.SIMR3.BIT.IICSDAS=0x3;        //SSDAn端子はハイインピーダンス状態
    SCI9.SIMR3.BIT.IICSCLS=0x3;        //SSCLn端子はハイインピーダンス状態

    //[3]
    SCI9.SMR.BIT.CM=0;            //0:調歩同期式 1:クロック同期式
    SCI9.SMR.BIT.CKS=0x3;        //PLCK/64
    SCI9.SCMR.BIT.SDIR=1;        //MSBファーストで送受信
    SCI9.SCMR.BIT.SINV=0;        //そのまま送信
    SCI9.SCMR.BIT.SMIF=0;        //SCIモード

    //[4]
/*32MHz,1分周期の場合*/
//    SCI9.BRR = 103;            // 9600bps
    SCI9.BRR = 51;            //19200bps
//    SCI9.BRR = 25;            //38400bps
//    SCI9.BRR = 8;            //115200bps

    //[5]
    SCI9.SEMR.BIT.NFEN=1;        //ノイズ除去フィルタあり
    SCI9.SNFR.BIT.NFCS=1;        //1分周のクロックをノイズフィルタに使用

    SCI9.SIMR1.BIT.IICM=1;        //簡易I2Cモード
    SCI9.SIMR1.BIT.IICDL=1;        //SCLから1サイクル遅れてSDAを変化させる

    SCI9.SIMR2.BIT.IICACKT=1;    //NACK送信またはACK/NACK受信
    SCI9.SIMR2.BIT.IICCSC=1;    //クロック同期を行う(スレーブからのクロックストレッチを受け入れる)
    SCI9.SIMR2.BIT.IICINTM=1;    //0:ACK/NACK割込み、1:送受信割込み

    SCI9.SPMR.BYTE=0;            //SPI機能全停止

    SCI9.SCR.BYTE|=0x30;        //送信許可+受信許可
}

※2019/02/27 追記

送信許可、受信許可の設定を個別で変更すると先に変更した方だけが有効になるようです。
送信受信の許可/禁止はビットごとに変更せず、いっぺんに変更してください。


<解説>
[3]の部分
SCI9.SMR.BIT.CKSは任意の設定が可能です。
今回は出力の視認のため、なるべく遅くなるようにメインクロックの1/64の速度で動作させます。

[4]の部分
今回は32MHz動作時のUART通信の値をそのまま持ってきました。
メインクロックの設定を変更していない場合はLOCO 125KHzで動作するので19200bpsにはなりません。
クロックの速度はUARTと異なりマスターがコントロールするので、適当に設定しても動きます。

[5]の部分
ノイズ除去フィルタありに設定してみました。効果のほどは未検証です。
SCI9.SIMR2.BIT.IICINTMは送受信割込みに設定してみました。
とりあえず割込み無しで送信テストを行うので、今回はどちらもで良さそうです。


I2Cの送信

通信の準備ができたので送信を試してみます。
マスタ送信動作(簡易I2C モード)のフローチャートに基づいて設定を行っていきます。
SH7125の時と同様にDRV8830に指令を送ります。

DRV8830の取説に従って、通信の順は
・スタートコンディション
・スレーブアドレス(0xC8)
・サブアドレス(0x00)
・設定値(0x49)
・ストップコンディション
となります。

<設定>
void send_i2c(void){
    int i;

    //スタートコンディションの発行
    SCI9.SIMR3.BIT.IICSTIF=0;    //フラグクリア
    SCI9.SIMR3.BIT.IICSTAREQ=1;    //スタートコンディション生成指令
    SCI9.SIMR3.BIT.IICSDAS=0x1;    //SSDAn端子は開始条件、再開始条件、停止条件
    SCI9.SIMR3.BIT.IICSCLS=0x1;    //SSCLn端子は開始条件、再開始条件、停止条件
    while(SCI9.SIMR3.BIT.IICSTIF==0);    //開始/再開始/停止条件生成が完了するまで待機

    //データ送信準備
    SCI9.SIMR3.BIT.IICSTIF=0;    //フラグクリア
    SCI9.SIMR3.BIT.IICSDAS=0x0;    //SSDAn端子はデータ出力
    SCI9.SIMR3.BIT.IICSCLS=0x0;    //SSCLn端子はクロック出力

    //データ0(アドレス)送信
    SCI9.TDR=0xC8;    //宛先アドレス
    for(i=0;i<100;i++);    //ちょっとだけ空ループ
    while(SCI9.SSR.BIT.TEND==0);    //送信完了まで待機

    //データ1(サブアドレス)送信
    SCI9.TDR=0x00;    //サブアドレス
    for(i=0;i<100;i++);    //ちょっとだけ空ループ
    while(SCI9.SSR.BIT.TEND==0);    //送信完了まで待機

    //データ2(電圧設定)送信
    SCI9.TDR=0x49;    //電圧設定値
    for(i=0;i<100;i++);    //ちょっとだけ空ループ
    while(SCI9.SSR.BIT.TEND==0);    //送信完了まで待機

    //ストップコンディションの発行
    SCI9.SIMR3.BIT.IICSTPREQ=1;    //ストップコンディション
    SCI9.SIMR3.BIT.IICSDAS=0x1;    //SSDAn端子は開始条件、再開始条件、停止条件
    SCI9.SIMR3.BIT.IICSCLS=0x1;    //SSCLn端子は開始条件、再開始条件、停止条件
    while(SCI9.SIMR3.BIT.IICSTIF==0);    //開始/再開始/停止条件生成か完了するまで待機

    //送信終了の後処理
    SCI9.SIMR3.BIT.IICSTIF=0;    //フラグクリア
    SCI9.SIMR3.BIT.IICSDAS=0x3;    //SSDAn端子はハイインピーダンス状態
    SCI9.SIMR3.BIT.IICSCLS=0x3;    //SSCLn端子はハイインピーダンス状態

}

<解説>
フローチャートではTXI割込みを使用していますが、今回は割り込みを使わず送信完了フラグTENDが立つまで待機させました。
また、SCI9.TDRを設定直後だとTENDが立っている様なので、送信を開始するまでの間を持たせるためにちょっとだけ空ループをさせています。
今回はスレーブからのACK/NACKの返信を気にせずに一方的にデータを送って一方的に終了させました。

とりあえず、これでDRV8830が動くところまでは確認できました。
次回は受信動作を確認します。
PR

コメント

プロフィール

HN:
ぼんどF博士
性別:
男性

最新コメント