ものづくりBLOG blog page

H8サンプルプログラム-その3

2010-05-28 (Fri) 09:14

H8サンプルプログラム-その3

CPUボード:RY3048Fone を使って、
制御対象回路として「ものづくり kumamoto Ver.01」を制御するサンプルプログラムを作ります。
7セグメントLED(LED1、LED2)の点灯、スイッチ入力を制御します。小さなテーマの集まりですが、対象としているハードウェアの接続(ケーブル、回路内のすべて)を確認しながら進めてください。その一つひとつがプログラムの力になります。


■テーマ概要
7セグメントLEDを使い、1秒間隔でカウントアップ、カウントダウンするカウンタを作ります。
表示の初期値は、SW1(トグルスイッチ)がオンの時、「00」とし、オフの時、「99」とします。
 カウント間隔(表示):1秒(システムクロックから発生させます)
 SW1:カウント方向の指示 →オンの時、カウントアップします。オフの時、カウントダウンします。
 SW2(プッシュスイッチ):カウント動作停止 →プッシュ(オン)時、カウント停止します。
 SW3(透過センサー):カウント動作開始 →遮光(オフ)時、カウント開始する。


■接続
制御対象回路 CPUボード:RY3048Fone
CN1     →      J2
CN2     →      J3
                   J1      →      トグルスイッチ、プッシュスイッチ、透過センサー


■開発環境
ルネサスエレクトロニクス社 High-performance Embedded Workshop を使います。
最新版をルネサスエレクトロニクス社のホームページよりダウンロードしてセットアップしてください。

注:このプロジェクトでは、「H8S,H8/300 Standard Toolchain...」(「ビルド」メニューから起動)の設定を変更している。「標準ライブラリ」の「モード」をデフォルト設定の「ライブラリファイル指定なし」から、「ライブラリファイル作成(常に)」に設定した。そうしないと下記リンクエラーが発生する。
L2310 (E) Undefined external symbol "$sp_regsv$3" referenced in "C:\sakaki\・・\demo02.obj"
L2310 (E) Undefined external symbol "$spregld2$3" referenced in "C:\sakaki\・・\demo03.obj"
Optimizing Linkage Editor Abort
→この対応で一度、ライブラリファイルが作成されると、その後、以前の「ライブラリファイル指定なし」に戻してもリンクエラーは発生しなくなった。理由は、不明。しかし、今後の事が心配である為、「ライブラリファイル指定なし」には戻さない。


■準備-その1
ヘッダファイルを用意します。
ファイル名:ry3048fone.h
フォルダー:自分の開発環境に合わせる。

ヘッダファイルの内容は、次の通り。
---この次から---

void InitializeIO(void);
int GetSW1(void);
int GetSW2(void);
int GetSW3(void);
void Wait1msec(void);
void WaitMsec(int msec);


#define COUNT_START    1
#define COUNT_STOP     0

#define LED_AL_OFF     0xff
#define LED_AL_ON      0x00

#define OE_ENABLE      0
#define OE_DISABLE     1
#define FET_ENABLE     1
#define FET_DISABLE    0

#define LED7SEG_ALL    PA.DR.BYTE
#define OE_7SEG        PB.DR.BIT.B7
#define OE_LED         PB.DR.BIT.B6
#define A              0x01
#define B              0x02
#define C              0x04
#define D              0x08
#define E              0x10
#define F              0x20
#define G              0x40

#define SW1            P7.DR.BIT.B1
#define SW2            P7.DR.BIT.B3
#define SW3            P7.DR.BIT.B5
#define SW_ON          0
#define SW_OFF         1

#define True           1
#define False          0

const char LEDSegData[10] = {
    ~(A+B+C+D+E+F),
    ~(B+C),
    ~(A+B+G+E+D),
    ~(A+B+G+C+D),
    ~(F+G+B+C),
    ~(A+F+G+C+D),
    ~(A+F+G+C+D+E),
    ~(A+B+C),
    ~(A+B+C+D+E+F+G),
    ~(A+B+C+D+F+G) };


void InitializeIO(void)
{
    /* 入出力端子の定義 */
    PA.DR.BYTE = 0;
    PA.DDR     = 0xff;
    PA.DR.BYTE = LED_AL_OFF;
    PB.DR.BYTE = 0;
    PB.DDR     = 0xff;

    /* タイマーの定義 */
    ITU1.TCR.BYTE     = 0x23;
    ITU1.GRA          = 0x0c00;
    ITU.TSTR.BIT.STR1 = COUNT_START;
}


void Wait1msec(void)
{
    for(;;){
        if( ITU1.TSR.BIT.IMFA != 0 ) break;
    }
    ITU1.TSR.BIT.IMFA = 0;
}


void WaitMsec(int msec)
{
    int iCnt;

    if( msec < 0 ) return;
    for( iCnt = 0 ; iCnt < msec ; iCnt++ ) Wait1msec();
}


int GetSW1(void)
{
    return( SW1 );
}


int GetSW2(void)
{
    return( SW2 );
}


int GetSW3(void)
{
    return( SW3 );
}


---この前まで---


■準備-その2
サンプル用のスタータプログラム(アセンブラ)を用意します。
ファイル名:demo03start.src
フォルダー:プロジェクト指定のフォルダー

---この次から---

        .CPU    300HA:20

STACK_BASE:     .EQU    H'FFFF10        ; スタック基底アドレス(モード7)

        .IMPORT _main                   ; 外部参照(main関数)

        .SECTION V                      ; H'000000
        .DATA.L RESET_START

        .SECTION P                      ; H'000100
RESET_START:
        MOV.L   #STACK_BASE,ER7         ; スタックの設定
        JSR     @_main                  ; C言語のmain()関数へジャンプ
OWARI:
        BRA     OWARI

        .END

---この前まで---

注:このファイル(拡張子が「src」)は、これまで作成してきた中に入っています。それをそのまま、ファイル名を変えて利用されても構いません。先に作成したファイル「demo01start.src」のファイル名称を「demo03start.src」変更して流用してもよいです。


■準備-その3
サンプル用のソースプログラムファイル(C言語)を用意します。
ファイル名:demo03.c
フォルダー:プロジェクト指定のフォルダー

---この次から---

#include "3048f.h"
#include "ry3048fone.h"

void main(void);

void main(void)
{
    /* ローカル変数の定義 */
    int Digit1st;
    int Digit2nd;
    int CountOfSeconds;
    int i;
    int CountEnable;


    /* 処理 */ 
    InitializeIO();
    OE_7SEG = OE_ENABLE;
    OE_LED = OE_DISABLE;
    if( GetSW1() == SW_ON ) CountOfSeconds = 0;
    else CountOfSeconds = 99;
    CountEnable = False;
    for(;;){
        Digit2nd = CountOfSeconds / 10;
        Digit1st = CountOfSeconds - ( Digit2nd * 10 );
        for( i = 0 ; i < 500 ; i++ ){
            if( GetSW2() == SW_ON ) CountEnable = False;
            if( GetSW3() == SW_OFF ) CountEnable = True;
            LED7SEG_ALL = LEDSegData[Digit2nd];
            LED7SEG_1 = FET_ENABLE;
            LED7SEG_2 = FET_DISABLE;
            Wait1msec();
            LED7SEG_ALL = LEDSegData[Digit1st];
            LED7SEG_1 = FET_DISABLE;
            LED7SEG_2 = FET_ENABLE;
            Wait1msec();
        }
        if( GetSW1() == SW_ON
         && CountEnable == True ){
            if( CountOfSeconds >= 99 ) CountOfSeconds = 0;
            else CountOfSeconds++;
        } else if( GetSW1() == SW_OFF
                && CountEnable == True ){
            if( CountOfSeconds <= 0 ) CountOfSeconds = 99;
            else CountOfSeconds--;
        }
    }
}


---この前まで---

注:時間「≒1000msec」について
この計算は、関数「Wait1msec()」を2つ、それを500回ループで回すので、(1msec+1msec)x500=1000msec となる。しかし、厳密には、同じループ内に合計6ステップのステートメントがあるので、その分の処理時間が加わる事になる。そういった意味合いで、「≒1000msec」となる。
 

ものづくりBLOG

Blog Category

Blog Calendar

RSS 2.0