如何在 Rust 上通过 DMA 控制占空比?

问题描述 投票:0回答:1

我根据这个topic编写了我的代码,但它不起作用。我正在使用 stm32f7xx_hal 板条箱,但我认为我的程序的逻辑与示例中的代码类似。我的问题是占空比保留其在这一行中配置的占空比

buzz_pwm.set_duty(Channel::C1, 0)
。 我在 STM32F767ZI 上运行此代码:

    let mut rcc = dp.RCC.constrain();
    let clocks = rcc
        .cfgr
        .set_defaults()
        .freeze();

    let gpioa = dp.GPIOA.split();
    let buzz = gpioa.pa6.into_alternate();
    let mut buzz_pwm = dp.TIM3.pwm_hz(buzz, 4_000_000.Hz(), &clocks);

    let max_duty = buzz_pwm.get_max_duty();
    buzz_pwm.set_duty(Channel::C1, max_duty / 3);
    buzz_pwm.enable(Channel::C1);

    let dma_buf = [max_duty / 3 * 2, max_duty / 3, 0];

    unsafe {
        let tim3 = &*TIM3::ptr();
        let rcc_ptr = &*RCC::ptr();
        let dma1 = &*DMA1::ptr();

        rcc_ptr.ahb1enr.modify(|_, w| w.dma1en().set_bit());

        let ccr1_addr = tim3.ccr1() as *const _ as u32;

        tim3.dier.write(|w| w
            .tde().enabled()
            .cc1ie().enabled()
            .ude().enabled()
        );

        tim3.dcr.write(|w| w.dba().bits(15));

        dma1.st[4].m0ar.write(|w| w.m0a().bits(dma_buf.as_ptr() as u32));
        dma1.st[4].ndtr.write(|w| w.ndt().bits(dma_buf.len() as u16));
        dma1.st[4].par.write(|w| w.pa().bits(ccr1_addr));

        dma1.st[4].cr.reset();
        dma1.st[4].cr.modify(|_, w| w
            .chsel().bits(5)
            .mburst().single()
            .pburst().single()
            .pl().high()
            .msize().bits32()
            .psize().bits32()
            .minc().set_bit()
            .pinc().clear_bit()
            .circ().enabled()
            .dir().memory_to_peripheral()
            .teie().set_bit()
            .htie().set_bit()
            .tcie().set_bit()
            .en().enabled()
        );
    }

请告诉我我哪里错了。

stm32 dma pwm rust-embedded
1个回答
0
投票

我的错误是我没有启用捕获/比较 1 DMA 请求。 这是一个适合我的主循环:

    let dp = pac::Peripherals::take().unwrap();
    let mut rcc = dp.RCC.constrain();
    let clocks = rcc.cfgr
        .hse(HSEClock::new(8.MHz(), HSEClockMode::Oscillator))
        .pllm(4)
        .plln(96)
        .pllp(PLLP::Div4)
        .use_pll()
        .sysclk(48.MHz())
        .freeze();

    let gpioa = dp.GPIOA.split();
    let buzz = gpioa.pa6.into_alternate();
    let mut buzz_pwm = dp.TIM3.pwm_hz(buzz, 2_000_000.Hz(), &clocks);

    let max_duty = buzz_pwm.get_max_duty() as i32;
    buzz_pwm.set_duty(Channel::C1, 0);
    buzz_pwm.enable(Channel::C1);

    let dma_buf = [max_duty / 6, max_duty / 4, max_duty / 4, max_duty / 3, 0, 0, 0];

    unsafe {
        let tim3 = &*TIM3::ptr();
        let rcc_ptr = &*RCC::ptr();
        let dma1 = &*DMA1::ptr();

        rcc_ptr.ahb1enr.modify(|_, w| w.dma1en().set_bit());

        let ccr1_addr = tim3.ccr1() as *const _ as u32;

        tim3.dier.write(|w| w
            .tde().enabled()
            .cc1de().enabled() //enable capture/compare 1 DMA request
            .ude().enabled()
        );

        dma1.st[4].m0ar.write(|w| w.m0a().bits(dma_buf.as_ptr() as u32));
        dma1.st[4].ndtr.write(|w| w.ndt().bits(dma_buf.len() as u16));
        dma1.st[4].par.write(|w| w.pa().bits(ccr1_addr));

        dma1.st[4].cr.reset();
        dma1.st[4].cr.modify(|_, w| w
            .chsel().bits(5)
            .mburst().single()
            .pburst().single()
            .pl().high()
            .msize().bits32()
            .psize().bits32()
            .minc().set_bit()
            .pinc().clear_bit()
            .circ().enabled()
            .dir().memory_to_peripheral()
            .teie().set_bit()
            .htie().set_bit()
            .tcie().set_bit()
            .en().enabled()
        );
    }
© www.soinside.com 2019 - 2024. All rights reserved.