忍者ブログ

Fグループ電子工作講座

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

I2Cの設定(1)無理矢理動かす

前回から時間が空きましたが、実際にI2Cを使ってみます。

I2Cとは
I2Cの設定(2)もう少し真面目に動かす
I2Cの設定(3)関数化
I2Cを試してみる

通信試験用にI2C仕様のモータドライバを使用します。
秋月:DRV8830使用DCモータードライブキット
色んな事情により、マイコンはSH7125ベースボードを使用します。

取扱説明書によれば
 アドレス:0xC8
 データ0:0x00
 データ1:0x49
の順に送信すればモーターが回ります。

配線

今回は目で見てビットが判別できる超低速でデータ送信を行います。
また、送信状態を把握するためにLEDポート(PE0,PE1)を使用します。
ドライバからのACKの受信を無視して一方的にデータを送信します。

本来バスはプルアップするのですが、今回はプルアップせず、
抵抗を経由して1対1で接続します。

本来の回路
 


実験用回路

また、スレーブがACKを返した時、マスターH、スレーブLとなる事を視認するため、
LEDを付けてみます。

実際の配線

モータードライバの電力はベースボードから供給しています。
モーターはコンデンサを付けたものを使用します。




プログラム

割込み等を使用せずに出力のON-OFFだけ制御します。
マイコン内で内部カウントをインクリメント(1づつ増加)させていき、内部カウントに応じてSCLとSDAを制御します。


動作確認のため、汎用性を無視してプログラムを作成します。
LEDの制御関数のみ以前作成したものを使います。
汎用IO設定:io_setup.cio_setup.h

<設定>
#include "io_setup.h"

main(){
    int i=0;
    int count=0;        //内部カウント
    int scl=1,sda=1;    //バス状態は1
    int addless;
    int data[2];
    int stop_f=0;

    hardware_setup();    //入出力の初期化
    set_LED_R(scl);        //LED赤の初期化(クロック)
    set_LED_G(sda);        //LED緑の初期化(データ)

    /*変数の初期化*/
    addless=0xC8;    //アドレスの設定
    data[0]=0;        //データ0の設定(サブアドレス)
    data[1]=0x49;    //データ1の設定(電圧、正転逆転)

    /*メインループ*/
    while(1){
        i++;
        if(i>40000){    //40000カウントごとに処理
            i=0;
            count++;    //内部カウントを1増加
        }
   
        //クロック出力の設定
        if(stop_f){            //通信停止中
            scl=1;            //バス開放
            count=0;        //カウントリセット
            i=0;            //カウントリセット
        }else if((count/2)%2){    //2で割って、更に2で割った余りが0でないとき2,3,6,7,10,11・・・・
            scl=0;
        }else{                //それ以外
            scl=1;
        }//end count

        switch(count){    //内部カウントに応じてSDAを設定
            case 0:
                sda=1;
                break;
            case 1:        //スタートコンディション
                sda=0;
                break;

            case 3+4*0:    //3 アドレスbit7
                sda=(addless&0x80)?1:0;
                break;
            case 3+4*1:    //7 アドレスbit6
                sda=(addless&0x40)?1:0;
                break;
            case 3+4*2:    //11 アドレスbit5
                sda=(addless&0x20)?1:0;
                break;
            case 3+4*3:    //15 アドレスbit4
                sda=(addless&0x10)?1:0;
                break;
            case 3+4*4:    //19 アドレスbit3
                sda=(addless&0x08)?1:0;
                break;
            case 3+4*5:    //23 アドレスbit2
                sda=(addless&0x04)?1:0;
                break;
            case 3+4*6:    //27 アドレスbit1
                sda=(addless&0x02)?1:0;
                break;
            case 3+4*7:    //31 アドレスbit0
                sda=(addless&0x01)?1:0;
                break;
            case 3+4*8:    //35 ACK待ち
                sda=1;
                break;

            case 3+36+4*0:    //39 データ0bit7
                sda=(data[0]&0x80)?1:0;
                break;
            case 3+36+4*1:    //43 データ0bit6
                sda=(data[0]&0x40)?1:0;
                break;
            case 3+36+4*2:    //47 データ0bit5
                sda=(data[0]&0x20)?1:0;
                break;
            case 3+36+4*3:    //51 データ0bit4
                sda=(data[0]&0x10)?1:0;
                break;
            case 3+36+4*4:    //55 データ0bit3
                sda=(data[0]&0x08)?1:0;
                break;
            case 3+36+4*5:    //59 データ0bit2
                sda=(data[0]&0x04)?1:0;
                break;
            case 3+36+4*6:    //63 データ0bit1
                sda=(data[0]&0x02)?1:0;
                break;
            case 3+36+4*7:    //67 データ0bit0
                sda=(data[0]&0x01)?1:0;
                break;
            case 3+36+4*8:    //71 ACK待ち
                sda=1;
                break;

            case 3+36*2+4*0:    //75 データ0bit7
                sda=(data[1]&0x80)?1:0;
                break;
            case 3+36*2+4*1:    //79 データ0bit6
                sda=(data[1]&0x40)?1:0;
                break;
            case 3+36*2+4*2:    //83 データ0bit5
                sda=(data[1]&0x20)?1:0;
                break;
            case 3+36*2+4*3:    //87 データ0bit4
                sda=(data[1]&0x10)?1:0;
                break;
            case 3+36*2+4*4:    //91 データ0bit3
                sda=(data[1]&0x08)?1:0;
                break;
            case 3+36*2+4*5:    //95 データ0bit2
                sda=(data[1]&0x04)?1:0;
                break;
            case 3+36*2+4*6:    //99 データ0bit1
                sda=(data[1]&0x02)?1:0;
                break;
            case 3+36*2+4*7:    //103 データ0bit0
                sda=(data[1]&0x01)?1:0;
                break;
            case 3+36*2+4*8:    //107 ACK待ち
                sda=1;
                break;

            case 3+36*3:    //111 ストップコンディション準備
                sda=0;
                break;
            case 3+36*3+2:    //113 ストップコンディション
                sda=1;
                stop_f=1;
                break;

            case :
                break;
        }//end switch

        set_LED_R(scl);        //LED赤(クロック)を出力
        set_LED_G(sda);        //LED緑(データ)を出力

    }//end while
}//end main

モーターが回れば成功です。
スレーブがACKを返すとブレッドボードのLEDが光ることが分かるはずです。
0x49を変えるとモーターの回り方が変わります。

40000カウントでインクリメントしていますが、1カウントでインクリメントすれば
一瞬で通信が終わるので起動直後からモーターが回るようになります。
PR

コメント

プロフィール

HN:
ぼんどF博士
性別:
男性
自己紹介:

最新コメント