メインプログラム:T_CONT.c

プロセッサーエキスパート(PE)で設定した結果、下図の様なソースファイルが生成されます。初期設定は全て完了していますのでMAIN関数の含まれているT_CONT.cのみを記述します。

【宣言部】
Types definition
今まで使っていたchar型やint型などのデータ型をunsibned intと書くのは長いのでwordとする宣言文です。
MAS_CON:マスコンVRをAD変換した結果を格納するレジスタです。
SPEED:モーターの回転数を制御するレジスタです。
BREAK_CON:ブレーキVRをAD変換した結果を格納するレジスタです。
PRESSURE:圧力計サーボの指示値レジスタです。
ATCPOS: ATCセンサー番号レジスタです。
ATCFLG: ATCモードフラグです。
STOPFLG:停止可能フラグです。

/* Types definition */
typedef unsigned char byte;
typedef unsigned int word;
typedef unsigned long dword;
typedef unsigned long dlong[2];

/***** 宣言部 *****/
word MAS_CON;   // マスコンレバーの位置レジスタ
word SPEED;     // 電車の現在速度レジスタ
word BREAK_CON; // ブレーキレバーの位置レジスタ
word BREAK;    // 電車の現在のブレーキレジスタ
word PRESSURE; // 圧力計値レジスタ
byte ATCPOS;   // ATCセンサー番号レジスタ
byte ATCFLG;   // ATCモードフラグ
byte STOPFLG;  // 停止可能フラグ


【ATC割込み関数】
PORTBの立下りで割込みが発生すると、この関数が呼び出されます。割込みフラグをクリアして、どのポートが原因かでATCPOS(ATCポジション)を設定します。

//*********************************************************
//* ATC割込み関数
//*********************************************************
ISR(ATC) // PTB割込み処理
{
  PTBSC_PTBACK = 1; // 割込みフラグのクリア
  if(PTBD_PTBD0 == 0) ATCPOS = 1; // センサー1
  if(PTBD_PTBD1 == 0) ATCPOS = 2; // センサー2
  if(PTBD_PTBD2 == 0) ATCPOS = 3; // センサー3
}

【ATC運転関数】
関数名はATCMODEです。この関数はATC運転の処理を行います。
SPEEDもBREAK_CONもMAS_CONも0〜1023の可変範囲です。これらをプログラムで制御します。まずSPEEDが300以上の場合はBREAK_CONを800として速度を落とします。
SPEEDが300以下になったらブレーキを解除し、マスコンを140に設定します。電車は慣性走行を行いながら徐々に速度が低下し、SPEEDが140になった時点で定速度走行となります。
SPEEDが300以下でセンサー1が検出されるとATCPOSは1となり、SPEEDは徐行運転速度の120となり、停止可能フラグをセットしてATCPOSが2になるまで維持されます。
停止可能フラグが1でセンサー2が検出されるとATCPOSは2となり、SPEEDを0として停止します。ATCPOSが2でSPEEDが0の状態は乗降待ちとなり5秒間停車した後、自動運転終了のため、ATCフラグとATCPOSをクリアします。停止可能フラグが0の場合はそのまま通過して次の駅のセンサーまで走行が維持されます。

//*********************************************************
//* ATC運転関数
//*********************************************************
void ATCMODE(void)
{
  int i;
/***** 速度300以上 *****/
  if(SPEED >=300)
  {
    BREAK_CON = 800;  // ブレーキを800
    MAS_CON = 140;   // マスコンを140(徐行)
  }
/***** 速度300以下 *****/
  if(SPEED < 300)
  {
    BREAK_CON = 100; // ブレーキ解除
  }
/***** センサー1検出(速度300以下) *****/
  if(ATCPOS == 1 & SPEED <= 300)
  {
    SPEED = 120;       // 徐行運転
    BREAK_CON = 100;   // ブレーキ解除
    ATCPOS = 0;       // センサー番号レジスタをクリア
    STOPFLG = 1;      // 停止可能フラグをセット
  }
/***** 乗降待ち *****/
  if(ATCPOS == 2 & SPEED == 0)
  {
    for(i=1;i<6;i++)
    {
      Cpu_Delay100US(10000);
    }
/***** 自動運転終了 *****/
    ATCFLG = 0;     // 自動運転フラグをクリア
    ATCPOS = 0;     // センサー番号フラグをクリア
  }
/***** センサー2検出(停止可能) *****/
  if(ATCPOS == 2 & STOPFLG)
  {
    MAS_CON = 0;    // マスコンを停止位置に設定
    SPEED = 0;      // 停止
    STOPFLG = 0;    // 停止可能フラグクリア
  }
}

【初期設定】
TRIM設定はお馴染みの内臓クロックトリムの設定です。初期設定はポートB割込み用の設定です。

//*********************************************************
//* メイン関数
//*********************************************************
void main(void)
{
/* Write your local variable definition here */

/*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
  PE_low_level_init();
/*** End of Processor Expert internal initialization. ***/

/* Write your code here */
/* For example: for(;;) { } */
//*********************************************************
//* 初期設定
//*********************************************************

/***** TRIM設定 *****/
  ICSTRM = 0x9E;
  ICSSC_FTRIM = 1;

/***** 初期設定 *****/
  PTBPS = 7;        // PORTB0〜PORT2を割込み要因に設定
  PTBES = 0;        // 立下りで割込み発生に設定
  PTBSC_PTBMOD = 0; // 割込みはエッジのみ検出に設定
  PTBSC_PTBIE = 1;   // 割込み許可
  ATCPOS = 0;      // ATCセンサー番号レジスタをクリア

【メインループ】
ATC自動運転スイッチが押されているかチェックし、押されていればATCFLG(ATCフラグ)を反転します。次にATCフラグにより手動運転かATC運転かに分岐します。ATCフラグが1ならばATC運転関数にジャンプします。
モーター制御PWMの可変幅は0〜20000、SPEEDレジスタの値は0〜1023なのでSPEEDレジスタの値を20倍してモーター制御PWMのパルス幅を可変します。
手動運転の時はマスコンとブレーキのボリュームをAD変換します。
SPEEDに対してMAS_CONが大きいとSPEEDをインクリメントして加速します。MAS_CONがSPEEDより小さい時はSPEEDからBREAKの値を減算して減速します。BREAKは最低値が1なのでブレーキをかけなくても徐々に減速します。(慣性走行)BREAKの値が大きいとそれだけ減速率が上がり早く速度が低下します。
圧力計表示はBREAK_CONの可変範囲0から1023をサーボの動作範囲2.375mS〜1.53mSに変換して出力しています。サーボにより可変できる範囲が違いますので注意してください。
速度計表示はSPEEDの可変歯に0〜1023をサーボの動作範囲2.375mS〜0.67mSに変換して出力しています。
ブレーキのAD変換する時に100を加算するのは、AD変換値が100を超えるまでBREAK値が慣性走行時と同じ1になってしまうのでブレーキを操作しても速度が低下しない事を防いでいます。
ボリューム値のオフセットと思えば良いでしょう。

//*********************************************************
//* メインループ
//*********************************************************
  for(;;)
  {
/***** 自動運転スイッチチェック *****/
    if(PTBD_PTBD6 == 0)
    {
      Cpu_Delay100US(100);
      if(PTBD_PTBD6 == 0) ATCFLG = !ATCFLG;
      while(!PTBD_PTBD6){}
    }
/***** ATC運転/手動運転分岐 *****/
    if(ATCFLG == 1)
    {
      ATCMODE(); // 自動運転
    }
    else
    {
/***** 手動運転 *****/
      STOPFLG = 0; // 停止可能フラグクリア
      ATCPOS = 0; // センサー番号レジスタクリア
      ADCSC1 = 11; // AD変換スタート
      while (!ADCSC1_COCO); // AD変換終了待ち
      MAS_CON = ADCR; // 変換値をレジスタに格納
      Cpu_Delay100US(10);
      ADCSC1 = 10; // AD変換スタート
      while (!ADCSC1_COCO); // AD変換終了待ち
      BREAK_CON = ADCR + 100; // 変換値にOFFSETを付けてレジスタに格納
    }

/***** 圧力計制御 *****/
    PRESSURE = 9500-BREAK_CON*6; // 2.375mS〜1.53mS
    TPM1C1V = PRESSURE; //
    BREAK = (BREAK_CON / 100); // BREAK=1〜11
/***** 速度制御 *****/
    if(MAS_CON>SPEED) //
    {
      Cpu_Delay100US(200);
      SPEED = SPEED + 1; // 加速
    }
    else
    {
      if(SPEED) // 速度が0でない
      {
        if(SPEED > BREAK) // 速度がブレーキより大きい
        {
          SPEED = SPEED - BREAK; // 減速
        }
        else // 速度がブレーキより小さい
        {
          SPEED = 0; // 停止
        }
        Cpu_Delay100US(1000);
      }
    }
/***** 速度計制御 *****/
    if(SPEED > 50)
    {
      TPM1C0V = 9500 - ((SPEED - 50) * 7); // 2.375mS〜0.67mS
    }
    else
    {
      TPM1C0V = 9500;
    }
/***** 線路出力電圧制御 *****/
    if(PTBD_PTBD7) // 進行方向スイッチ
    { //
      TPM2C1V = 0; // SPEED 比 タイマー値
      Cpu_Delay100US(1); // 停止 = 0 0% 0
      TPM2C0V = SPEED * 20; // 全速 = 1023 100% 20000
    }
    else
    {
      TPM2C0V = 0;
      Cpu_Delay100US(1);
      TPM2C1V = SPEED * 20;
    }
  }
/*** Don't write any code pass this line, or it will be deleted during code generation. ***/
/*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
  for(;;){}
/*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/
} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/

/* END T_CONT */

TOP BACK NEXT