Top Page [◀◀]  2   3   4   5   6   7   8   9   ... [▶▶Last Page

8S2612Fのポート出力について

こんにちは、かもへいと申します。

どなたか、8Sのポート出力について詳しい方がいらっしゃれば、ご教授願いたく思います。

 故あって、2612のポート周りの出力を触っています。

TPU2で100us周期のカウンタ割り込みを作成して、P14、P16のポートにOFF/ON出力をしています。

P16は、5000カウントで500ms周期のOFF/ONが出来ているのですが、P14の出力は、P16の周期で三回(1500ms)に一度、800msほど

遅れてOFF出力されてしまいます。

その1ms後にはP14も正しくON出力されているので、OFFになるときに遅延が発生している状況です。

P16のOFF/ON周期がずれていないので、P14のOFFタイミングは、ロジック的に正しく叩いているはずなのですが・・・。

簡単な図で申し訳ありません。図の赤丸のように、ポート出力の遅れが出ています。

これが遅れなのか、タイマに起因するものなのかはわかりませんが、少なくとも、P16の500ms周期に遅れが出ていない

事と、P14の出力が遅れた場合でも、次の立ち上がり時間に影響が出ていないので、ポートの出力遅れかと推察して

います。

どうぞ、よろしくお願いいたします。

 

***** 追加情報です。本当は、最初に書くべきでした・・・ *****


ポートやタイマの設定部分を触らずに、メインの関数にデバッグ用のロジックを追加したり、変数を追加した
利すると、現象が起こらないROMが出来たりします。
さらに追加するとまた起こるようになったり、削除すると起こらなくなったりします。
起きなくなったROMでは、何度実行しても現象は発生しません。
ポート周辺のロジックを触らずに、別の割り込み関数の中に初期化処理やローカル変数を追加しても起こる
ような状況です。

何かやってはいけない禁則的なものか、おまじない的な何かが必要なんでしょうかね・・・。

  • わわいです
    800μsの遅れ、ですね
    まず、その100μsのタイマ割り込みでポートにパルスを出すようにして、その遅れるときにもきちんと100μsごとの割り込みがかかっているかを確認することですね

    ・きちんと割り込みがかかっている
     P14の駆動コードで遅れるようなコードが組んである
    ・遅れるときには割り込みかかっていない
     他に800μの時間がかかる割り込みがかかっているか、メインループで割り込みディセーブルにしてブロックしている
  • 素朴な疑問なのですが、ご相談の異常なケース以外でも P14 と P16 は同じポートの割に立ち上がり/立下りのタイミングが合っていませんが、別々に制御されてるということでしょうか?
  • In reply to fujita nozomu:

    かもへいさん
    タイマ割り込みでポートを駆動していたら、しょうがないです、タイマー出力端子からの出力であれば、タイマーを開始するタイミングが合っていないのでしょうか、同期動作等を検討する必要があるかも。
  • カウンタはどのタイミングでリセットしていますか。
     カウンタ出力は符号無しで、それを符号付きのインテジャーに読み込んでいるとか。
     その結果、プラスとマイナスが切り替る値付近でミスをしているとか。
  • In reply to わわい:

    Replyありがとうござます。

    >・きちんと割り込みがかかっている
    > P14の駆動コードで遅れるようなコードが組んである
    >・遅れるときには割り込みかかっていない
    > 他に800μの時間がかかる割り込みがかかっているか、メインループで割り込みディセーブルにして
    ブロックしている

    割り込みはかかっています。遅れるP14も、遅れないP16も、同じタイマ割り込みでカウンタを++して
    各周期を出していますが、P16の500ms周期は崩れないまま、P14だけが遅めにOFFされます。

    ちなみに、TPU2は他のTPUとは同期設定されておらず、各々単体でカウンタ動作をしています。
    あと、書き込みのところにも追記しますが、全く関係ないAD部分の割り込みでないロジックや、SPI通信
    のバッファ変数を使いしたり減らしたりすると、現象が起きなくなる場合もあります。
    その場合は、同じROMであれば全く発生しません。極端なことを言うと、変数を定義して、代入処理を
    追加しただけでも起きたりします。

    私の知識ではちょっとお手上げ状態です。
  • In reply to fujita nozomu:

    Replyありがとうございます。
    そうですね、別制御になります。

    P14とP16は、以下のような仕様です。

    ・PORT1、BIT4、BIT6を使用、P16で500ms周期のタイミングを出力、P14で500msの前後でポートを
     OFF、ONする。

    ・P14
     通常はOFF。P16の500ms開始から、1ms後にON、499ms後にOFFします。

    ・P16
     通常はOFF。500msごとに、最初の2ms間だけONして、以降498msはOFFにします。

    P14が、P16のONタイミングを挟んでOFF→ONする形になります。
  • In reply to IKUZO:

    Replyありがとうございます。

    100usタイマ割り込みの関数中では、

    ・100ms周期のフラグセット
    ・1msを測定するためのカウンタ++(&1ms周期のフラグセット&カウンタ0クリア処理)

    しかしていません。

    ポート駆動の処理は、各フラグがONの時に、メインで拾って処理後にOFFにしています。
    タイマ端子からの出力はしていません。
    1ms周期のフラグが立つごとにメインで変数をインクリメントして500ms周期を作成し、P1
    を使用してポート処理を行っています。
  • In reply to リカルド:

    Replyありがとうございます。

    ポート制御に使用しているカウンタは、unsignedの変数を使用しているので、符号による境界ミスの
    要素は現状ありませんでした。
    すべての変数において、カウンタがフローしないコードが組まれていることを確認しています。
    タイマのカウンタはTPUのコンペアマッチでアップカウンタ指示で行っていますので、分周に対しての
    固定カウンタ値までの++になります。こちらは±関係なさそうですよね。
  • In reply to かもへい:

    わわいです
    割り込みがちゃんとかかっている、ということであれば、そのポートを駆動しているコードにバグが有る、ということになろうかと思います。
    おそらく、タイマ割り込みの割り込み関数だと思われますが、そのコードを提示できるでしょうか。
  • In reply to かもへい:

    >ポート駆動の処理は、各フラグがONの時に、メインで拾って処理後にOFFにしています。
    >タイマ端子からの出力はしていません。
    >1ms周期のフラグが立つごとにメインで変数をインクリメントして500ms周期を作成し、P1
    >を使用してポート処理を行っています。

     これを読むと割り込み処理でグローバル変数に書き込み、メイン関数でその内容を読んでポートを操作しているように感じる。
     割り込み処理でポート出力の処理まで行わないのが原因かな。
  • かもへいさん、こんにちは。NoMaYと申します。

    実は、メインループというのは、以下のAのような単純なループではなくて、以下のBのような色々な処理が行われているのではないですか? (かもへいさんが書かれた割り込み関数の処理を擬似コードにするには少し考えないといけなさそうでしたので、とりあえず単純な処理でイメージしています。)

    A)

    volatile unsigned int tick = 0;

    void main(void)
    {
        初期化処理

        for(;;)
        {
            // まさにこれだけしかしていない、割り込みもTPU2の割り込みしか使っていない
            if (tick == 10)
            {
                P14のON
            }
            if (tick == 4990)
            {
                P14のOFF
            }
            if (tick == 0)
            {
                P16のON
            }
            if (tick == 20)
            {
                P16のOFF
            }
        }
    }

    void TPU2_interrupt(void)
    {
        tick++;
        if (tick == 5000)
        {
            tick = 0;
        }
    }

    B)

    volatile unsigned int tick = 0;

    void main(void)
    {
        初期化処理

        for(;;)
        {
            // 当然色々な処理をしている、割り込みもTPU2以外にバンバンと入る
            // でも大抵は1ms以内(というか数十μs程度以内?)にそれらの処理は完了する
            // でも1500msに1回だけ正にP14をOFFする直前に1800μs掛かる処理が発生しているとか??
            処理その1
            処理その2
            ...
            処理そのN-1
            処理そのN
            if (tick == 10)
            {
                P14のON
            }
            if (tick == 4990)
            {
                P14のOFF
            }
            if (tick == 0)
            {
                P16のON
            }
            if (tick == 20)
            {
                P16のOFF
            }
        }
    }

    void TPU2_interrupt(void)
    {
        tick++;
        if (tick == 5000)
        {
            tick = 0;
        }
    }

    void ABC_interrupt(void)
    {
        ...
    }
    ・・・
    void XYZ_interrupt(void)
    {
        ...
    }

     

  • かもへいさん、こんにちは。NoMaYです。

    その後、どうでしょうか? 原因の究明&問題の解決は出来ましたでしょうか?

  • In reply to NoMaY:

    mainループで追従式はどうしてもタイミングがズレたりしますよねー、正確なタイミングで出すには、優先順位の高い割り込み中で出力するか、逆に全部の割り込みを禁止にするか、ハードウェア機能で出力するしか手がないと思いますが、問題の現象はアドレスとかデータの受け渡しのタイミングがずれて起こるものでしょうから、ランダムに発生しているものが、波形に表示されているのだろうと思います。

  • In reply to わわい:

    わわいさん、こんにちは。

    すみません、コードは客先のベースソフトなので、一部変更か抜粋で提示できるかできないかのものなので、今回は申し訳ありません。
    ただ、この後書き込みをしていただいた、NoMaY さんのイメージコードがほぼそのままですので、参考になるかと思います。
    やはりタイマでしょうか・・・。もう少し探ってみます。
  • In reply to リカルド:

    リカルドさん、こんにちは。

    そうです。グローバルでタイマ割り込み→カウンタアップ→フラグ立て→メインにタイミング譲渡してポート操作です。割り込みで入れてやってみようと思います。
    (タイマ割り込み内はなるべく簡素に、というイメージでしたが、割り込み内でポート叩きとかありなんですね)

Top Page [◀◀]  2   3   4   5   6   7   8   9   ... [▶▶Last Page