多次引用同一变量,无需借用或克隆

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

目前,我正在多次重新定义同一个变量(

dp
)以使程序正常运行。然而,这感觉不对,我认为会有更好的方法来做到这一点。对于上下文,我处于
no_std
环境中,并使用 avr-hal-template 为 avr-atmega328p (Arduino Uno) 进行编译。

#![no_std]
#![no_main]

use arduino_hal::hal::wdt;
use motor_shield::{dc::DcMotor, init_pwm, Motor};
use panic_halt as _;

#[arduino_hal::entry]
fn main() -> ! {
    let dp = arduino_hal::Peripherals::take().unwrap();
    let pins = arduino_hal::pins!(dp);

    let dp = arduino_hal::Peripherals::take().unwrap();
    let mut pwm = init_pwm(None, dp, pins).unwrap();
    let mut dc_motor = DcMotor::try_new(&mut pwm, Motor::Motor1).unwrap();

    let dp = arduino_hal::Peripherals::take().unwrap();
    let mut watchdog = wdt::Wdt::new(dp.WDT, &dp.CPU.mcusr);
    watchdog.start(wdt::Timeout::Ms4000).unwrap();

    loop {
        let _ = dc_motor.set_throttle(&mut pwm, 0.5);
        arduino_hal::delay_ms(1000);
        let _ = dc_motor.set_throttle(&mut pwm, 0.0);
        arduino_hal::delay_ms(1000);
        watchdog.feed();
    }
}

对于上下文,这是

init_pwm
函数:

pub fn init_pwm(i2c: Option<I2c>, dp: Peripherals, pins: Pins) -> Result<Pca9685<I2c>, MotorError> {
    let i2c = if let Some(i2c) = i2c {
        i2c
    } else {
        I2c::new(
            dp.TWI,
            pins.a4.into_pull_up_input(),
            pins.a5.into_pull_up_input(),
            50000,
        )
    };

    let address = Address::from(60);

    let mut pwm = Pca9685::new(i2c, address).map_err(|_| MotorError::PwmError)?;
    pwm.enable().map_err(|_| MotorError::PwmError)?;
    pwm.set_prescale(4).map_err(|_| MotorError::PwmError)?;
    Ok(pwm)
}

我能想到做的一件事是借用 dp,但这行不通,因为函数不接受引用。我也无法克隆 dp,因为它没有实现克隆特征。

rust arduino rust-no-std rust-embedded
1个回答
0
投票

感谢 Chayim Friedman 的评论,我终于找到了解决方案。我将

init_pwm
函数更改为需要
WDT
而不是完整的外设,因为这就是它所需要的。然后,我可以仅使用
dp.TWI
而不是
dp
来调用该函数。

pub fn init_pwm(i2c: Option<I2c>, twi: TWI, pins: Pins) -> Result<Pca9685<I2c>, MotorError> {
  // ...
  else {
    I2c::new(
      twi,
      pins.a4.into_pull_up_input(),
      pins.a5.into_pull_up_input(),
      50000,
    )
  }
// in main.rs
fn main() -> ! {
  let dp = Peripherals::take().unwrap();
  let pins = arduino_hal::pins!(dp);
    
  let mut pwm = init_pwm(None, dp.TWI, pins).unwrap();
  let mut dc_motor = DcMotor::try_new(&mut pwm, Motor::Motor1).unwrap();
    
  let mut watchdog = wdt::Wdt::new(dp.WDT, &dp.CPU.mcusr);
  watchdog.start(wdt::Timeout::Ms4000).unwrap();
  // ...
}
© www.soinside.com 2019 - 2024. All rights reserved.