C言語

メイン処理の実装

メイン処理では、10ms周期毎に、ウォッチドッグタイマクリアと、赤外線リモコン受信データ解析処理、モータ制御処理、スリープ制御を行います。

メインの処理の流れ

メイン処理は、無限ループです。このメイン処理の前に全モジュールの初期化と、タイマ関連を開始します。

メイン処理では、次のような流れで処理します。

  • ウォッチドッグタイマクリア
  • 受信完了フラグ取得
  • 受信継続フラグ取得
  • 受信完了フラグがONの場合は、5~8を実行し、OFFの場合は、9以降を実行する
  • 受信完了フラグをクリア
  • スリープカウンタをクリア
  • 赤外線リモコン受信データ解析処理を呼び出し、実行結果をセットする
  • 実行結果のボタン種別により、各ボタンに応じたモータ制御処理を呼び出し、16へ遷移する
  • 受信継続してない場合は、モータ制御の停止処理を呼び出す
  • スリープカウンタをインクリメント
  • スリープカウンタが30s経過した場合は、12~15を実行し、経過していない場合は16以降を実行する
  • タイマ制御スリープ処理を呼び出し、タイマを停止する
  • 赤外線リモコン受信制御のスリープ処理を呼び出す
  • HALTモードに移行する
  • HALTモード復帰後はメイン周期タイマを再開する
  • メイン周期フラグ取得
  • メイン周期フラグがONしていない場合(10ms経過していない場合)は、ONするまで(10ms経過するまで)ループさせ、1へ遷移させない。
  • メイン周期フラグがONになったら、1へ遷移する

簡単ではありますが、処理の流れとしては以上となります。

メイン処理の実装

実際の実装の内容については次のようになります。

#include "common.h"
#include "AppRcvDataAls.h"
#include "DrRcvCtrl.h"
#include "DrMotorCtrl.h"
#include "DrWdtCtrl.h"
#include "DrTimerCtrl.h"

static void S_AppMain_AllInit( void );

#define U2S_APPMAIN_SLEEP_TIMEUP        ((U2)(3000U))

static U2 u2s_AppMain_SleepCnt;

void AppMain(void)
{
    U1 u1l_RcvFixFlg;
    U1 u1l_MainCycleFlg;
	  U1 u1l_RcvCntinuFlg;
    U4 u4l_BottomKind;

    S_AppMain_AllInit();
    EI();

    while( 1 )
    {
        G_DrWdtCtrl_WdtTimClr();
        u1l_RcvFixFlg = U1G_DrRcvCtrl_GetRcvFinFlg();
        u1l_RcvCntinuFlg = U1G_DrRcvCtrl_GetRcvCntinuFlg();

        if( u1l_RcvFixFlg == U1_ON )
        {
            G_DrRcvCtrl_ClrRcvFinFlg();
            u2s_AppMain_SleepCnt = U2_CLR;
            u4l_BottomKind = U4G_AppRcvDataAls_Main();

            switch( u4l_BottomKind )
            {
            case U4G_APPRCVDATAALS_BTM_FOW:
                G_DrMotorCtrl_Forward();
                break;
            case U4G_APPRCVDATAALS_BTM_BCK:
                G_DrMotorCtrl_Back();
                break;
            case U4G_APPRCVDATAALS_BTM_RGT:
                G_DrMotorCtrl_Right();
                break;
            case U4G_APPRCVDATAALS_BTM_LFT:
                G_DrMotorCtrl_Left();
                break;
            default:
                G_DrMotorCtrl_Stop();
                break;
            }
        }
        else
        {
            if( u1l_RcvCntinuFlg != U1_ON )
            {
                G_DrMotorCtrl_Stop();
            }
            u2s_AppMain_SleepCnt++;

            if( u2s_AppMain_SleepCnt >= U2S_APPMAIN_SLEEP_TIMEUP )
            {
                G_DrTimerCtrl_Sleep();
                G_DrRcvCtrl_Sleep();
                halt();
                G_DrTimerCtrl_MainCycleStart();
            }
        }

        u1l_MainCycleFlg = U1G_DrTimerCtrl_GetMainCycleFlg();
        while( u1l_MainCycleFlg != U1_ON )
        {
            u1l_MainCycleFlg = U1G_DrTimerCtrl_GetMainCycleFlg();
        }
        G_DrTimerCtrl_ClrMainCycleFlg();
    }
}

static void S_AppMain_AllInit( void )
{
    G_DrRcvCtrl_Init();
    G_DrTimerCtrl_MainCycleStart();
    G_DrRcvCtrl_Start();
}

S_AppMain_AllInit関数で、各モジュールで作成した初期化処理を呼び出します。
このS_AppMain_AllInit関数を実行後、AppMain関数に戻った後、EI関数を実行しています。
これは、割り込み許可にする命令です。基本的にRL78マイコンの起動時は割り込み禁止となっています。このため、どこかのタイミングで明示的に割り込み許可にしないと、割り込み機能のレジスタを割り込み許可にしても、割り込みを行わないので、今回は、割り込みを使用するタイマの開始直後にEI関数を実行しています。

その他は、処理の流れで説明した通り、実装しているつもりです。

簡単ではありますが、メイン処理の実装の実装については以上となります。

-C言語