STM32F103 | libopencm3 | Переключение GPIO с использованием прерывания - PullRequest
0 голосов
/ 08 мая 2020

Итак, я пытаюсь переключить светодиод на основе прерывания от кнопки.

В идеале, когда кнопка нажата, светодиод должен включаться, т.е. включаться, если он выключен, и наоборот. Но когда я выполняю этот код, он переключается и возвращается в исходное состояние.

Ожидаемый результат: Светодиод выключен »Кнопка нажата» Светодиод включен

Практический результат: Светодиод выключен »Кнопка нажата» Светодиод включен »Светодиод выключен

Я добавил задержку для отскока, так что подпрыгивание отсутствует. Также ODR GPIO устанавливается в ISR при нажатии кнопки, так как же он очищается при выходе из ISR?

Буду очень признателен за вашу помощь! Спасибо.

#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/exti.h>
#include <libopencm3/cm3/nvic.h>

#define LEDPIN (GPIO13)

static void exti_setup(void)
{
    /* Enable GPIOA and AFIO clock. */
    rcc_periph_clock_enable(RCC_GPIOB);
    rcc_periph_clock_enable(RCC_AFIO);

    /* Enable EXTI0 interrupt. */
    nvic_enable_irq(NVIC_EXTI15_10_IRQ);

    /* Set GPIO12 (in GPIO port B) to input  */
    gpio_set_mode(GPIOB, GPIO_MODE_INPUT,GPIO_CNF_INPUT_FLOAT, GPIO12);

    /* Configure the EXTI subsystem. */
    exti_select_source(EXTI12,GPIOB);
    exti_set_trigger(EXTI12, EXTI_TRIGGER_BOTH);
    exti_enable_request(EXTI12);
}


static void gpio_setup(void)
{
    /* Enable clock for GPIO port C */
    rcc_periph_clock_enable(RCC_GPIOC);

    /* Set LEDPIN (in GPIO port C) as opendrain output  */
    gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_OPENDRAIN, LEDPIN);
}

void delay(){
    int i;
    for (i = 0; i < 1000000; i++) 
    {
        __asm__("nop");
    } 
}

void handler(){
    delay();
    gpio_toggle(GPIOC, GPIO13);
}

int main(void)
{
    gpio_setup();
    exti_setup();

    while (1) {
    __asm__("nop");
    }
    return 0;
}

void exti15_10_isr()
{
    exti_reset_request(EXTI12);
    handler();
}

Ответы [ 2 ]

1 голос
/ 08 мая 2020
  1. Не открытый сток, а pu sh -pull
  2. Кнопки не должны использовать EXTI, так как это усложняет устранение ошибок , часто наводняет u C прерываниями, Вместо этого используйте прерывание по таймеру для чтения ключа и устранения дребезга.
0 голосов
/ 08 мая 2020

Как справедливо заметил @dev_eng, проблема заключалась в том, что прерывание было настроено как на восходящем / падающем фронте.

Настройка его с одним КРАЕМ, который либо ПОДНИМАЕТСЯ, либо УДАЛЯЕТСЯ, решила мою проблему.

...