忍者ブログ

Fグループ電子工作講座

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

SHプログラムを分割する

前回のヘッダファイルの使い方に基づき、今回はプログラムを分割します。

分割するのはSH7125ベースボードにスイッチとLEDを増設した回のプログラムです。
関数のプロトタイプ宣言をヘッダファイルに、関数の実体をソースファイルに分割します。
ファイル名はそれぞれ
io_setup.h
io_setup.c
としました。

関数のプロトタイプ宣言と関数の実体しか出てこないのでさほど難しくありません。

ファイル作成

1) メモ帳などでテキスト(*.txt)を作製
2) ファイル → 名前を付けて保存
   ファイル名:io_setup.hまたはio_setup.c
   ファイルの種類:すべてのファイル
3) 保存
保存したファイルはメインのソースファイル(*.c)があるフォルダに移動させておきましょう。

プロジェクトへの追加

1) 該当のプロジェクト(*.hws)を開く
2) プロジェクト → ファイルを追加
3) io_setup.cを追加
※io_setup.hは自分で追加しなくてもincludeで勝手にDependenciesに追加される様です
 気になる方はio_setup.hも追加しましょう。
 自分で追加した場合は C header fileに追加されます。

あとは基本的にメインのソースファイルの該当部分をそれぞれ作製したヘッダとソースに移すだけです。
今回は今後の設定を分かりやすくするために使用していないポートの機能は何も設定せず放置する仕様に変更しました。


io_setup.hの内容

void hardware_setup(void);
void set_LED_R(int);
void set_LED_G(int);
int get_sw1(void);
int get_PortA_bit(int);
void set_PortE_bit(int,int);

ダウンロード


io_setup.cの内容

#include "iodefine.h"
#include "io_setup.h"

/*=============各ポートの入出力設定と汎用IOの機能設定=============*/
void hardware_setup(void){
    //ポートEの特殊機能設定
    //今回はポートEの0~7を汎用IOに設定する
    PFC.PECRL2.BIT.PE7MD  = 0x0;    //PE07 IO
    PFC.PECRL2.BIT.PE6MD  = 0x0;    //PE06 IO
    PFC.PECRL2.BIT.PE5MD  = 0x0;    //PE05 IO
    PFC.PECRL2.BIT.PE4MD  = 0x0;    //PE04 IO

    PFC.PECRL1.BIT.PE3MD  = 0x0;    //PE03 IO
    PFC.PECRL1.BIT.PE2MD  = 0x0;    //PE02 IO
    PFC.PECRL1.BIT.PE1MD  = 0x0;    //PE01 IO
    PFC.PECRL1.BIT.PE0MD  = 0x0;    //PE00 IO

    //ポートEの入出力を設定する
    //3,2を入力それ以外は出力
    //1111 1111 1111 0011(2進数)
    //   F    F    F    3(16進数)
    PFC.PEIORL.WORD = 0xFFF3;
    // !!!注意!!!
    //ベースボードを接続する場合PE02は出力に設定しないこと。

    //ポートAの特殊機能設定
    PFC.PACRL4.BIT.PA15MD = 0x0;    //PA15 IO
    PFC.PACRL4.BIT.PA14MD = 0x0;    //PA14 IO
    PFC.PACRL4.BIT.PA13MD = 0x0;    //PA13 IO
    PFC.PACRL4.BIT.PA12MD = 0x0;    //PA12 IO

    PFC.PACRL3.BIT.PA11MD = 0x0;    //PA12 IO
    PFC.PACRL3.BIT.PA10MD = 0x0;    //PA12 IO

    //ポートAの入出力を設定する
    PFC.PAIORL.WORD = 0x0000;    //全部入力

}

/*============= LED赤の出力関数(0:消灯、1:点灯) =============*/
void set_LED_R(int on){
    if(on==0)    //関数への入力が0の時
        PE.DRL.BIT.B0=0;    //消灯
    else        //それ以外(入力が0の時)
        PE.DRL.BIT.B0=1;    //点灯
}

/*============= LED緑の出力関数(0:消灯、1:点灯) =============*/
void set_LED_G(int on){
    if(on==0)    //関数への入力が0の時
        PE.DRL.BIT.B1=0;    //消灯
    else        //それ以外(入力が0の時)
        PE.DRL.BIT.B1=1;    //点灯
}

/*============= SW1の状態取得関数(SW1上:0、SW1下:1)=============*/
int get_sw1(void){
    return PE.DRL.BIT.B2;
}


/*============= PortA 10-15入力関数(ビット番号) =============*/
int get_PortA_bit(int bit){
    int state=0;    //変数を宣言しておく
    int outdata=0;    //変数を宣言しておく

    if( bit<10 || bit>15 )    //関係ない端子を指定した場合
        return -1;            //0,1以外の数値を返して強制終了
  
    state = PA.DRL.WORD&(0x0001<<bit);    //0または0以外の値として取得
    outdata = (state==0)? 1 : 0 ;        //0-1に変換(プルアップへの対応のため反転)
    return outdata;    //指定したポートの状態を返す
}

/*============= PortE 4-7出力関数(ビット番号、ON/OFF) =============*/
void set_PortE_bit(int bit,int on){
    int outdata=0;

    if( bit<4 || bit>7 )    //関係ない端子を指定した場合
        return;                //ここでこの関数を強制終了

    outdata=0x0001<<bit;

    if(on==0){    //OFFする場合
        PE.DRL.WORD &=~outdata;    //OFF 指定したビットのみ0にする
    }else{
        PE.DRL.WORD |= outdata;    //ON 指定したビットのみ1にする
    }
}

変更箇所解説

PFC.PECRL2.WORDだった個所をPFC.PECRL2.BIT.PE7MDPE4MDに変更しました。
以前はPE4~PE7の4つ分の特殊機能設定が入ったPECRL2WORDアクセスで4つ分まとめて設定していましたが、これをBITアクセスを使って1ビットごとに分けて設定する仕様に変更しました。
ただし、このBITというアクセス方法はPECRL2に1ビットずつアクセスするという意味ではなく、PEの1ビット分に該当する個所に関してPECRL2に3ビットずつアクセスしています。

ダウンロード

別ファイルの機能取り込み

とりあえず機能を別ファイルに移すことができましたが、メインのソースファイルと新規作成したファイルが関連付けられていないためこのままではビルドの際にエラーが出ます。
そこでメインのソースファイルでヘッダファイルio_setup.hをincludeします

メインのソースファイル(sw1.cとか)の中身

#include "iodefine.h"    //マイコン設定に必要な情報読み込み
#include "io_setup.h"    //ポートの入出力設定に用いる関数読込

main(){
    int i;
    int bit_state;
    hardware_setup();    //マイコンの端子を初期化(汎用IO)
    set_LED_R(0);        //とりあえずLED赤消灯
    set_LED_G(0);        //とりあえずLED緑消灯
    while(1){
        if(get_sw1()){        //スイッチ1がON:下の時
            set_LED_R(1);    //LED赤点灯
            set_LED_G(0);    //LED緑消灯
        }else{                //スイッチ1がON:下じゃない時(OFF:上)
            set_LED_R(0);    //LED赤消灯
            set_LED_G(1);    //LED緑点灯
        }

        //4bit分の入力を受け付け、4bit分出力する
        for(i=0;i<4;i++){
            bit_state = get_PortA_bit(10+i);    //PortAの10~13ビット目の状態取得
            set_PortE_bit(4+i,bit_state);        //PortEの4~7ビット目に出力
        }
    }
}

これで細かい設定が完全に裏方に回りメインのソースは実現したい内容だけになりました。
余計な部分に気を取られる事がなくなり、メインのプログラムに集中できるようになります。

ダウンロード
PR

コメント

プロフィール

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

最新コメント