モールス出力 8チャネル版  2006.04.11



・ はじめに
 
モールス出力(1チャネル) を、8チャネルへ拡張したものです。チャネル数が増えた以外、基本的には1チャネルのものと変わりません。( #define MORSE_CH_N の部分を変更すれば、1〜8の任意のチャネル数で動作します)

・ 起動/停止
 
複数チャネルになったので、起動/停止関数へ「チャネル番号(0〜7)の指定」が追加されました。
  MorseON(ch, TabelTopAdr);     // 起動
  MoseOFF(ch);                  // 停止
これだけです。

・ 内部の動作
 
ワーク

1チャネル時と同じ物を8チャネルへ拡張しました。モールス出力は、直接ドライバを呼ぶのではなく、出力チャネルのON/OFFをフラグにセットする形式になりましたので、出力フラグ MorseO が追加になっています。(ドライバは後でまとめて呼びます)
  #define MORSE_CH_N  8   // モールス出力チャネル数 0 - 8(max)
  struct morse_wk {
      byte    *tbladr;    // モールス出力用 テーブルアドレス
      byte    *tblp;      // モールス出力用 テーブル読出ポインタ
      byte    rect;       // モールス出力用 繰返しカウンタ
      byte    onct;       // モールス出力用 ON 時間カウンタ
      byte    offct;      // モールス出力用 OFF
  } ;
  union morse_out {       // モールス出力レベル(ON/OFF)
      byte    out;
      struct  {
          byte ch7 : 1 ;
          byte ch6 : 1 ;
          byte ch5 : 1 ;
          byte ch4 : 1 ;
          byte ch3 : 1 ;
          byte ch2 : 1 ;
          byte ch1 : 1 ;
          byte ch0 : 1 ;
      } ch ;
  };
  struct  morse_wk    MorseW[MORSE_CH_N];
  union   morse_out   MorseO;
起動関数

引数へ(操作対象の)チャネル番号が追加になっています。他は1チャネル時と同じです。
  void  MorseON(byte ch, byte *tbl_adr)
  {
      if (ch > MORSE_CH_N -1) return;
      InterruptSave();            // CCR 保存、割込禁止
      MorseW[ch].onct   = 0;
      MorseW[ch].offct  = 0;
      MorseW[ch].tbladr = tbl_adr;
      InterruptLoad();            // CCR 復帰(割込フラグも)
  }
停止関数

引数へ(操作対象の)チャネル番号が追加になっています。他は1チャネル時と同じです。
  void  MorseOFF(byte ch)
  {
      if (ch > MORSE_CH_N -1) return;
      MorseW[ch].tbladr = 0;
      MorseO.out &= ~(0x01 << ch);        // 出力フラグ
      MorseDrv();                         // ポート駆動
  }
本体関数  ( 10mS 毎に駆動されます)

チャネル数が増えた部分以外は1チャネル時と変わりません。
  void  Morse(void)
  {
      byte    ch;
    for (ch=0; ch < MORSE_CH_N; ch++) {
      if (MorseW[ch].tbladr == 0) {       // 出力停止中?
          MorseO.out &= ~(0x01 << ch);    // 出力OFF
          continue;
      }
                                          // -----------------------------------
      if (MorseW[ch].onct != 0) {         // ON時間カウント中?
                                          // -----------------------------------
          if (--MorseW[ch].onct == 0) {       // ON時間カウントアップなら
              MorseO.out &= ~(0x01 << ch);            // 出力OFF
              MorseW[ch].offct = *(MorseW[ch].tblp++);// OFF時間セット
          } else {
              MorseO.out |= 0x01 << ch;               // 出力ON
          }
                                          // -----------------------------------
      } else if (MorseW[ch].offct != 0) { // OFF時間カウント中?
                                          // -----------------------------------
          if (--MorseW[ch].offct == 0) {      // OFF時間カウントアップなら
              MorseW[ch].onct = *(MorseW[ch].tblp++); // ON時間セット
              if (MorseW[ch].onct == 0) {             // テーブルエンドなら
                  if (MorseW[ch].rect != 0) {         // 無限繰返しではなくて
                      if (--MorseW[ch].rect == 0) {   // 繰返し回数終了なら
                          MorseW[ch].tbladr = 0;      // 出力停止
                          MorseO.out &= ~(0x01 << ch);// 出力OFF
                          continue;
                      } else {
                          startMorse(ch);     // テーブルTopから再動作開始
                      }
                  } else {
                      startMorse(ch);         // テーブルTopから再動作開始
                  }
              }
              MorseO.out |= 0x01 << ch;       // 出力ON
          } else {
              MorseO.out &= ~(0x01 << ch);    // 出力OFF
          }
                                          // -----------------------------------
      } else {                            // 新規出力開始(今までは停止中だった)
                                          // -----------------------------------
          MorseW[ch].rect = *MorseW[ch].tbladr;   // 繰返し回数
          startMorse(ch);                     // テーブルTopから新規動作開始
      }
    }
  }
                                          // ------------------------------------
                                          // テーブルTopから動作開始
                                          // ------------------------------------
  void  startMorse(byte ch)
  {
      MorseW[ch].tblp = MorseW[ch].tbladr +1;     // テーブル読み出しP
      MorseW[ch].onct = *(MorseW[ch].tblp++);     // ON時間
      MorseO.out |= 0x01 << ch;                   // 出力ON
  }
・ ポート駆動
 
チャネル0から7までを順にドライブします。本体関数 Morse() に続いて呼びます。
  void  MorseDrv()
  {
      MorseCH0drv(MorseO.ch.ch0);  if (MORSE_CH_N < 2) return;
      MorseCH1drv(MorseO.ch.ch1);  if (MORSE_CH_N < 3) return;
      MorseCH2drv(MorseO.ch.ch2);  if (MORSE_CH_N < 4) return;
      MorseCH3drv(MorseO.ch.ch3);  if (MORSE_CH_N < 5) return;
      MorseCH4drv(MorseO.ch.ch4);  if (MORSE_CH_N < 6) return;
      MorseCH5drv(MorseO.ch.ch5);  if (MORSE_CH_N < 7) return;
      MorseCH6drv(MorseO.ch.ch6);  if (MORSE_CH_N < 8) return;
      MorseCH7drv(MorseO.ch.ch7);
  }
  void  MorseCH0drv(byte out)
  {
      if (out != 0)   P50 = 0;
      else            P50 = 1;
  }
  void  MorseCH1drv(byte out)
  {
      if (out != 0)   P51 = 0;
      else            P51 = 1;
  }
  void  MorseCH2drv(byte out)
  {
      if (out != 0)   P52 = 0;
      else            P52 = 1;
  }
  void  MorseCH3drv(byte out)
  {
      if (out != 0)   P53 = 0;
      else            P53 = 1;
  }
  void  MorseCH4drv(byte out)
  {
      if (out != 0)   P54 = 0;
      else            P54 = 1;
  }
  void  MorseCH5drv(byte out)
  {
      if (out != 0)   P55 = 0;
      else            P55 = 1;
  }
  void  MorseCH6drv(byte out)
  {
      if (out != 0)   P56 = 0;
      else            P56 = 1;
  }
  void  MorseCH7drv(byte out)
  {
      if (out != 0)   P57 = 0;
      else            P57 = 1;
  }

・ テスト用のプログラムソース  Morse8.lzh (9.4KB 2007.07.12)
 
簡単にテストするためのものです。H8/3694(3664)で動作します。
ポート5(全ビット)をモールス出力に、P85を10mS毎の反転出力に割当てています。
(これらのポートが既に使用中ならソフトの変更で空きポートへ振ってください)
他のポートには何もしていませんので、空きポートがあれば処理をお願いします。

・ 修正
 
2007.07.12 エエカゲンな書き方をしていたポインタ操作部分を修正しました。


Top      戻る