Мой обработчик прерывания EXTI0 не перезаписывается/не работает должным образом (STM32F3Discovery)

Я пытаюсь узнать о кодировании для встроенных устройств и хочу реализовать прерывание. Для этого я написал программу, в которой основная функция — это просто цикл, который мигает одним светодиодом, а прерывание должно зажечь другой светодиод, чтобы проверить, все ли сработало.

Мой код выглядит следующим образом:

#![no_main]
#![no_std]

use f3discovery::{Tim6, set_high};

use cortex_m;
use cortex_m_rt::entry;
use stm32f30x::interrupt;


#[inline(never)]
fn delay_ms(ms: u16) {
    Tim6::new_ms(ms).setup();
    Tim6::start();
    while Tim6::check_finish() {}
    Tim6::reset();
}


const RCC_AHBENR: u32 = 0x4002_1014;
const RCC_APB2ENR: u32 = 0x4002_1018;

const _GPIOA_MODER: u32 = 0x4800_0000;
const GPIOA_PUPDR: u32 = 0x4800_000C;
const _GPIOA_BSRR: u32 = 0x4800_0018;

const _SYSCFG_EXTICR1 : u32 = 0x4001_0008;

const EXTI_IMR1 : u32 = 0x4001_0400;
const EXTI_RTSR1 : u32 = 0x4001_0408;
const EXTI_PR1 : u32 = 0x4001_0414;

const NVIC_ISER0 : u32 = 0xE000_E100;

#[entry]
fn main() -> ! {
    let (mut leds, _rcc, _tim6) = aux9::init();

    Tim6::enable();
    
    set_high(RCC_AHBENR, 1 << 17);
    set_high(RCC_APB2ENR, 1);
    set_high(GPIOA_PUPDR, 1 << 1);
    set_high(EXTI_IMR1, 1);
    set_high(EXTI_RTSR1, 1);
    set_high(NVIC_ISER0, 1 << 6);

    loop {
        leds[0].on();
        delay_ms(500);
        leds[0].off();
        delay_ms(500);
    }
}

#[interrupt]
fn EXTI0() {
    let (mut leds, _rcc, _tim6) = aux9::init();

    leds[4].on();
    // delay_ms(500);
    // leds[4].off();
    // delay_ms(500);
    set_high(EXTI_PR1, 1);
}

Я использую модуль f3discovery, который написал сам, для таймера и еще один модуль (aux9) для светодиодов. Когда я запускаю программу, первый светодиод мигает до тех пор, пока не будет нажата кнопка, что приводит к прерыванию. Но второй светодиод никогда не загорается. Удаление EXTI0 дает тот же результат, что заставляет меня думать, что обработчик перезаписан неправильно.

Буду благодарен за любой совет :)


person MEisebitt    schedule 12.01.2021    source источник


Ответы (1)


Причина в линии

let (mut leds, _rcc, _tim6) = aux9::init();

в функции EXTI0. В функцию aux9::init() входит строка

let p = stm32f0x::Peripherals::take().unwrap()

и unwrap вызовет панику при втором вызове функции, тем самым перейдя к обработчику паники, где программа останется.

Кредиты для этого до агг.

person MEisebitt    schedule 14.01.2021