0

uC/OS-III を実行している NXP LPC1857 でスムーズに動作する LED の PWM 信号を取得するのに問題があります。1 ミリ秒で実行されている OS システムスティックを無効にした場合にのみ、定期的に発生するちらつきが停止します。

各色 (赤、緑、青) 用に 1 つ、全期間用に 1 つ、計 4 つのマッチ レジスタを使用してタイマーを設定しました。最初の 3 つの一致出力は、各色の物理出力ピンをクリアしています。最後のピリオドが一致すると、次のピリオドの 3 つのカラー出力すべてを設定するための割り込みが生成されます。

割り込みの周りに次のコードを追加して、timer0 割り込み中に OS からの割り込みを無効にしようとしました。

void TIMER0_IRQHandler(void)
{
    CPU_SR_ALLOC();
    OS_CRITICAL_ENTER();
    OSIntEnter();
    if (Chip_TIMER_MatchPending(PWM_TIMER, PWM_RED))
    {
        Chip_TIMER_ClearMatch(PWM_TIMER, PWM_RED);
        PWM_TIMER->EMR &= ~(((uint32_t) 0x01) << PWM_RED);
    }
    if (Chip_TIMER_MatchPending(PWM_TIMER, PWM_GREEN))
    {
        Chip_TIMER_ClearMatch(PWM_TIMER, PWM_GREEN);
        PWM_TIMER->EMR &= ~(((uint32_t) 0x01) << PWM_GREEN);
    }
    if (Chip_TIMER_MatchPending(PWM_TIMER, PWM_BLUE))
    {
        Chip_TIMER_ClearMatch(PWM_TIMER, PWM_BLUE);
        PWM_TIMER->EMR &= ~(((uint32_t) 0x01) << PWM_BLUE);
    }
    if (Chip_TIMER_MatchPending(PWM_TIMER, PWM_MATCH))
    {
        Chip_TIMER_ClearMatch(PWM_TIMER, PWM_MATCH);
        PWM_TIMER->EMR |= (((uint32_t) 0x01) << PWM_RED);
        PWM_TIMER->EMR |= (((uint32_t) 0x01) << PWM_GREEN);
        PWM_TIMER->EMR |= (((uint32_t) 0x01) << PWM_BLUE);
    }
    OS_CRITICAL_EXIT();
    OSIntExit();
}

システムスティックが PWM 信号のちらつきを引き起こす理由を知っている人はいますか?

4

2 に答える 2

0

OS_CRITICAL_ENTER() および OS_CRITICAL_EXIT() を使用しないでください。代わりに、CPU_CRITICAL() と CPU_CRITICAL_EXIT() を使用して、クリティカル セクション中の割り込みを無効にする必要があります。

また、この ISR はタスクを通知しないため、OSIntEnter() および OSIntExit() を呼び出す必要はありません。あなたのコードは次のようにすべきだと思います:

void TIMER0_IRQHandler(void)
{
    if (Chip_TIMER_MatchPending(PWM_TIMER, PWM_RED))
    {
        Chip_TIMER_ClearMatch(PWM_TIMER, PWM_RED);
        PWM_TIMER->EMR &= ~(((uint32_t) 0x01) << PWM_RED);
    }
    if (Chip_TIMER_MatchPending(PWM_TIMER, PWM_GREEN))
    {
        Chip_TIMER_ClearMatch(PWM_TIMER, PWM_GREEN);
        PWM_TIMER->EMR &= ~(((uint32_t) 0x01) << PWM_GREEN);
    }
    if (Chip_TIMER_MatchPending(PWM_TIMER, PWM_BLUE))
    {
        Chip_TIMER_ClearMatch(PWM_TIMER, PWM_BLUE);
        PWM_TIMER->EMR &= ~(((uint32_t) 0x01) << PWM_BLUE);
    }
    if (Chip_TIMER_MatchPending(PWM_TIMER, PWM_MATCH))
    {
        Chip_TIMER_ClearMatch(PWM_TIMER, PWM_MATCH);
        PWM_TIMER->EMR |= (((uint32_t) 0x01) << PWM_RED);
        PWM_TIMER->EMR |= (((uint32_t) 0x01) << PWM_GREEN);
        PWM_TIMER->EMR |= (((uint32_t) 0x01) << PWM_BLUE);
    }
}

ジャン

于 2016-04-29T13:56:04.767 に答える
0

理由は完全にはわかりませんが、最終的に解決策を見つけました:P.

PWMタスクを除いて、自分のタスクからOSを完全に取り除いた後も、問題は残っていました。そこで、タイマーコードに戻りました。

ちらつきを取り除くために追加しなければならなかった唯一のことは、周期割り込みを取得した後にタイマーをリセットすることでした。

年:

if (Chip_TIMER_MatchPending(PWM_TIMER, PWM_MATCH))
{
    Chip_TIMER_ClearMatch(PWM_TIMER, PWM_MATCH);
    PWM_TIMER->EMR |= (((uint32_t) 0x01) << PWM_RED);
    PWM_TIMER->EMR |= (((uint32_t) 0x01) << PWM_GREEN);
    PWM_TIMER->EMR |= (((uint32_t) 0x01) << PWM_BLUE);
}

新しい:

if (Chip_TIMER_MatchPending(PWM_TIMER, PWM_MATCH))
{
    Chip_TIMER_ClearMatch(PWM_TIMER, PWM_MATCH);
    PWM_TIMER->EMR |= (((uint32_t) 0x01) << PWM_RED);
    PWM_TIMER->EMR |= (((uint32_t) 0x01) << PWM_GREEN);
    PWM_TIMER->EMR |= (((uint32_t) 0x01) << PWM_BLUE);
    Chip_TIMER_Reset(PWM_TIMER);
}

誰かがこのリセットが必要な理由を説明できますか?

次の行がこれを処理することを期待していました(これは私の初期化ルーチンにあります):

Chip_TIMER_ResetOnMatchEnable(PWM_TIMER, PWM_MATCH);
于 2016-06-18T13:28:42.900 に答える