#放大器 #ADC #嵌入式HAL驱动程序 #硬件接口 #负载细胞

无std hx711

一个与HX711(负载细胞放大器和ADC)接口的平台无关的驱动程序

7个版本 (重大更改)

使用旧的Rust 2015

0.6.0 2020年9月22日
0.5.0 2020年6月19日
0.4.0 2020年6月4日
0.3.0 2020年5月2日
0.1.0 2019年4月20日

434嵌入式开发

Download history 1/week @ 2024-03-24 33/week @ 2024-03-31 11/week @ 2024-04-07 86/week @ 2024-04-14 61/week @ 2024-04-21 90/week @ 2024-04-28 45/week @ 2024-05-05 27/week @ 2024-05-12 1/week @ 2024-05-19 9/week @ 2024-05-26 53/week @ 2024-06-02 30/week @ 2024-06-09 56/week @ 2024-06-16 33/week @ 2024-06-23 25/week @ 2024-06-30 41/week @ 2024-07-07

每月159 次下载

MIT/Apache

13KB
181

Build Status crates.io docs.rs

HX711

一个与HX711(负载细胞放大器和24位ADC)接口的平台无关的驱动程序

功能

  • 重置芯片
  • 设置模式(增益和通道)
  • 读取转换结果(阻塞和非阻塞)
  • 进入低功耗模式并唤醒

已在STM32F103上测试。欢迎提交其他硬件的拉取请求!

由于接口通过切换GPIO引脚工作,因此需要特别注意。请参阅以下内容。

示例

请参阅此处:https://github.com/jonas-hagen/hx711-examples

不完整的开胃菜

let mut val: i32 = 0;

let dout = gpioa.pa6.into_floating_input(&mut gpioa.crl);
let pd_sck = gpioa.pa7.into_push_pull_output(&mut gpioa.crl);

let mut hx711 = Hx711::new(Delay::new(cp.SYST, clocks), dout, pd_sck).into_ok();

// Obtain the tara value
writeln!(tx, "Obtaining tara ...").unwrap();
const N: i32 = 8;
for _ in 0..N {
    val += block!(hx711.retrieve()).into_ok(); // or unwrap, see features below
}
let tara = val / N;
writeln!(tx, "Tara:   {}", tara).unwrap();

可选功能

never_type

当使用nightly rust时,可以可选地启用never_type功能。

对于某些HAL,数字输入和输出引脚永远不会失败。当使用此类crate的驱动程序时,可以在所有结果上使用.into_ok()而不是.unwrap().expect()

例如STM32f1xx嵌入式HAL

// Without never_type (stable rust):
// We know that this never fails
let weight = block!(hx711.retrieve()).unwrap())

// With never_type (nightly rust)
// It is obvious that this is always ok
let weight = block!(hx711.retrieve()).into_ok()

位操作和延迟

由于HX711需要特定的时钟周期来设置操作模式(25、26或27周期),因此使用GPIO接口实现协议。所以,在读取过程中要当心中断!仅状态变化之间的延迟需要为0.1 µs(根据HX711规格),允许在约5 µs内通过所有24个周期。但是,当前的嵌入式HAL不支持小于1 µs的延迟(请参阅embedded-hal #63以进行讨论)。使用1 µs的延迟,读取需要至少48 µs。根据设备的时钟速度,总时间可能增加到300 µs(使用8 MHz的STM32F103进行测试)或更多。在一个控制循环中,这可能是不可取的,并且保持时间接近5 µs更有吸引力。

为了调整性能,可以使用延迟特质的替代实现。例如

use embedded_hal::blocking::delay::DelayUs;

pub struct BusyDelay {
    nops_per_us: u32,
}

impl BusyDelay {
    pub fn new(loops_per_us: u32) -> Self {
        BusyDelay{loops_per_us: loops_per_us as u32}
    }
}

impl DelayUs<u32> for BusyDelay {
    fn delay_us(&mut self, us: u32) {
        for _ in 0..us {
            cortex_m::asm::delay(self.nops_per_us)
        }
    }
}

或者甚至

pub struct NoDelay();

impl NoDelay {
    pub fn new() -> Self {
        NoDelay()
    }
}

impl DelayUs<u32> for NoDelay {
    fn delay_us(&mut self, _us: u32) {
    }
}

关于这个主题的一些随机笔记

  • 也许可以添加一个 nodelay 功能?
  • 尝试使用 SPI,将 MOSI 作为时钟,MISO 作为数据线,而不使用实际的 SPI 时钟,这将很有趣。
  • 如何在 Linux 上实现它?有什么想法吗?

变更日志

v0.6

  • 将 nb 需求更新到 1.0.0
  • 添加 get_mode 函数。感谢 m-ou-se

v0.5

  • never_type 的使用隐藏在针对稳定 Rust 的功能背后

v0.4

  • 添加延迟。
  • 添加 enable()disable() 函数以进入和离开低功耗模式。

v0.3

  • 添加自定义错误类型。一些 HAL 实现数字接口的方式使其无法失败。在这种情况下,输入和输出引脚的错误类型是不可靠的。通过自定义错误类型,我们可以在使用此类 HAL 实现时允许使用 .into_ok()

v0.2

  • 更新到 embedded-hal 数字引脚 v2 API。感谢 mmou

v0.1

  • 第一个版本。

许可证

许可协议为以下之一

任选其一。

依赖

~71KB