1

私は Atmel SAM3x8E マイクロコントローラーを使用しており、ボタンを押したときに単純な LED 切り替えを実行しようとしています。プルアップ構成ボタンを使用して割り込みルーチンをトリガーしています。

これは、割り込みの初期化です。

// Set button pins as pull-up inputs 
pio_set_input(PIOC, BUTTON_1, PIO_PULLUP);
pio_set_input(PIOC, BUTTON_2, PIO_PULLUP); 

// Configure button input pin interrupt mode and handler (Rising Edge)
pio_handler_set(PIOC, ID_PIOC, BUTTON_1,  PIO_IT_RISE_EDGE, button_press_handler);
pio_handler_set(PIOC, ID_PIOC, BUTTON_2,  PIO_IT_RISE_EDGE, button_press_handler);

// Enable the interrupts
pio_enable_interrupt(PIOC, BUTTON_1); 
pio_enable_interrupt(PIOC, BUTTON_2); 
NVIC_EnableIRQ(PIOC_IRQn); 
NVIC_EnableIRQ(PIOC_IRQn); 

次に、これが割り込みルーチンです。

// Interrupt handler for button press
void button_press_handler(uint32_t a, uint32_t b)
{
   pio_toggle_pin_group(PIOC, BLUE_LED4); // NOT TOGGLING LED (ONLY TURNS IT ON)
}

しかし、実行すると、LED を切り替えることができません。それは単にオンになり、オンのままになります。pio_toggle_pin_group が呼び出す関数は次のとおりです。

 * \param p_pio Pointer to a PIO instance.
 * \param ul_mask Bitmask of one or more pin(s) to configure.
 */
void pio_toggle_pin_group(Pio *p_pio, uint32_t ul_mask)
{
    if (p_pio->PIO_ODSR & ul_mask) {
        /* Value to be driven on the I/O line: 0. */
        p_pio->PIO_CODR = ul_mask;
    } else {
        /* Value to be driven on the I/O line: 1. */
        p_pio->PIO_SODR = ul_mask;
    }
}

LED が希望どおりに切り替えられない理由について何か考えはありますか? Atmel ASFのドキュメントを参照しましたが、まだわかりません。

4

3 に答える 3

1

実際の関数呼び出しについてはお手伝いできませんが、エッジ割り込みを使用するとします。私の知る限り、立ち上がりエッジごとに割り込みハンドラを呼び出します。ただし、最初の立ち上がりエッジの後、ボタン リリースでトリガーする必要があります。これは立ち下がりエッジになるため、割り込みハンドラー内でエッジを変更する必要があります。

ただし、メカニカル ボタンは、押したり離したりしたときにきれいなシングル エッジを生成しないことを考慮する必要があります。代わりにバウンスします。プルアップ (またはダウン) 抵抗を備えた通常の瞬間的な接触ボタンの場合、これによりイベントごとに複数のパルスが発生するため、LED が複数回オン/オフになり、任意の状態にとどまる可能性があります。ほとんどの時間。可能であれば、オシロスコープで確認してください。

これは、コンデンサによってハードウェアで回避するか、関連するエッジの後に他のボタンイベントに反応する前にデッドタイムを持つタイマーを使用してソフトウェアで回避できます。デッド タイムはボタンの種類によって異なりますが、典型的な値は 5 ~ 20 ミリ秒であり、ボタンのデータシートに記載する必要があります。疑わしい場合は、許容可能な最大値を使用してください。

于 2015-04-25T23:53:06.723 に答える
0

これは私のために働いたものです:

// Interrupt handler for button press
void button_press_handler(uint32_t a, uint32_t b)
{
    // Turn the LED's on or off
        if (pio_get(PIOC, PIO_TYPE_PIO_OUTPUT_0, BLUE_LED4))
        pio_clear(PIOC, BLUE_LED4);
        else
        pio_set(PIOC, BLUE_LED4);
}

そして、これはLEDをオンにするために機能する「set」関数と呼ばれるものです:

void pio_set(Pio *p_pio, const uint32_t ul_mask)
{
    p_pio->PIO_SODR = ul_mask;
}
于 2015-04-26T01:04:21.957 に答える