2

こんにちは、StackOverflow!

次のコードには、外部照明デバイスの動作を変更する単純なステート マシンがあります (コメントが示すように)。状態は、GP1 に接続されたボタンを押すことによって変更されます。GP1 に接続されている回路は、VDD を 0.6VDD と比較するコンパレータ デバウンシング回路であり (RC/ダイオード/シュミット トリガ回路も試しました)、信号を強制的に LO にします。ボタンをすばやく押すと、スコープ上にきれいな方形波が表示されます。

PIC10F200現在の (そして望ましくない)動作は次のとおりです。

  1. スイッチが押されている (状態 = 0)
  2. ステート マシン変数のインクリメント (状態 = 1)
  3. 照明はケース 1 に進み、オンになります
  4. 照明が 1 秒以上点灯している
  5. 照明が消える
  6. ボタンが再び作動するか、電源がオフになるまで、システムはこの状態を維持します

問題は、なぜこのように振る舞うのかということです。また、可能であれば、ボタンを 1 回押すだけで状態が 1 つ増えるように修正するにはどうすればよいでしょうか。システムの電源が入っていて、ボタンが再び作動しない限り、PIC はそれを維持しますか?

#define SYS_FREQ        8000000L
#define FCY             SYS_FREQ/4
#define _XTAL_FREQ      4000000

/******************************************************************************/
/* User Global Variable Declaration                                           */
/******************************************************************************/


/******************************************************************************/
/* Main Program                                                               */
/******************************************************************************/

__CONFIG(MCLRE_ON & CP_OFF & OSC_IntRC);

void main(void)
{
    TRIS = 0b111110;

    unsigned char state = 0;

    while(1)
    {
        switch (state)
        {
            case 0: // IDLE/OFF
                if (GPIObits.GP0) GPIObits.GP0 = 0;
                break;
            case 1: // ON
                if (!GPIObits.GP0) GPIObits.GP0 = 1;
                break;
            case 2: // BLINK (slow)
                GPIObits.GP0 = !GPIObits.GP0;
                __delay_ms(100);
                break;
            case 3: // BLINK (fast)
                GPIObits.GP0 = !GPIObits.GP0;
                __delay_ms(50);
                break;
            case 4: // BEAT DETECT
                GPIObits.GP0 = GPIObits.GP2;
                break;
            default:
                state = 0;
                break;
        }

        if (!GPIObits.GP1)
        {
            __delay_ms(250);
            state++;
        }
    }
}

更新: このコード/システムで何を達成しようとしているのかについて少し混乱しているように見えるので、完全なコンテキストを提供しましょう。このマイクロコントローラであるPIC10F200は、エレクトロルミネセンス (EL) ワイヤ ドライバの全体的なボード設計の一部です。マイコンコントローラは、ドライバICのポートに接続することで、ドライバ回路を有効にするかどうかを制御するだけです。システムには 4 つの動作モードがあり、ワイヤは常時オン、ワイヤは点滅、ワイヤは高速で点滅、低周波ビートが検出されるたびにワイヤが点滅します (システム内の別の回路)。GP0ENこれらの動作モードからの移行は、PCB に取り付けられる押しボタン (一時的にオン) スイッチによって制御されます。これstateには、上記のコードで、ボタン操作間で安定した状態を維持することが必要です。現在、これは行われておらず、この投稿の元の部分で説明されているように動作します。質問のタイトルが示すように、現在安定していないのはなぜstateですか?どうすれば安定しますか?

更新 (2014-03-08): 解決策

GP0 が出力で、GP2 が T0CKI で、作動時に信号を LO に駆動するスイッチがあると仮定して、次の設定を行う必要があります。

TRIS = 0b111110;
OPTION = 0b11101111;

OPTION のビット 0 ~ 3 が本当に重要かどうかは、判断の呼び出しであり、WDT モジュールの使用を選択するかどうかです。

さらに、ボタン リリース検出の実装は、カウント中の任意の時点で GP2 が LO になるとリセットする単純なカウンター メカニズムです。

if (TMR0 > 0)
{
    while (count < 20)
    {
        if (!GPIObits.GP2) count = 0;
        __delay_ms(10);
        count++;
    }
    TMR0 = 0;
    state++;
}
4

3 に答える 3

2

ハードウェア/ソフトウェアの設計に問題があります!

  1. プログラムが遅延ループにある場合、キー ボタンはチェックされません。
  2. キー プレス イベントのみをチェックしていますが、キー リリースもチェックする必要があります。

私の目的は、GP1 の代わりに GP2 (T0CKI) ピンをキー ボタンに使用できるようにすることです。カウンタ TMR0 入力として使用する場合、このピンはシュミット トリガ入力になります。その後、MCPU TMR0 を GP2 (T0CKI) ピンの外部クロックを使用するカウンターとして構成します。また、T0SE ビットを設定して、T0CKI ピンのハイからローへの遷移でインクリメントするカウンターを設定する必要があります。ループ後のプログラムで、0 より大きいキーが押された場合は TMR0 の内容を確認します。数ミリ秒待って、キーが解放されたかどうかを確認し、変数を増やしてstateTMR0 の内容をクリアします。

于 2014-03-06T09:15:27.797 に答える
0

あなたの移動

if (!GPIObits.GP1){
    if(isPressed == false){
        //__delay_ms(250); //you dont need the delay
        state++;
        if(state == 5){state = 0;}
        isPressed = true;
    }
}
else{isPressed = false;}

switch声明の前に。ループchar isPressed = false;の前にwhile

ヴァルター

于 2014-03-05T20:24:29.287 に答える