forked from stm32-rs/stm32f1xx-hal
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Example of using i2c with the bme280 air sensor (stm32-rs#313)
* Example of useing i2c with the bme280 air sensor
- Loading branch information
Showing
4 changed files
with
139 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
[package] | ||
name = "i2c-bme280" | ||
version = "0.1.0" | ||
license = "Apache-2.0" | ||
description = "I2C example for real peripheral" | ||
repository = "https://github.com/stm32-rs/stm32f1xx-hal" | ||
edition = "2018" | ||
publish = false | ||
|
||
[dependencies] | ||
bme280 = "0.2.1" | ||
cortex-m-semihosting = "0.3.3" | ||
panic-semihosting = "0.5.2" | ||
cortex-m-rt = "0.6.8" | ||
cortex-m = "0.6.0" | ||
|
||
[dependencies.stm32f1xx-hal] | ||
path = "../.." | ||
version = "0.7.0" | ||
features = ["stm32f103", "rt", "stm32-usbd"] | ||
|
||
[profile.dev] | ||
incremental = false | ||
codegen-units = 1 | ||
|
||
[profile.release] | ||
codegen-units = 1 | ||
debug = true | ||
lto = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/* Linker script for the STM32F103C8T6 */ | ||
MEMORY | ||
{ | ||
FLASH : ORIGIN = 0x08000000, LENGTH = 64K | ||
RAM : ORIGIN = 0x20000000, LENGTH = 20K | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
//! Reads data from a BME280 over i2c | ||
//! | ||
//! This assumes that a BME280 is connected with clk on PB6 and data on PB7. | ||
//! | ||
//! For the Adafruit breakout boards PB6 should be connected to SCK and PB7 to SDI | ||
//! | ||
//! This program writes the sensor values to the debug output provided by semihosting | ||
//! you must enable semihosting in gdb with `monitor arm semihosting enable` I have it | ||
//! added to my `.gdbinit`. Then the debug infomation will be printed in your openocd | ||
//! terminal. | ||
//! | ||
//! This program dose not fit on my blue pill unless compiled in release mode | ||
//! eg. `cargo run --example i2c-bme280 --features "stm32f103 bme280 rt" --release` | ||
//! However as noted above the debug output with the read values will be in the openocd | ||
//! terminal. | ||
#![deny(unsafe_code)] | ||
#![no_std] | ||
#![no_main] | ||
|
||
use cortex_m_semihosting::hprintln; | ||
use panic_semihosting as _; | ||
|
||
use bme280::BME280; | ||
use cortex_m_rt::entry; | ||
use stm32f1xx_hal::{ | ||
delay::Delay, | ||
i2c::{BlockingI2c, DutyCycle, Mode}, | ||
pac, | ||
prelude::*, | ||
}; | ||
|
||
#[entry] | ||
fn main() -> ! { | ||
// Get access to the core peripherals from the cortex-m crate | ||
let cp = cortex_m::Peripherals::take().unwrap(); | ||
// Get access to the device specific peripherals from the peripheral access crate | ||
let dp = pac::Peripherals::take().unwrap(); | ||
|
||
// Take ownership over the raw flash and rcc devices and convert them into the corresponding | ||
// HAL structs | ||
let mut flash = dp.FLASH.constrain(); | ||
let mut rcc = dp.RCC.constrain(); | ||
let mut afio = dp.AFIO.constrain(); | ||
// Freeze the configuration of all the clocks in the system and store the frozen frequencies in | ||
// `clocks` | ||
let clocks = if 1 == 1 { | ||
rcc.cfgr.use_hse(8.mhz()).freeze(&mut flash.acr) | ||
} else { | ||
// My blue pill with a stm32f103 clone dose not seem to respect rcc so will not compensate its pulse legths | ||
// with a faster clock like this. And so the sensor dose not have time to respond to the START pulse. | ||
// I would be interested if others with real stm32f103's can use this program with the faster clocks. | ||
rcc.cfgr | ||
.use_hse(8.mhz()) | ||
.sysclk(48.mhz()) | ||
.pclk1(6.mhz()) | ||
.freeze(&mut flash.acr) | ||
}; | ||
|
||
// Acquire the GPIOB peripheral | ||
let mut gpiob = dp.GPIOB.split(); | ||
|
||
let scl = gpiob.pb6.into_alternate_open_drain(&mut gpiob.crl); | ||
let sda = gpiob.pb7.into_alternate_open_drain(&mut gpiob.crl); | ||
|
||
let i2c = BlockingI2c::i2c1( | ||
dp.I2C1, | ||
(scl, sda), | ||
&mut afio.mapr, | ||
Mode::Fast { | ||
frequency: 400_000.hz(), | ||
duty_cycle: DutyCycle::Ratio16to9, | ||
}, | ||
clocks, | ||
1000, | ||
10, | ||
1000, | ||
1000, | ||
); | ||
|
||
// The Adafruit boards have address 0x77 without closing the jumper on the back, the BME280 lib connects to 0x77 with `new_secondary`, use | ||
// `new_primary` for 0x76 if you close the jumper/solder bridge. | ||
let mut bme280 = BME280::new_secondary(i2c, Delay::new(cp.SYST, clocks)); | ||
bme280 | ||
.init() | ||
.map_err(|error| { | ||
hprintln!("Could not initialize bme280, Error: {:?}", error).unwrap(); | ||
panic!(); | ||
}) | ||
.unwrap(); | ||
loop { | ||
match bme280.measure() { | ||
Ok(measurements) => { | ||
hprintln!("Relative Humidity = {}%", measurements.humidity).unwrap(); | ||
hprintln!("Temperature = {} deg C", measurements.temperature).unwrap(); | ||
hprintln!("Pressure = {} pascals", measurements.pressure).unwrap(); | ||
} | ||
Err(error) => { | ||
hprintln!("Could not read bme280 due to error: {:?}", error).unwrap(); | ||
} | ||
} | ||
} | ||
} |