在上一篇博客中,我们试图直接写到BSRR寄存器的地址,这不是安全访问,因为我们陷入了硬件故障异常。你可以阅读那篇博客 来自这里.
现在在这篇博客中,我们将以一种非常不同的方式工作。我们不打算使用BSRR寄存器,而是要使用寄存器块来访问GPIO 块的寄存器。
由于我们正在使用嵌入式系统,它们使我们的任务快速而可靠。另外,与传统的计算机相比,它们的体积要小得多,这使得它们结构紧凑,便于携带,有利于大规模生产。嵌入式系统的管理是相当容易的,因为在其创建过程中使用的元素是廉价和持久的。嵌入式系统也具有成本效益。
直接使用十六进制地址是容易出错的,这一点我们在上一篇博客中已经看到了,我们是如何面对硬件异常的。现在我们要以一种 "安全 "的方式来工作。让我们看看我们如何做到这一点。
我们将在工作中牢记寄存器的3个规则。
- 不乱用实际地址
- 应尊重读/写权限
- 应该防止修改寄存器的保留部分。
寄存器块
寄存器块是一组与外设相关的寄存器,这些寄存器组位于_内存的_一个_连续的区域内。_
为什么我们在这里谈论寄存器块?
寄存器块是一种结构类型,它的每个字段都代表一个寄存器。这些寄存器是以下方法的组合:根据其读/写权限,读、写或修改。我们可以使用寄存器块访问的寄存器的数量是。
我们可以在寄存器块结构的帮助下访问所有这些寄存器。
代码
是时候编写一个安全的程序了,它将帮助我们使用寄存器块访问**"bsrr "**寄存器。
#![no_main]
#![no_std]
use cortex_m::asm::delay;
use cortex_m_rt::entry;
use panic_itm as _;
use stm32f3_discovery::leds::Leds;
use stm32f3_discovery::stm32f3xx_hal::{pac::GPIOE, prelude::*, stm32};
#[entry]
fn main() -> ! {
let gpioe = unsafe { &*GPIOE::ptr() };
let device_peripherals = stm32::Peripherals::take().unwrap();
let mut reset_and_clock_control = device_peripherals.RCC.constrain();
// initialize user leds
let mut gpio_pe = device_peripherals
.GPIOE
.split(&mut reset_and_clock_control.ahb);
let _leds = Leds::new(
gpio_pe.pe8,
gpio_pe.pe9,
gpio_pe.pe10,
gpio_pe.pe11,
gpio_pe.pe12,
gpio_pe.pe13,
gpio_pe.pe14,
gpio_pe.pe15,
&mut gpio_pe.moder,
&mut gpio_pe.otyper,
);
loop {
// Turn "on" the North LED
gpioe.bsrr.write(|write| write.bs9().set_bit());
delay(3_0000_00);
// Turn "on" the North LED
gpioe.bsrr.write(|write| write.bs11().set_bit());
delay(3_0000_00);
// Turn "off" the North LED
gpioe.bsrr.write(|write| write.br9().set_bit());
delay(3_0000_00);
// Turn "off" the North LED
gpioe.bsrr.write(|write| write.br11().set_bit());
delay(3_0000_00);
}
}
**注意:**你可以从这里看到代码和使用的依赖性。 储存器.
这里你可以注意到我们使用了 "stm32f3_discovery::stm32f3xx_hal::pac::GPIOE",它为我们提供了RegisterBlock。我们必须使用不安全块来访问这个寄存器块,因为我们必须取消对原始指针的引用。
- 你注意到的第一件事。这里没有涉及任何神奇的地址。相反,我们使用一个更人性化的方式,例如,gpioe.bsrr,来指代GPIOE寄存器块中的BSRR寄存器。
- 然后,我们有这样的写入方法,它需要一个闭包。如果使用身份闭合(|w|w),这个方法将把寄存器设置为_默认_(复位)值,即微控制器上电/复位后的值。
- 这个值是BSRR寄存器的0x0。因为我们想给寄存器写一个非零的值,所以我们使用构建器的方法,比如bs9和br9,对默认值的一些位进行构建。
现在逐一应用这些命令
- 加载
- 断开主程序
- 继续
- 步骤
- 下一步
- print gpioe
你会看到这样的输出。
这个打印出的寄存器块的地址和**"bsrr "寄存器的地址将在一个连续的内存中,即0x48001018**。
使用寄存器块闪烁LEDs-
现在让我们试着用这种安全的方式来闪烁LEDs。现在运行命令"continue"。
输出...
这就是你如何以安全的方式使用寄存器块访问LEDs。
我希望你喜欢这种使用寄存器的工作方式。谢谢你的阅读...!
如果你想阅读更多这样的内容? 请订阅《锈蚀时代》通讯,每两周一次,直接在您的收件箱中收到见解和最新更新。订阅《锈蚀时代》通讯:https://bit.ly/2Vdlld7。