作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
访问 GPIO 的 Rust STM32xxx_hal 代码片段
let gpioa = dp.GPIOA.split(&mut rcc);
let mut p12 = gpioa.pa12;
loop {
p12.into_push_pull_output().set_low().unwrap();
//after some processing, time to switch p12 to input
p12.into_floating_input();
}
编译器提示
into_push_pull_output()
之后p12 已“移动”。
#![deny(warnings)]
#![deny(unsafe_code)]
#![no_main]
#![no_std]
// #[allow(unused)]
// use panic_halt;
#[allow(unused)]
use panic_semihosting;
use cortex_m_rt::entry;
use stm32g0xx_hal as hal;
use hal::prelude::*;
use hal::rcc::Config;
use hal::stm32;
#[entry]
fn main() -> ! {
let dp = stm32::Peripherals::take().expect("cannot take peripherals");
let mut rcc = dp.RCC.freeze(Config::lsi());
let mut delay = dp.TIM16.delay(&mut rcc);
let gpioa = dp.GPIOA.split(&mut rcc);
let gpiob = dp.GPIOB.split(&mut rcc);
let mut l3 = gpioa.pa12.into_push_pull_output();
let mut l2 = gpioa.pa11.into_push_pull_output();
let mut l1 = gpiob.pb7.into_push_pull_output();
loop {
let _l1b = l1.into_floating_input();
l3.set_high().unwrap();
l2.set_low().unwrap();
delay.delay(500.ms());
l2.set_high().unwrap();
l3.set_low().unwrap();
delay.delay(500.ms());
l1 = _l1b.into_push_pull_output();
let _l2b = l2.into_floating_input();
l1.set_high().unwrap();
l3.set_low().unwrap();
delay.delay(500.ms());
l3.set_high().unwrap();
l1.set_low().unwrap();
delay.delay(500.ms());
l2 = _l2b.into_push_pull_output();
let _l3b = l3.into_floating_input();
l1.set_high().unwrap();
l2.set_low().unwrap();
delay.delay(500.ms());
l2.set_high().unwrap();
l1.set_low().unwrap();
delay.delay(500.ms());
l3 = _l3b.into_push_pull_output();
}
}
最佳答案
为什么 p12 已经“移动”了
为了澄清“移动”消息:您正在使用的 API(例如, into_push_pull_output()
函数)具有以下签名:
pub fn into_push_pull_output(
self,
moder: &mut MODER,
otyper: &mut OTYPER
) -> PA12<Output<PushPull>>
那里有很多,但要注意的重要一点是第一个参数是
self
,而不是
&self
或
&mut self
.这意味着如果您调用
p12.into_push_pull_output()
,然后是
ownership值(value)
p12
被转移出你的功能并进入
into_push_pull_output
功能。由于所有权转移,
p12
的值您正在编写的函数不再可以使用。换句话说,即使没有循环,您也可能遇到此错误:
let p12 = gpioa.pa12;
p12.into_push_pull_output().set_low().unwrap();
return p12; // ERROR! `p12` has already moved!
但是为什么开发人员会制作一个 API 来阻止我使用 p12 值呢?
let mut p12 = gpioa.pa12;
p12.into_floating_input();
p12.set_low();
这段代码有问题。而
set_low
如果 IO 引脚处于“输出”状态,则可能是有效操作,如果代码在 IO 引脚处于输入状态时尝试运行此操作,则可能是一个错误。理想情况下,我们希望能够在编译时检测此类问题。
into_floating_input()
之后,您的 pin 将由类型为
PA12<Input<Floating>>
的值表示.同样,在调用
into_push_pull_output()
之后,您的 pin 将由类型为
PA12<Output<PushPull>>
的值表示.这两种类型为它们实现了不同的方法。
p12
代表一个引脚的值,您可能有多个
p12
值,每个值都代表处于特定状态的引脚。 Rust 编译器将确保您一次只能操作一个这样的值,并且您调用的任何方法都只会在引脚处于特定状态时才被允许。当以这种方式查看时,我上面显示的错误代码在编译时被捕获:
let p12 = gpioa.pa12;
// `into_floating_input()` returns a new value, which represents the pin in
// the "floating input" state.
let new_p12 = p12.into_floating_input();
// This will cause a compiler error, since the type `PA12<Input<Floating>>`
// of `new_p12` wouldn't have a `set_low()` method.
new_p12.set_low();
如果您还没有,请查看
Rust Embedded Book 中的“静态保证”一章有关此模式的更多信息。
// Define a value which has a specific type `PA12<Output<PushPull>>`
let mut p12 = gpioa.pa12.into_push_pull_output().set_low().unwrap();
loop {
// Use `let` to assign a new value, which has the type `PA12<Input<Floating>>`.
let p12_input = p12.into_floating_input();
// Perform method calls on `p12_input`
// ...
// Get ourselves back to a `PA12<Output<PushPull>>` value.
p12 = p12_input.into_push_pull_output().set_low().unwrap();
}
关于rust 嵌入式将 GPIO 引脚从输出更改为输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65755746/
我是一名优秀的程序员,十分优秀!